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 two common methods to bypass API hooking:
1) Restore original system libraries in memory; 2) Bypass Windows APIs and call syscalls directly.
To restore ntdll.dll
in memory, common approaches include:
- Read
ntdll.dll
from the filesystem and overwritentdll.dll
in memory - Map the
\\KnownDlls\\ntdll.dll
section into memory
However, restoring system libraries has downsides: you still call Windows APIs (monitored by EDR), and EDR can re-apply hooks.
The second method is to call syscalls directly, avoiding Windows APIs. Windows changes SSN (System Service Number) mapping between versions, so you must resolve SSNs at runtime or maintain mappings. Common approaches:
- Use SSN mappings maintained by SysWhispers
- Parse
Nt*
/Zw*
fromntdll.dll
in memory and sort by address (preferred). This derives mappings dynamically. SysWhispers3 implements this approach.
EDR can detect syscalls by scanning for known patterns, since normal programs rarely invoke them directly. To evade, malware can generate syscall stubs at runtime (SysWhispers3 egghunter
).
Additionally, EDR can inspect call stacks. Direct kernel entry without ntdll.dll
frames is suspicious. A bypass is to use a syscall gadget, then pivot into ntdll.dll
after setting SSN in RAX
(SysWhispers3 jumper
).
Tools
- https://github.com/jthuraisamy/SysWhispers
- https://github.com/jthuraisamy/SysWhispers2
- https://github.com/klezVirus/SysWhispers3
- https://github.com/crummie5/FreshyCalls
Resources
- https://klezvirus.github.io/RedTeaming/AV_Evasion/NoSysWhisper/
- https://www.mdsec.co.uk/2020/12/bypassing-user-mode-hooks-and-direct-invocation-of-system-calls-for-red-teams/
- https://www.crow.rip/crows-nest/mal/dev/inject/syscalls/indirect-syscalls
- https://dosxuz.gitlab.io/post/perunsfart/
- https://blog.sektor7.net/#!res/2021/perunsfart.md