From ac96d571cd662f2acef099360c15878ecfbaffef Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 8 Jul 2025 20:12:43 +0200 Subject: [PATCH] thesis: Almost complete first section --- thesis/.gitignore | 1 + thesis/listings/ltrace.txt | 4 ++ thesis/listings/main.c | 10 ++++ thesis/listings/strace.txt | 37 +++++++++++++ thesis/src/02.intercept.tex | 103 ++++++++++++++++++++++++++++++------ thesis/src/99.intercept.bib | 12 +++++ 6 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 thesis/listings/ltrace.txt create mode 100644 thesis/listings/main.c create mode 100644 thesis/listings/strace.txt diff --git a/thesis/.gitignore b/thesis/.gitignore index c06a2ea..91383f3 100644 --- a/thesis/.gitignore +++ b/thesis/.gitignore @@ -3,6 +3,7 @@ /example.* /*.pdf /*.txt +/_minted/ *.acn *.aux *.glo diff --git a/thesis/listings/ltrace.txt b/thesis/listings/ltrace.txt new file mode 100644 index 0000000..ef4e67c --- /dev/null +++ b/thesis/listings/ltrace.txt @@ -0,0 +1,4 @@ +malloc(10) = 0x55624164b2a0 +printf("Hello World!\nString: %s\n", "Abc123") = 28 +free(0x55624164b2a0) = ++++ exited (status 0) +++ diff --git a/thesis/listings/main.c b/thesis/listings/main.c new file mode 100644 index 0000000..a877f00 --- /dev/null +++ b/thesis/listings/main.c @@ -0,0 +1,10 @@ +#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); +} diff --git a/thesis/listings/strace.txt b/thesis/listings/strace.txt new file mode 100644 index 0000000..21a4b8c --- /dev/null +++ b/thesis/listings/strace.txt @@ -0,0 +1,37 @@ +execve("./main", ["./main"], 0x7ffd63b32bb0 /* 71 vars */) = 0 +brk(NULL) = 0x55adbd615000 +access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) +openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 +fstat(3, {st_mode=S_IFREG|0644, st_size=277707, ...}) = 0 +mmap(NULL, 277707, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f79bd90b000 +close(3) = 0 +mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f79bd909000 +openat(AT_FDCWD, "/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 +read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0px\2\0\0\0\0\0"..., 832) = 832 +pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 840, 64) = 840 +fstat(3, {st_mode=S_IFREG|0755, st_size=2006328, ...}) = 0 +pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 840, 64) = 840 +mmap(NULL, 2030680, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f79bd719000 +mmap(0x7f79bd73d000, 1507328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24000) = 0x7f79bd73d000 +mmap(0x7f79bd8ad000, 319488, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x194000) = 0x7f79bd8ad000 +mmap(0x7f79bd8fb000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e1000) = 0x7f79bd8fb000 +mmap(0x7f79bd901000, 31832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f79bd901000 +close(3) = 0 +mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f79bd716000 +arch_prctl(ARCH_SET_FS, 0x7f79bd716740) = 0 +set_tid_address(0x7f79bd716a10) = 22451 +set_robust_list(0x7f79bd716a20, 24) = 0 +rseq(0x7f79bd716680, 0x20, 0, 0x53053053) = 0 +mprotect(0x7f79bd8fb000, 16384, PROT_READ) = 0 +mprotect(0x55ad87c2e000, 4096, PROT_READ) = 0 +mprotect(0x7f79bd98c000, 8192, PROT_READ) = 0 +prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 +munmap(0x7f79bd90b000, 277707) = 0 +getrandom("\xcf\x53\xd9\xf6\xf0\x89\x95\xbd", 8, GRND_NONBLOCK) = 8 +brk(NULL) = 0x55adbd615000 +brk(0x55adbd636000) = 0x55adbd636000 +fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0x2), ...}) = 0 +write(1, "Hello World!\n", 13) = 13 +write(1, "String: Abc123\n", 15) = 15 +exit_group(0) = ? ++++ exited with 0 +++ diff --git a/thesis/src/02.intercept.tex b/thesis/src/02.intercept.tex index 121920d..8507da2 100644 --- a/thesis/src/02.intercept.tex +++ b/thesis/src/02.intercept.tex @@ -7,10 +7,95 @@ Lorem Ipsum. Lorem Ipsum. + +\subsection{\texttt{ptrace} System Call}\label{subsec:ptrace} + +The first thing that pops up when researching on how to intercept system calls in Linux is the \texttt{ptrace} (``process trace'') system call. +This system call allows one process to observe and control the execution of another process (including memory and registers). +The control is handed from the traced process to the tracing process each time any signal is delivered. +\cite{ptrace.2} + +To make use of this system call, a corresponding command already exists. +See~\ref{subsec:strace}. + + +\subsection{\texttt{strace} Command}\label{subsec:strace} + +The \texttt{strace} (``system call/signal trace'') command may be used to run a specified command and to thereby intercept and record the system calls which are made. +Each system call is recorded as a line and either written to the standard error output or a specified file. +\cite{strace.1} + +Listings \ref{lst:main.c} and \ref{lst:strace} give a simple example of what this output looks like. +It is clearly visible that only (``pure'') system calls are recorded, and calls to library functions (like \texttt{malloc} or \texttt{free}) do not appear. +Also note that, arguments to the calls are displayed in a ``pretty'' way. +For example, strings 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} + \caption{Contents of \texttt{main.c}.} + \label{lst:main.c} +\end{listing} + +\begin{listing}[htbp] + \begin{minted}{text} +execve("./main", ["./main"], 0x7ffd63b32bb0 /* 71 vars */) = 0 +[-- 32 lines omitted --] +write(1, "Hello World!\n", 13) = 13 +write(1, "String: Abc123\n", 15) = 15 +exit_group(0) = ? ++++ exited with 0 +++ + \end{minted} + \caption{Output of \texttt{strace ./main}.} + \label{lst:strace} +\end{listing} + +This approach works great for debugging and other use-cases, +but only intercepting system calls does not statisfy the requirements for this work. + + +\subsection{\texttt{ltrace} Command}\label{subsec:ltrace} + +The \texttt{ltrace} (``library call trace'') command may be used to trace dynamic library calls instead of system calls. +It works similarly to \texttt{strace} (see \ref{subsec:strace}). +\cite{ltrace.1} + +Listings \ref{lst:main.c} and \ref{lst:ltrace} illustrate what the output of \texttt{ltrace} looks like. +In contrast to the output of \texttt{strace} now only ``real'' calls to library functions are included in the output. +Therefore, a lot less ``noise'' is generated (see omitted lines in listing \ref{lst:strace}). +Again, the function arguments are displayed in a ``pretty'' way. +This command uses so-called prototype functions~\cite{ltrace.conf.5} to format function arguments. + +\begin{listing}[htbp] + \begin{minted}{text} +malloc(10) = 0x55624164b2a0 +printf("Hello World!\nString: %s\n", "Abc123") = 28 +free(0x55624164b2a0) = ++++ exited (status 0) +++ + \end{minted} + \caption{Output of \texttt{ltrace ./main}.} + \label{lst:ltrace} +\end{listing} + +This method fits the requirements for this work a lot better than \texttt{strace} (see~\ref{subsec:strace}), +but it is not very flexible and offers no means to modify the intercepted function calls. + + \subsection{Wrapper Functions in gcc}\label{subsec:wrapper-functions} -Another method for overriding functions is to tell the compiler directly, which functions should be overridden. +A different approach to intercepting function calls is to tell the compiler directly, which functions should be intercepted. The compiler, and the linker respectively, then directly link calls to the specified functions to wrapper functions. +(See \ref{subsec:preloading} for more details.) The default linker \texttt{ld} includes such a feature. See the OPTIONS section in the ld(1) Linux manual page~\cite{ld.1}: @@ -47,7 +132,7 @@ See the OPTIONS section in the gcc(1) Linux manual page~\cite{gcc.1}: This means, by specifying \texttt{-Wl,-{}-wrap=\textit{symbol}} when compiling using gcc, all calls from the currently compiled program to \texttt{\textit{symbol}} are redirected to \texttt{\_\_wrap\_\textit{symbol}}. To call the real function inside the wrapper, \texttt{\_\_real\_\textit{symbol}} may be used. -The listings \ref{lst:wrap.c} and \ref{lst:wrap} try to illustrate this by overriding the \texttt{malloc} function of the C standard library. +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} @@ -111,7 +196,7 @@ See the ENVIRONMENT section in the ld.so(8) Linux manual page~\cite{ld.so.8}: \end{quote} This means, by setting the environment variable \texttt{LD\_PRELOAD}, it is possible to override specific functions. -The listings \ref{lst:preload.c} and \ref{lst:preload} try to illustrate this by overriding the \texttt{malloc} function of the C standard library. +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} @@ -153,18 +238,6 @@ By using this method, it is possible to override, and therefore wrap, any functi Although, one has to be aware that not only function calls inside the targeted binary, but also calls inside other libraries (e.g., to \texttt{malloc}) are redirected to the overriding function. -\subsection{Kernel Module}\label{subsec:kernel-module} - -Lorem Ipsum. - -\subsection{Emulation}\label{subsec:emulation} - -Lorem Ipsum. - -\subsection{Modifying the Kernel}\label{subsec:modifiying-kernel} - -Lorem Ipsum. - \subsection{Conclusion}\label{subsec:conclusion} Lorem Ipsum. diff --git a/thesis/src/99.intercept.bib b/thesis/src/99.intercept.bib index 1607897..2d8d820 100644 --- a/thesis/src/99.intercept.bib +++ b/thesis/src/99.intercept.bib @@ -10,3 +10,15 @@ @manual{gcc.1, title = {GCC(1) -- GNU -- Linux manual pages}, } +@manual{ptrace.2, + title = {ptrace(2) -- System Calls Manual -- Linux manual pages}, +} +@manual{strace.1, + title = {STRACE(1) -- General Commands Manual -- Linux manual pages}, +} +@manual{ltrace.1, + title = {LTRACE(1) -- User Commands -- Linux manual pages}, +} +@manual{ltrace.conf.5, + title = {ltrace.conf(5) -- ltrace configuration file -- Linux manual pages}, +}