1
0

Compare commits

...

2 Commits

Author SHA1 Message Date
4c91cf7a6e proj: Add perf/ 2025-08-13 12:26:10 +02:00
b48c5b4921 thesis: Incorporate feedback 2025-08-13 12:23:20 +02:00
8 changed files with 112 additions and 39 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@ bin/
*.log *.log
*.pdf *.pdf
related-work/ related-work/
main

View File

@@ -1240,7 +1240,7 @@ void sym(exit)(int status) {
char msg_buf[BUFFER_SIZE]; char msg_buf[BUFFER_SIZE];
rcv(msg_buf, sizeof(msg_buf)); rcv(msg_buf, sizeof(msg_buf));
if_modify_int("exit", int, status) if_modify_int("exit", int, status)
else if_invalid(getopt) else if_invalid(exit)
} }
__real_exit(status); __real_exit(status);
} }

16
proj/perf/Makefile Normal file
View File

@@ -0,0 +1,16 @@
CC=gcc
CFLAGS=-std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809L -g
.PHONY: all clean
all: default
default: main
main.o: main.c
$(CC) -c -o $@ $^ $(CFLAGS)
main: main.o
$(CC) -o $@ $^ $(CFLAGS) -lc
clean:
rm -rf main *.o

33
proj/perf/main.c Normal file
View File

@@ -0,0 +1,33 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
int main(const int argc, const char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: main <cycles>\n");
return 1;
}
const long cycles = strtol(argv[1], NULL, 10);
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
int pipes[2];
for (int i = 0; i < cycles; i++) {
if (pipe(pipes) != 0) {
fprintf(stderr, "unable to create pipes: %s\n", strerror(errno));
exit(1);
}
close(pipes[0]);
close(pipes[1]);
}
clock_gettime(CLOCK_MONOTONIC, &end);
const long duration = end.tv_sec * 1000000000 + end.tv_nsec - start.tv_sec * 1000000000 - start.tv_nsec;
printf("start: %li.%09li\nend: %li.%09li\nduration: %li,%03li,%03li ns\n", start.tv_sec, start.tv_nsec, end.tv_sec, end.tv_nsec, duration / 1000000, duration / 1000 % 1000, duration % 1000);
}

22
proj/perf/test.sh Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
REPEAT=30
CYCLES=50
function test() {
echo $@
for c in $(seq 1 $CYCLES); do
for i in $(seq 1 $REPEAT); do
echo "cycles: $((c * 100)) ($i/$REPEAT)"
$@ $((c * 100))
sleep 1
done
done
}
test ./main
cd ../intercept
test ./intercept -o -i - -- ../perf/main
test ./intercept -o -i stderr -- ../perf/main
test ./intercept -o -i file:out.log -- ../perf/main
#test ./intercept -o -i unix:/ -- ../perf/main

View File

