DynamoRIO clients
This commit is contained in:
6
doc.tex
6
doc.tex
@@ -156,9 +156,9 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%{{{%
|
||||
%\onehalfspacing % Stelle 1.5er Abstand ein
|
||||
%\setstretch{1.1}
|
||||
\input{inc/1.introduction}
|
||||
\newpage
|
||||
\clearpage
|
||||
% \input{inc/1.introduction}
|
||||
% \newpage
|
||||
% \clearpage
|
||||
|
||||
\input{inc/2.dynamorio}
|
||||
\newpage
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
\label{sec:dynamorio}
|
||||
|
||||
This section will give a short overview of the dynamic binary instrumentation tool DynamoRIO, which will be used throughout this thesis.
|
||||
It is mainly based on on the chapter \textit{DynamoRIO} and \textit{Code Cache} of \cite{Bruening2004} as well as on \cite{Bruening2003}.
|
||||
|
||||
\subsection{Dynamic Binary Instrumentation}
|
||||
\label{sec:dbi}
|
||||
@@ -9,11 +10,11 @@ This section will give a short overview of the dynamic binary instrumentation to
|
||||
\revabbr{Dynamic binary instrumentation}{DBI} is a method for analyzing and manipulating the behavior of a binary application while it is running.
|
||||
This is achieved through the injection of additional instructions into the instruction trace of the target application.
|
||||
|
||||
Debuggers on the other hand, use special breakpoint instructions (e.g. INT3 on x86 or BKPT on ARM) that get injected at specific places in the code.
|
||||
When reaching those breakpoint instructions, a context switch to the operating system kernel will be performed, however, those context switches, result in a significant performance penalty as the processor state has to be saved and restored afterwards. (TODO irgendwie literatur referenz hier)
|
||||
Debuggers on the other hand, use special breakpoint instructions (e.g. INT3 on x86 or BKPT on ARM) that get injected at specific places in the code, raising a debug exception when reaching it.
|
||||
At those exceptions a context switch to the operating system kernel will be performed, however, those context switches result in a significant performance penalty as the processor state has to be saved and restored afterwards. (TODO irgendwie literatur referenz hier)
|
||||
|
||||
Because the instrumentation tool runs in the same process as the application, it is important that it operates transparently, meaning that it will not affect the application behavior in unintended ways.
|
||||
This is a special challenge as the dynamic instrumentation is not allowed to use the same memory routines or input/output buffering as the application \cite{Bruening2003}.
|
||||
This is a special challenge as the dynamic instrumentation is not allowed to use the same memory routines or input/output buffering as the target application \cite{Bruening2003}.
|
||||
|
||||
In contrast to static code analysis, which cannot predict the execution path of the program, the full runtime information is available to the dynamic instrumentation.
|
||||
|
||||
@@ -21,10 +22,28 @@ So DBI can be a mature choice for examining the runtime behavior of a binary app
|
||||
|
||||
The following section \ref{sec:dynamorio_core} will explain how the core functionality of the DBI tool DynamoRIO works.
|
||||
|
||||
\subsection{DynamoRIO Core}
|
||||
\subsection{Core Functionality}
|
||||
\label{sec:dynamorio_core}
|
||||
|
||||
% vlt auf transparenz eingehen wie dies gelöst wird.
|
||||
A simple way observe and potentially modify the instructions of an application during execution is the use of a interpretation engine, where the binary gets emulated.
|
||||
This approach, however, might be powerful but is very slow.
|
||||
|
||||
DynamoRIO on the other hand uses a so called \textit{code cache} where \textit{basic blocks} get copied into prior to execution.
|
||||
A basic block is a sequence of instructions that end with a single control transfer instruction.
|
||||
In the code cache basic blocks get extended by two \textit{exit stubs}, ensuring that at the end the control is transferred back to DynamoRIO via a context switch.
|
||||
From there the applications state is saved and the next basic block will be copied into the code cache, modified and executed after restoring the applications state.
|
||||
Basic blocks that are already in the code cache get directly executed, however, a context switch is still needed to determine the next basic block.
|
||||
To reduce this overhead, DynamoRIO can \textit{link} two basic blocks together that were targeted by a direct branch, avoiding the context switch.
|
||||
For indirect branches it is not possible to link them as their target basic blocks may vary and DynamoRIO needs to translate the branch address to the address of the basic block in the code cache.
|
||||
However, basic block that are often executed in a sequence are be merged into a \textit{trace}.
|
||||
At the end of each basic block, a additional check is performed to determine if the indirect branch target will stay in the same trace, possibly preventing the context switch.
|
||||
The generic term for a basic block or a trace is a \textit{fragment}.
|
||||
|
||||
Figure \ref{fig:dynamorio} illustrates the functionality of DynamoRIO.
|
||||
The application code will get loaded by the dispatcher, modified by the basic block builder and finally be executed in the code cache.
|
||||
|
||||
% vlt noch auf transparenz eingehen wie dies gelöst wird.
|
||||
|
||||
\input{img/thesis.tikzstyles}
|
||||
\begin{figure}[!ht]
|
||||
\begin{center}
|
||||
@@ -34,9 +53,44 @@ The following section \ref{sec:dynamorio_core} will explain how the core functio
|
||||
\end{center}
|
||||
\end{figure}
|
||||
|
||||
\subsection{DynamoRIO Client}
|
||||
\subsection{Clients}
|
||||
\label{sec:dynamorio_client}
|
||||
|
||||
Currently, the presence of DynamoRIO does not have an effect other than that the application is executed from the code cache.
|
||||
Clients make it possible to dynamically modify the basic blocks, either to alter the application behavior or to insert observational instructions.
|
||||
A DynamoRIO client is compiled into a shared library and passed to the \textit{drrun} utility using a command line option.
|
||||
It then can implement a number of hook functions that get called by DynamoRIO such as the basic block creation or the trace creation event.
|
||||
It is important to note that hooks like the basic block creation function do not get called when this basic block is executed but when it is generated and placed into the code cache.
|
||||
|
||||
\subsection{DynamoRIO API}
|
||||
\label{sec:dynamorio_api}
|
||||
The table \ref{tab:dynamorio_api} lists the most important hooks that a client can implement.
|
||||
|
||||
\begin{table}[!ht]
|
||||
\caption{Client routines that get called by DynamoRIO \cite{Bruening2003}.}
|
||||
\begin{center}
|
||||
\begin{tabular}{|p{0.6\linewidth} | p{0.4\linewidth}|}
|
||||
\hline
|
||||
Client Routine & Description\\
|
||||
\hline
|
||||
\hline
|
||||
void dynamorio\_init() & Client initialization\\
|
||||
\hline
|
||||
void dynamorio\_exit() & Client finalization\\
|
||||
\hline
|
||||
void dynamorio\_thread\_init(void *context) & Client per-thread initialization\\
|
||||
\hline
|
||||
void dynamorio\_thread\_exit(void *context) & Client per-thread finalization\\
|
||||
\hline
|
||||
void dynamorio\_basic\_block(void *context, app\_pc tag, IntrList *bb) & Client processing of basic block\\
|
||||
\hline
|
||||
void dynamorio\_trace(void *context, app\_pc tag, IntrList *trace) & Client processing of trace\\
|
||||
\hline
|
||||
void dynamorio\_fragment\_deleted(void *context, app\_pc tag) & Notifies client when a fragment is deleted from the code cache\\
|
||||
\hline
|
||||
void dynamorio\_end\_trace(void *context, app\_pc trace\_tag, app\_pc next\_tag) & Asks client whether to end the current trace\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\label{tab:dynamorio_api}
|
||||
\end{table}
|
||||
|
||||
A client that already comes with DynamoRIO is DrCacheSim with the DrMemtrace-Framework, which will be further explained in section \ref{sec:analysis_tool}.
|
||||
|
||||
@@ -116,7 +116,7 @@ This hierarchy is also reflected in the DbiPlayer as shown in Figure \ref{fig:db
|
||||
\label{sec:dbiplayer_functionality}
|
||||
|
||||
With the overall architecture of the initiator introduced, this section explains the internal functionality of the DbiPlayer and its threads.
|
||||
As mentioned previously, the threads cannot run by themself, rather they require synchronization to ensure the simulated system replicates the real running application as good as possible.
|
||||
As mentioned previously, the threads cannot run by themselves, rather they require synchronization to ensure the simulated system replicates the real running application as good as possible.
|
||||
The analysis tool appends timestamps into the memory access traces that will be used to pause the execution of a thread, when the global time has not yet reached this far yet, or to advance the global time, when the thread is allowed to run.
|
||||
It is to note that the term global time in this context does not correspond to the SystemC simulation time but denotes a loose time variable that the DbiPlayer uses to schedule its threads.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user