Skip to content

Bypass API Hooking

API hooking modifies the content of Windows APIs in system libraries (e.g., ntdll.dll, kernel32.dll, ...) in memory to place hooks and hijack the control flow. There are basically two methods to bypass API hooking. One method is to restore the original system library in memory, and the other method is to bypass Windows APIs altogether and call syscall directly.

To restore system library, such as ntdll.dll, in memory comes several ways:

  • Read ntdll.dll from filesystem and overwrite ntdll.dll in memory
  • Map \KnownDlls\ntdll.dll section to memory

However, there are some disadvantages to restoring system libraries. First, you still need to call Windows APIs to read the file, which are monitored by EDR. Second, EDR can reapply API hooking.

The second method is to call syscalls directly, avoiding Windows APIs altogether. Unlike Linux, Windows changes the mapping of SSNs (System Service Numbers) frequently. To call syscalls in Windows, you need to know the SSN mapping for different Windows versions. There are various ways to obtain this mapping:

  • SSN mapping maintained by SysWhisper
  • Parsing Nt- / Zw- APIs from ntdll.dll in memory and sorting them by address, which is a preferred method nowadays. This approach allows us to avoid maintaining the SSN mapping ourselves, as we can derive it from ntdll.dll. SysWhispers3 implement this kind of method.

EDR can easily detect syscall behavior by statically scanning for syscall patterns, as normal programs do not use syscalls directly. To avoid detection, malware can generate the syscall assembly at runtime, a technique implemented as egghunter in SysWhispers3.

Additionally, EDR can detect syscall behavior by examining the program's call stack. Typically, a program will enter the kernel directly instead of going through ntdll.dll. To evade this, malware can use a syscall gadget and jump to ntdll.dll after setting the SSN in the rax register. This technique is implemented as jumper in SysWhispers3.

Tools

Resource