--- title: "Dr. Syscall: System Call Monitoring Extension" layout: default permalink: /page_drsyscall.html ---

Dr. Memory

Dr. Syscall: System Call Monitoring Extension

The `drsyscall` DynamoRIO Extension provides system call monitoring features beyond the basics in the DynamoRIO API itself. `drsyscall` is part of the Dr. Memory Framework.

- Setup
- Event Replacement
- Dr. Syscall API
- System Call Numbers

# Setup

To use `drsyscall` with your client, first locate the Dr. Memory Framework. Then use the standard method of using an Extension with the name `drsyscall`. The two steps will look like this in your client's `CMakeLists.txt` file:

find_package(DrMemoryFramework)
use_DynamoRIO_extension(clientname drsyscall)

To point CMake at the framework, set the DrMemoryFramework_DIR variable to point at the `drmf` subdirectory of the Dr. Memory package that you are using. For example:

cmake -G"Ninja" -DDynamoRIO_DIR=c:/path/to/DynamoRIO-Windows-4.1.0-8/cmake -DDrMemoryFramework_DIR=c:/path/to/DrMemory-Windows-1.6.0-2/drmf ../mysrcs/

That will automatically set up the include path and library dependence.

Your client must call `drsys_init()` prior to accessing any API routines in `drsyscall`, and should call `drsys_exit()` at process exit time.

# Event Replacement

`drsyscall` uses the `drmgr` Extension to ensure its events occur at the proper order. A user of `drsyscall` must use the `drmgr` versions of the basic block and thread events.

# Dr. Syscall API

`drsyscall` provides the following key features:

1. System call name to number querying
2. System call number to name querying
3. System call argument type iteration
4. System call argument value iteration
5. Query whether a system call return value indicates success
6. Iteration over every memory region read or written by a system call
7. Storage of system call argument values for access in post-syscall events

Many features of `drsyscall` operate on the current in-progress system call. The client should register for the pre- and post-syscall events through `drmgr`. In those events, the client can then invoke `drsyscall` API routines to query the current system call. The client should normally use a default priority for its system call events to ensure that `drsyscall's` per-system-call initialization is in place prior to invoking `drsyscall` functions.

If the client wishes to modify the machine context, system call parameters, or system call return value, the client must use a separate system call event that is ordered prior to DRMGR_PRIORITY_PRESYS_DRSYS or DRMGR_PRIORITY_POSTSYS_DRSYS.

The client can statically iterate over the types of the parameters to every system call in its dr_init() routine and decide which system calls it wants to monitor. It should then request that `drsyscall` filter those system calls. Only filtered system calls can be dynamically queried.

When dealing with system call results and identifying whether a system call succeeded, drsys_cur_syscall_result() distinguishes itself from dr_syscall_get_result_ex() by providing accurate results for all system calls, in particular including Windows win32k.sys graphical (NtGdi) and user (NtUser) system calls. It also knows which system calls return 64-bit results, elminating the need for the caller to specifically request the top 32 bits in such cases. For setting the result value of a system call, currently `drsyscall` does not provide its own routine and dr_syscall_set_result_ex() should be used.

# System Call Numbers

On Linux, the system call number is the standard number exported by the kernel. For `SYS_ioctl`, a secondary number indicates the request code. `drsyscall` does not currently split the 32-bit SYS_socketcall or IPC system calls into secondary numbers.

On Windows, `drsyscall` uses the raw number from the eax register. This includes the WOW64 index stored in the upper 16 bits on Windows 8 and beyond. Secondary numbers are used for `NtUserCall*` system calls.

For MacOS, whether 32-bit or 64-bit, we normalize the system call number to a positive integer with the top 8 bits set to 0x1 for a Mach system call, 0x3 for Machdep, and 0x0 for BSD (allowing the direct use of SYS_ constants). The user can access the raw eax register in the pre-syscall event to view the unmodified number, whose encoding varies depending on the bitwidth and interrupt vector used.