Now that we have a better understanding of syscalls and know the chain from application ==> Windows Api ==> Native Windows Api. It is time to really implement the bypass by making use of Direct Syscalls.
But first, let's dive a tiny bit deeper into the code we already created in Part 1. We gonna use WinDBG to investigate the code of the native Windows API. We will focus specifically on the NtAllocateVirtualMemory native Windows function And what these instructions look like in assembly!
I am interested if this changes after our use of Syswhispers!
Assembly code can be intimidating at first, but with some guidance, we can break it down step by step to understand what’s happening. First, we want to use Windbg.
WinDbg is a kernel-mode and user-mode debugger that’s included in Debugging Tools for Windows
So we gonna use that tool to debug and view the code steps our native Windows API makes especially focusing on one instruction. The ntAllocateVirtual memory function. This can be performed by executing the following command:
u ntdll!NtAllocateVirtualMemory
. Let's analyze the code line by line.
0:000> u ntdll!NtAllocateVirtualMemory
ntdll!NtAllocateVirtualMemory:
00007ffb`6ff8d140 4c8bd1 mov r10,rcx
00007ffb`6ff8d143 b818000000 mov eax,18h
00007ffb`6ff8d148 f604250803fe7f01 test byte ptr [SharedUserData+0x308 (00000000`7ffe0308)],1
00007ffb`6ff8d150 7503 jne ntdll!NtAllocateVirtualMemory+0x15 (00007ffb`6ff8d155)
00007ffb`6ff8d152 0f05 syscall
00007ffb`6ff8d154 c3 ret
00007ffb`6ff8d155 cd2e int 2Eh
00007ffb`6ff8d157 c3 ret
00007ffb`0972d140 4c8bd1 mov r10,rcx
In the first line, the mov
(move) instruction is used to copy the value of the rcx
register into the r10
register. This is an important step because the r10
Register now stores the address of the first instruction that should be executed when the syscall is finished and go’s back to userland.