Une collection de notes diverses sur des trucs et astuces pour faire des choses avec un ordinateur...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

100 lines
2.8 KiB

\chapter{Debug}\index{Debug}
\label{chap:debug}
Quand plus rien ne marche, reste-il encore un espoir ?
Il existe bien entendu des outils \textsl{mainstream}
tels que le classique \texttt{gdb}\index{gdb}, mais il en existe
une foultitude d'autres, injustement méconnus.
En voici quelques-uns.
% ==============================================================
\section{Strace}\index{strace}
Strace permet de tracer les appels systèmes d'un processus.
Comme vous le savez tous, un appel système
(aka syscall\index{syscall})
est \textbf{le} moyen de communication qu'utilise un process
utilisateur pôur demander un service au noyau.
\begin{verbatim}
strace -o toto ./kluge
\end{verbatim}
% ==============================================================
\section{LD\_PRELOAD}\index{LD\_PRELOAD}
D'accord, aves \texttt{strace} nous pouvons voir passer les
appels systèmes, mais dans la vie d'un process, certaines
opérations ne sortent pas de la \texttt{libc}\index{libc}.
L'une d'entre elles, \texttt{getenv(3)}, va nous servir d'exemple.
\begin{verbatim}
NAME
getenv - get an environment variable
SYNOPSIS
#include <stdlib.h>
char *getenv(const char *name);
DESCRIPTION
The getenv() function searches the environment list to find the envi‐
ronment variable name, and returns a pointer to the corresponding value
string.
\end{verbatim}
Cette fonction est utilisée par un logiciel pour avoir accès à
son contexte extérieur, son environnement, dans lequel on
peut trouver (entre autres) la variable \texttt{\$LOGNAME} qui,
oh surprise, contient votre nom de login.
Et justement, vous avez un programme sous la main que vous suspecter
d'avoir un problème relationnel avec cette variable.
Il nius faut donc remplacer le getenv de la libc par notre propre
version qui va écouter et exfiltrer l'utilisation de cette
fonction.
\begin{lstlisting}[language=C]
/*
spy_getenv.so: spy_getenv.c Makefile
gcc -Wall -shared -fPIC $< -ldl -o $@
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define __USE_GNU
#include <dlfcn.h>
typedef char * (*original_getenv)(const char *envname);
char *getenv(char *envname)
{
static char *arrow = "--getenv--> ";
static char *wtf = " --> WTF ?";
char *content;
original_getenv orig_getenv;
orig_getenv = (original_getenv)dlsym(RTLD_NEXT, "getenv");
write(STDERR_FILENO, arrow, strlen(arrow));
write(STDERR_FILENO, envname, strlen(envname));
content = orig_getenv(envname);
if (NULL != content) {
write(STDERR_FILENO, "=", 1);
write(STDERR_FILENO, content, strlen(content));
}
else {
write(STDERR_FILENO, wtf, strlen(wtf));
}
write(STDERR_FILENO, "\n", 1);
return content;
}
\end{lstlisting}
Simple et efficace.
% ==============================================================
% ==============================================================