@@ -14,29 +14,29 @@ Therefore, it is obvious, why many university courses still require students to
The problem when trying to verify, if students correctly implemented their assignment is that low-level OS constructs (like semaphores, pipes, sockets, memory management) make it hard to run automated tests, because the testing system needs to keep track, set up, and verify the usage of these resources. The problem when trying to verify, if students correctly implemented their assignment is that low-level OS constructs (like semaphores, pipes, sockets, memory management) make it hard to run automated tests, because the testing system needs to keep track, set up, and verify the usage of these resources.
The goal of this work was to find a way to easily intercept system or function calls and to verify if students called the right functions with the right arguments at the right time. The goal of this work was to find a way to easily intercept system or function calls and to verify if students called the right functions with the right arguments at the right time.
This restriction in scope allows to focus on simple binary programs without having to think about complex or I/O heavy programs. This restriction in scope allows focusing on simple binary programs without having to think about complex or I/O heavy programs.
Furthermore, in this setting the source code of the student's programs is obviously available because this is what they need to deliver. Furthermore, in this setting the source code of the student's programs is obviously available because this is what they need to deliver.
The availability of source code is a key concern when trying to intercept function or system calls as will be clear in the next chapters. The availability of source code is a key concern when trying to intercept function or system calls, as will be clear in the next chapters.
\section{Definitions}\label{sec:definitions} \section{Definitions}\label{sec:definitions}
First, function calls, system calls and their differences need to be defined. First, function calls, system calls, and their differences need to be defined.
The following subsections concern these definitions. The following subsections concern these definitions.
\subsection{Function Calls}\label{subsec:function-calls} \subsection{Function Calls}\label{subsec:function-calls}
Generally, a function in C (and also most other programming languages) is a piece of code which may be called and therefore executed from elsewhere. Generally, a function in C (and also most other programming languages) is a piece of code that may be called and therefore executed from elsewhere.
Functions have zero or more arguments and return a single value. Functions have zero or more arguments and return a single value.
When calling a function, the caller places the return address onto the stack. When calling a function, the caller places the return address onto the stack.
This address indicates where the function should continue executing when it is finished. This address indicates where the function should continue executing when it is finished.
Functions are used to structure programs, reuse functionality, or expose functionality in libraries. Functions are used to structure programs, reuse functionality, or expose functionality in libraries.
Other languages than C differentiate between functions, methods, procedures and so on. Other languages than C differentiate between functions, methods, procedures, and so on.
A function written in the source code is almost always compiled to a function in the resulting binary. A function written in the source code is almost always compiled to a function in the resulting binary.
Intercepting calls to functions would one allow to see the name of the function, arguments, return value, and return address. Intercepting calls to functions would one allow seeing the name of the function, arguments, return value, and return address.
\subsection{System Calls}\label{subsec:system-calls} \subsection{System Calls}\label{subsec:system-calls}
@@ -47,11 +47,11 @@ By invoking a system call, the (user-space) process hands control over to the (p
\cite[Chapter~10]{linuxkernel} \cite[Chapter~10]{linuxkernel}
How exactly these system calls work is architecture and system specific. How exactly these system calls work is architecture and system specific.
But generally, the process places the system call number, and its arguments in defined registers and then executes a special system call opcode. But generally, the process places the system call number and its arguments in defined registers and then executes a special system call opcode.
Then the kernel executes the requested operation and places the return value inside another register, and lastly hands the execution back to the process. Then the kernel executes the requested operation and places the return value inside another register, and lastly hands the execution back to the process.
\cite[Chapter~10]{linuxkernel} \cite[Chapter~10]{linuxkernel}
Intercepting calls to system calls would one allow to see the system call number, arguments and return value. Intercepting calls to system calls would one allow seeing the system call number, arguments, and return value.
One has to keep in mind, that many system-related functionalities are not in fact translated to system calls one-to-one. One has to keep in mind that many system-related functionalities are not in fact translated to system calls one-to-one.
For example \texttt{malloc}~\cite{malloc.3} has no dedicated system call, it is managed by the C standard library internally. For example, \texttt{malloc}~\cite{malloc.3} has no dedicated system call, it is managed by the C standard library internally.
Many system calls have corresponding wrapper functions in the C standard library (like \texttt{open}, \texttt{close}, \texttt{sem\_wait}). Many system calls have corresponding wrapper functions in the C standard library (like \texttt{open}, \texttt{close}, \texttt{sem\_wait}).

View File

@@ -1,18 +1,17 @@
\chapter{Intercepting Function Calls}\label{ch:intercepting-function-calls} \chapter{Intercepting Function Calls}\label{ch:intercepting-function-calls}
In this chapter all steps on how to intercept function calls in this work are discussed. In this chapter, all steps on how to intercept function calls in this work are discussed.
An example of what the resulting interception looks like may be found in Section~\ref{sec:intercepting-example}. An example of what the resulting interception looks like may be found in Section~\ref{sec:intercepting-example}.
Furthermore, an overview on how to test given programs is presented in Section~\ref{sec:automated-testing-on-intercepted-function-calls}. Furthermore, an overview on how to test given programs is presented in Section~\ref{sec:automated-testing-on-intercepted-function-calls}.
This chapter does not discuss how these function calls may be manipulated in any way. How these function calls may be manipulated is discussed in Chapter~\ref{ch:manipulating-function-calls}.
For that see Chapter~\ref{ch:manipulating-function-calls}.
\section{Identified Methods for Intercepting Function and System Calls}\label{sec:methods-for-intercepting} \section{Identified Methods for Intercepting Function and System Calls}\label{sec:methods-for-intercepting}
First, one has to answer the question on \textit{how exactly} to intercept function or system calls. First, one has to answer the question on \textit{how exactly} to intercept function or system calls.
At the beginning of this work it was not yet determined if the interception of function calls, system calls, or both should be used to achieve the overarching goal (see Section~\ref{sec:motivation-and-goal}). At the beginning of this work, it was not yet determined if the interception of function calls, system calls, or both should be used to achieve the overarching goal (see Section~\ref{sec:motivation-and-goal}).
This first section tries to list all possible methods on how to intercept function or system calls but does not claim completeness. This first section tries to list all possible and relevant methods on how to intercept function or system calls but does not claim exhaustiveness.
The order of the following subsections is roughly based on the thought process on finding the most appropriate method suitable for this work. The order of the following subsections is roughly based on the thought process on finding the most appropriate method suitable for this work.
@@ -135,7 +134,7 @@ See the gcc(1) Linux manual page~\cite[Section OPTIONS]{gcc.1}:
This means, by specifying \texttt{-Wl,-{}-wrap=\textit{symbol}} when compiling using gcc, 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}}. 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. To call the real function inside the wrapper, \texttt{\_\_real\_\textit{symbol}} may be used.
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} illustrate this by overriding the \texttt{malloc} function of the C standard library.
\begin{listing}[htbp] \begin{listing}[htbp]
\inputminted[linenos]{c}{src/listings/wrap.c} \inputminted[linenos]{c}{src/listings/wrap.c}
@@ -159,7 +158,7 @@ Therefore, the source code (or the corresponding \texttt{*.out} files) needs to
Note, only calls from the targeted source code will be redirected, calls from other libraries won't. Note, only calls from the targeted source code will be redirected, calls from other libraries won't.
Theoretically, it should be possible to re-link a given binary without having access to its source code. Theoretically, it should be possible to re-link a given binary without having access to its source code.
But due to other more straight-forward methods (see Subsection~\ref{subsec:preloading}), this has not been further investigated. But due to other more straight-forward methods (see Subsection~\ref{subsec:preloading}), this has not been investigated further.
\subsection{Preloading using \texttt{LD\_PRELOAD}}\label{subsec:preloading} \subsection{Preloading using \texttt{LD\_PRELOAD}}\label{subsec:preloading}
@@ -188,7 +187,7 @@ See the ld.so(8) Linux manual page~\cite[Section ENVIRONMENT]{ld.so.8}:
\end{quote} \end{quote}
This means, by setting the environment variable \texttt{LD\_PRELOAD}, it is possible to override specific functions. This means, by setting the environment variable \texttt{LD\_PRELOAD}, it is possible to override specific functions.
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} illustrate this by overriding the \texttt{malloc} function of the C standard library.
\begin{listing}[htbp] \begin{listing}[htbp]
\inputminted[linenos]{c}{src/listings/preload.c} \inputminted[linenos]{c}{src/listings/preload.c}
@@ -218,10 +217,10 @@ Although, one has to be aware that not only function calls inside the targeted b
During the research on different approaches to intercepting system and function calls, During the research on different approaches to intercepting system and function calls,
it has been found that the most reliable way to achieve the goals of this work (see Section~\ref{sec:motivation-and-goal}) is to intercept function calls instead of system calls. it has been found that the most reliable way to achieve the goals of this work (see Section~\ref{sec:motivation-and-goal}) is to intercept function calls instead of system calls.
This is because (as long as the programs to test are dynamically linked), intercepting function calls allows one to intercept many more calls and in a more flexible way. This is because---as long as the programs to test are dynamically linked---, intercepting function calls allows one to intercept many more calls and in a more flexible way.
Therefore, from now on this work only considers function calls and no system calls directly. Therefore, from now on this work only considers function calls and no system calls directly.
In this work preloading (see Subsection~\ref{subsec:preloading}) was chosen to be used In this work, preloading (see Subsection~\ref{subsec:preloading}) was chosen to be used
because it is simple to use (``clean'' source code, easy to compile and run programs with it) and offers the means to arbitrarily execute code when the intercepted function call is redirected. because it is simple to use (``clean'' source code, easy to compile and run programs with it) and offers the means to arbitrarily execute code when the intercepted function call is redirected.
The following sections concern the next steps in what else is needed to create a powerful ``interceptor''. The following sections concern the next steps in what else is needed to create a powerful ``interceptor''.
@@ -231,7 +230,7 @@ The following sections concern the next steps in what else is needed to create a
After deciding to use the preloading method to intercept function calls, a more detailed plan is needed to continue developing. 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. 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. The easiest and most straightforward way to structure the source code was to put all code in one single C file.
Listing~\ref{lst:intercept-preload.c} gives an overview over the grounding code structure. Listing~\ref{lst:intercept-preload.c} gives an overview of the underlying code structure.
For each function that should be intercepted, this function simply has to be declared and defined the same way \texttt{malloc} was. For each function that should be intercepted, this function simply has to be declared and defined the same way \texttt{malloc} was.
\begin{listing}[htbp] \begin{listing}[htbp]
@@ -244,8 +243,8 @@ For each function that should be intercepted, this function simply has to be dec
\section{Retrieving Function Argument Values}\label{sec:retrieving-function-argument-values} \section{Retrieving Function Argument Values}\label{sec:retrieving-function-argument-values}
Now that the first steps have been done, one needs to think about what exactly to record when intercepting. Now that the first steps have been done, one needs to think about what exactly to record when intercepting.
A simple notification that a given function was called would be too less. A simple notification that a given function was called would not be sufficient.
Within the following subsections it is tried to get as much information as possible from each function call. Within the following subsections, effort is put into getting as much information as possible from each function call.
As already mentioned, \texttt{ltrace} uses prototype functions to format its function arguments. As already mentioned, \texttt{ltrace} uses prototype functions to format its function arguments.
This allows \texttt{ltrace} to ``dynamically'' display function arguments for any new or unknown functions without the need for recompilation. This allows \texttt{ltrace} to ``dynamically'' display function arguments for any new or unknown functions without the need for recompilation.
@@ -254,9 +253,9 @@ This allows \texttt{ltrace} to ``dynamically'' display function arguments for an
However, due to implementation complexity reasons and the need for ``complex'' return types for string/buffer and structure values (see Section~\ref{sec:retrieving-function-return-values}) a statically compiled approach has been used for this work. However, due to implementation complexity reasons and the need for ``complex'' return types for string/buffer and structure values (see Section~\ref{sec:retrieving-function-return-values}) a statically compiled approach has been used for this work.
This means that each function formats its arguments and return values itself without any configuration option. This means that each function formats its arguments and return values itself without any configuration option.
The reason for retrieving as much information as possible from each function call is that at a later point in time it is possible to completely reconstruct the exact function calls and their sequence. The reason for retrieving as much information as possible from each function call is that at a later point in time, it is possible to completely reconstruct the exact function calls and their sequence.
This allows analysis on these records to be performed independently of the corresponding execution of the program. This allows analysis on these records to be performed independently of the corresponding execution of the program.
It should always be possible for any parser to fully parse the recorded calls without any specific knowledge of specific functions, their argument types, or return value type. It should always be possible to fully parse the recorded calls without any specific knowledge of specific functions, their argument types, or return value type.
\subsection{Numbers}\label{subsec:retrieving-numbers} \subsection{Numbers}\label{subsec:retrieving-numbers}
@@ -293,7 +292,7 @@ Example: \texttt{write(3, 0x1234:"Test\textbackslash{}x00ABC", 8)}.
\subsection{Flags}\label{subsec:retrieving-flags} \subsection{Flags}\label{subsec:retrieving-flags}
Some functions have one of their arguments dedicated to flags which may be combined by bitwise XOR. Some functions have one of their arguments dedicated to flags which may be combined by bitwise XOR\@.
These arguments are also of type integer. These arguments are also of type integer.
To distinguish flag arguments from others, a pipe symbol (\texttt{|}) is used after the colon and between the flags. To distinguish flag arguments from others, a pipe symbol (\texttt{|}) is used after the colon and between the flags.
@@ -304,7 +303,7 @@ Example: \texttt{open(0x1234:"test.txt", 0102:|O\_CREAT|O\_RDWR|, 0644)}.
For some functions constants are used. For some functions constants are used.
These constants are typically used C macros in the source code. These constants are typically used C macros in the source code.
This makes the source code more readable (and portable). This makes the source code more readable (and portable).
Constants are represented as an integer again followed by a colon, this time without any special characters to disdinguish them from other types. Constants are represented as an integer again followed by a colon, this time without any special characters to distinguish them from other types.
Example: \texttt{socket(2:AF\_INET, 1:SOCK\_STREAM, 6)}. Example: \texttt{socket(2:AF\_INET, 1:SOCK\_STREAM, 6)}.
@@ -320,7 +319,7 @@ Example: \\
\subsection{Pointers to Structures}\label{subsec:retrieving-pointers-to-structures} \subsection{Pointers to Structures}\label{subsec:retrieving-pointers-to-structures}
In rare cases structures (\texttt{struct}) are used as argument types. In rare cases, structures (\texttt{struct}) are used as argument types.
Two curly brackets (\texttt{\{\}}) are used to indicate structures. Two curly brackets (\texttt{\{\}}) are used to indicate structures.
Then the field names are displayed plainly, followed by a colon and then the value of that field. Then the field names are displayed plainly, followed by a colon and then the value of that field.
Commas are used to separate the fields respectively. Commas are used to separate the fields respectively.
@@ -347,13 +346,15 @@ Example (\texttt{read}): \\
\texttt{return 12; errno 0; buf=0x7fff70:"Hello World!"}, \\ \texttt{return 12; errno 0; buf=0x7fff70:"Hello World!"}, \\
\texttt{return -1; errno EINTR}. \texttt{return -1; errno EINTR}.
\todo{Explain Examples}
\section{Determining Function Call Location}\label{sec:determining-function-call-location} \section{Determining Function Call Location}\label{sec:determining-function-call-location}
Besides from argument values and return values, it would be interesting to know from where inside the intercepted program the function call came from. Besides argument values and return values, it would be interesting to know from where inside the intercepted program the function call came.
At first this seems quite impossible. At first this seems quite impossible.
But a function always knows at least the return address, the address to set then instruction pointer to when the function finishes. But a function always knows at least the return address, the address to set the instruction pointer to when the function finishes.
With this information it may be estimated where the call to the current function came from. With this information, it may be estimated where the call to the current function came from.
\subsection{Return Address and Relative Position}\label{subsec:return-address-and-relative-position} \subsection{Return Address and Relative Position}\label{subsec:return-address-and-relative-position}
@@ -486,7 +487,7 @@ The shared object currently supports intercepting the following functions:
\section{\texttt{intercept} Command}\label{sec:intercept-command} \section{\texttt{intercept} Command}\label{sec:intercept-command}
To make the usage of the aforementioned shared object more easy, a simple python script has been put together. To make the usage of the aforementioned shared object easier, a simple python script has been put together.
This script may be used as a command line tool. This script may be used as a command line tool.
See Listing~\ref{lst:intercept}. See Listing~\ref{lst:intercept}.
@@ -551,14 +552,14 @@ This includes the offset relative to the calling binary and a source file and li
\section{Automated Testing on Intercepted Function Calls}\label{sec:automated-testing-on-intercepted-function-calls} \section{Automated Testing on Intercepted Function Calls}\label{sec:automated-testing-on-intercepted-function-calls}
The recorded function calls of a program run now may be used to perform checks and tests on them. The recorded function calls of a program run may now be used to perform checks and tests on them.
It is trivially possible to check which functions were called and in what order. It is trivially possible to check which functions were called and in what order.
Furthermore, it is possible to check various pre- and post-conditions for each function call. Furthermore, it is possible to check various pre- and post-conditions for each function call.
This is beneficial because many library functions in C rely on these pre- and post-conditions, which are not enforced by the compiler or in any other way. This is beneficial because many library functions in C rely on these pre- and post-conditions, which are not enforced by the compiler or in any other way.
For example, the \texttt{malloc} function has the post-condition that the returned value later needs to be passed to \texttt{free} to avoid memory leaks. For example, the \texttt{malloc} function has the post-condition that the returned value later needs to be passed to \texttt{free} to avoid memory leaks.
The \texttt{free} function, on the other hand, has the pre-condition that the passed value was previously acquired using \texttt{malloc} and may not be yet free'd. The \texttt{free} function, on the other hand, has the pre-condition that the passed value was previously acquired using \texttt{malloc} and may not be yet free'd.
Any violation of such pre- and post-conditions may be reported as incompliant behavior. Any violation of such pre- and post-conditions may be reported as non-compliant behavior.
\cite{malloc.3} \cite{malloc.3}
This means that intercepted function calls allow a tester to check if programmers use library function in compliance to their specification. This means that intercepted function calls allow a tester to check if programmers use library function in compliance to their specification.

