diff --git a/thesis/listings/intercept-preload.c b/thesis/listings/intercept-preload.c new file mode 100644 index 0000000..3965284 --- /dev/null +++ b/thesis/listings/intercept-preload.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +static void *(*__real_malloc)(size_t); + +static int mode = 0; + +static void fin(void) { + if (mode > 0) fprintf(stderr, "intercept: stopped\n"); + mode = 0; +} + +static void init(void) { + if (mode) return; + mode = -1; + if (((__real_malloc) = dlsym(RTLD_NEXT, "malloc")) == NULL) { + fprintf(stderr, "intercept: unable to load symbol '%s': %s", + "malloc", strerror(errno)); + return; + } + atexit(fin); + fprintf(stderr, "intercept: intercepting function calls\n"); + mode = 1; +} + +void *malloc(size_t size) { + init(); + // before call to malloc + void *ret = __real_malloc(size); + // after call to malloc + return ret; +} diff --git a/thesis/listings/intercept-wrap.c b/thesis/listings/intercept-wrap.c new file mode 100644 index 0000000..5fc4c2b --- /dev/null +++ b/thesis/listings/intercept-wrap.c @@ -0,0 +1,27 @@ +#include +#include + +extern void *__real_malloc(size_t); + +static int mode = 0; + +static void fin(void) { + if (mode > 0) fprintf(stderr, "intercept: stopped\n"); + mode = 0; +} + +static void init(void) { + if (mode) return; + mode = -1; + atexit(fin); + fprintf(stderr, "intercept: intercepting function calls\n"); + mode = 1; +} + +void *__wrap_malloc(size_t size) { + init(); + // before call to malloc + void *ret = __real_malloc(size); + // after call to malloc + return ret; +} diff --git a/thesis/listings/intercept.c b/thesis/listings/intercept.c new file mode 100644 index 0000000..93c737e --- /dev/null +++ b/thesis/listings/intercept.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +#ifdef INTERCEPT_PRELOAD +#define load(name) \ + if (((__real_ ## name) = dlsym(RTLD_NEXT, #name)) == NULL) { \ + fprintf(stderr, "intercept: unable to load symbol '%s': %s", \ + #name, strerror(errno)); \ + return; \ + } +#define sym(name) name +#define func_def(ret, name) static ret (*__real_ ## name) +#else +#define sym(name) __wrap_ ## name +#define func_def(ret, name) extern ret __real_ ## name +#endif + +func_def(void *, malloc)(size_t); + +static int mode = 0; + +static void fin(void) { + if (mode > 0) fprintf(stderr, "intercept: stopped\n"); + mode = 0; +} + +static void init(void) { + if (mode) return; + mode = -1; +#ifdef INTERCEPT_PRELOAD + load(malloc); +#endif + atexit(fin); + fprintf(stderr, "intercept: intercepting function calls\n"); + mode = 1; +} + +void *sym(malloc)(size_t size) { + init(); + // before call to malloc + void *ret = __real_malloc(size); + // after call to malloc + return ret; +} diff --git a/thesis/listings/preload.c b/thesis/listings/preload.c new file mode 100644 index 0000000..646469b --- /dev/null +++ b/thesis/listings/preload.c @@ -0,0 +1,15 @@ +#include +#include +#include + +void *malloc(size_t size) { + // before call to malloc + void *(*_malloc)(size_t); + if ((_malloc = dlsym(RTLD_NEXT, "malloc")) == NULL) { + errno = ENOSYS; + return NULL; + } + void *ret = _malloc(size); + // after call to malloc + return ret; +} diff --git a/thesis/listings/wrap.c b/thesis/listings/wrap.c new file mode 100644 index 0000000..c1a5d27 --- /dev/null +++ b/thesis/listings/wrap.c @@ -0,0 +1,10 @@ +#include + +extern void *__real_malloc(size_t size); + +void *__wrap_malloc(size_t size) { + // before call to malloc + void *ret = __real_malloc(size); + // after call to malloc + return ret; +} diff --git a/thesis/src/02.intercept.tex b/thesis/src/02.intercept.tex index bbbc625..2add520 100644 --- a/thesis/src/02.intercept.tex +++ b/thesis/src/02.intercept.tex @@ -39,18 +39,7 @@ Also note that arguments to the calls are displayed in a ``pretty'' way. For example, string arguments would be simple pointers, but \texttt{strace} displays them as C-like strings. \begin{listing}[htbp] - \begin{minted}[linenos]{c} -#include -#include -#include - -int main(const int argc, char *const argv[]) { - char *str = malloc(10); - strcpy(str, "Abc123"); - printf("Hello World!\nString: %s\n", str); - free(str); -} - \end{minted} + \inputminted[linenos]{c}{listings/main.c} \caption{Contents of \texttt{main.c}.} \label{lst:main.c} \end{listing} @@ -149,18 +138,7 @@ To call the real function inside the wrapper, \texttt{\_\_real\_\textit{symbol}} Listings \ref{lst:wrap.c} and \ref{lst:wrap} try to illustrate this by overriding the \texttt{malloc} function of the C standard library. \begin{listing}[htbp] - \begin{minted}[linenos]{c} -#include - -extern void *__real_malloc(size_t size); - -void *__wrap_malloc(size_t size) { - // before call to malloc - void *ret = __real_malloc(size); - // after call to malloc - return ret; -} - \end{minted} + \inputminted[linenos]{c}{listings/wrap.c} \caption{Contents of \texttt{wrap.c}.} \label{lst:wrap.c} \end{listing} @@ -213,23 +191,7 @@ This means, by setting the environment variable \texttt{LD\_PRELOAD}, it is poss Listings \ref{lst:preload.c} and \ref{lst:preload} try to illustrate this by overriding the \texttt{malloc} function of the C standard library. \begin{listing}[htbp] - \begin{minted}[linenos]{c} -#include -#include -#include - -void *malloc(size_t size) { - // before call to malloc - void *(*_malloc)(size_t); - if ((_malloc = dlsym(RTLD_NEXT, "malloc")) == NULL) { - errno = ENOSYS; - return NULL; - } - void *ret = _malloc(size); - // after call to malloc - return ret; -} - \end{minted} + \inputminted[linenos]{c}{listings/preload.c} \caption{Contents of \texttt{preload.c}.} \label{lst:preload.c} \end{listing} @@ -264,9 +226,20 @@ because it is simple to use (``clean'' source code, easy to compile and run prog The following sections concern the next steps in what else is needed to create a powerful ``interceptor''. -\section{Combining Preloading and Wrapper Functions}\label{sec:combining-preloading-and-wrapper-functions} +\section{Fundamental Project Structure}\label{sec:structure} + +After deciding to use the preloading method to intercept function calls, a more detailed plan is needed to continue developing. +It was decided to have one single \texttt{intercept.so} file as a resulting artifact which then may be loaded via the \texttt{LD\_PRELOAD} environment variable. +The easiest and most straightforward way to structure the source code was to put all code in one single C file. +Listing \ref{lst:intecept-preload.c} gives an overview over the grounding code structure. +For each function that should be intercepted, this function simply has to be declared and defined as \texttt{malloc} was. + +\begin{listing}[htbp] + \inputminted[linenos]{c}{listings/intercept-preload.c} + \caption{Contents of \texttt{intercept-preload.c}.} + \label{lst:intecept-preload.c} +\end{listing} -Lorem Ipsum. \section{Retrieving Function Argument Values}\label{sec:Retrieving-function-argument-values}