Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

What is a direct syscall?

Warning

Wrapper routines in kernel32.dll and kernelbase.dll can be hooked by EDRs. Bypassing them with direct syscalls avoids those hooks but introduces other telltales (e.g. return address) that we’ll cover when we talk about indirect syscalls.

Over in The flow to a syscall, you see what are viewed as wrappers that wrap around direct syscalls. Some of the wrapping could be seen as bloat or unwanted overhead in a program. Also, those wrapper routines can be subject to user mode hooks, but let’s leave hooks out of this for now.

An option that can be done is to avoid those wrapper functions that are typically found in kernel32.dll and kernelbase.dll, to name a few, and just go directly to the syscall itself in ntdll.dll. This action is how the technique named direct syscalls was born. Skip all of the higher level stuff and go directly to the lowest level possible.

Syscall stub

We have already seen the format of a syscall and many folks simply call it a stub that prepares for the transition from ring 3 to ring 0, since a Windows installation only configures Intel CPUs to use those two rings (there are rings 1 and 2). The transition of rings is not done until the syscall instruction is executed. At that point in time, user mode code is left behind and the system will make the transition from ring 3 to ring 0. This will also change something called the Current Privilege Level (CPL) to 0.

The syscall stub pattern

When implant developers want to perform a direct syscall, many times a search is implemented looking for the following sequence of bytes:

// the start of the syscall stub
4c 8b d1 XX XX 00 00 

// the end of the stub
0f 05 c3 cd 2e c3

Note

On older Windows builds the byte pattern above can match a full stub. On recent builds, the stub includes extra instructions (the test/jne we cover in the next chapter), so pattern length and offsets may differ.

At the root of it, that is not really a complete stub, but on some older versions of Windows and ntdll.dll, it is. On more recent versions of Windows, there are some missing instructions from what is shown above. Those missing instructions are the following:

test    byte ptr [7FFE0308h], 1
jne     ntdll!<Some Nt Function>+0x15

Let’s dive into those instructions in the next chapter.