View File

@@ -2,9 +2,9 @@
\chapter{Manipulating Function Calls}\label{ch:manipulating-function-calls} \chapter{Manipulating Function Calls}\label{ch:manipulating-function-calls}
This chapter discusses how to manipulate function calls and how this may be used to test programs. This chapter discusses how to manipulate function calls and how this may be used to test programs.
For how function calls may be intercepted at all, see Chapter~\ref{ch:intercepting-function-calls}. How function calls may be intercepted at all is discussed in Chapter~\ref{ch:intercepting-function-calls}.
This chapter builds on the basis of the previous one and expands its functions. This chapter builds on the basis of the previous one and expands its functions.
``Manipulation'' in this context means to change the arguments of a function then running it normally, or skipping the execution of the real function completely and simply returning a given value (``mocking''). ``Manipulation'' in this context means to change the arguments of a function then calling it with those changed arguments, or skipping the execution of the real function completely and simply returning a given value (``mocking'').
These techniques allow in-depth testing of programs. These techniques allow in-depth testing of programs.
In contrast to simply recording and logging function calls which may be controlled via environment variables, manipulation of such function calls requires some other process to indicate how to handle each call. In contrast to simply recording and logging function calls which may be controlled via environment variables, manipulation of such function calls requires some other process to indicate how to handle each call.
@@ -62,7 +62,7 @@ Figure~\ref{fig:control-flow} illustrates the control flow for manipulating func
\section{Defining a Protocol}\label{sec:defining-a-protocol} \section{Defining a Protocol}\label{sec:defining-a-protocol}
When using a socket to communicate with another process, a protocol definition is needed. When using a socket to communicate with another process, a protocol definition is needed.
This works defines a text-based protocol in which line breaks denote the end of a message. This work defines a text-based protocol in which line breaks denote the end of a message.
The following subsections describe the defined message types. The following subsections describe the defined message types.
\subsection{\textit{Init} Message (Client \textrightarrow{} Server)}\label{subsec:init-message} \subsection{\textit{Init} Message (Client \textrightarrow{} Server)}\label{subsec:init-message}
@@ -72,7 +72,7 @@ The client (\texttt{intercept.so}) uses it to identify the running program to th
\subsection{\textit{Call} Message (Client \textrightarrow{} Server)}\label{subsec:call-message} \subsection{\textit{Call} Message (Client \textrightarrow{} Server)}\label{subsec:call-message}
For each function call the client sends this message to the server and waits for a reply (\textit{Action} message). For each function call, the client sends this message to the server and waits for a reply (\textit{Action} message).
The contents of this message type correspond to the first line of an intercepted function call (see Section~\ref{sec:automated-testing-on-intercepted-function-calls}). The contents of this message type correspond to the first line of an intercepted function call (see Section~\ref{sec:automated-testing-on-intercepted-function-calls}).
\subsection{\textit{Action} Message (Server \textrightarrow{} Client)}\label{subsec:action-message} \subsection{\textit{Action} Message (Server \textrightarrow{} Client)}\label{subsec:action-message}