Search code examples
cwinapinasmsystem-callsntdll

NtAllocatevirtualMemory results in 0xc0000005


memory allocation through VirtualAlloc Win32 API works smoothly, however, trying to make a direct system call as provided below results in 0xc0000005 error (STATUS_ACCESS_VIOLATION).

The code is as follows:

evasion.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

extern "C" NTSTATUS myNtAllocateVirtualMemory(
    HANDLE             ProcessHandle,
    PVOID              *BaseAddress,
    ULONG              ZeroBits,
    PULONG             RegionSize,
    ULONG              AllocationType,
    ULONG              Protect
);

int main(int argc, char* argv[])
{
        LPVOID rb;
        NTSTATUS res = myNtAllocateVirtualMemory(GetCurrentProcess(), &rb, 0, (PULONG)0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        printf("STATUS: %x\n", res);
        return 0;
}

syscall.asm:

section .text
global myNtAllocateVirtualMemory
myNtAllocateVirtualMemory:
        mov r10, rcx
        mov eax, 18h
        syscall
        ret

Compiled as follows on Linux for Windows 10 x86-64:

nasm -f win64 -o syscall.o syscall.asm
x86_64-w64-mingw32-g++ -m64 -c evasion.c -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -Wall -shared -fpermissive
x86_64-w64-mingw32-gcc evasion.o syscall.o -o evasion.exe

Any suggestions are very welcomed!


Solution

  • As @Luke and @OldBoy have stated in the comments, the RegionSize parameter should be a pointer to the value. As @TedLyngmo has mentioned: the BaseAddress pointer should be initialized to NULL;

    Adjusting both variables accordingly did the trick.

    Here is the working code:

    ...
    
    ULONG regionsize = 0x1000;
    
    int main(int argc, char* argv[])
    {
            LPVOID rb = NULL;
            NTSTATUS res = myNtAllocateVirtualMemory(GetCurrentProcess(), &rb, 0, &regionsize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
            ...
    }
    

    Appreciate your help, guys. Sorry, C is not my primary language.