Search code examples
c++nasmshellcode

Cast shellcode inside function pointer


I am trying to perform a system call on 32-bit, but there is an issue.

I originally had a naked function as my stub and used inline assembly, but when I tried to turn it into shellcode, despite it being a 1-to-1 copy of the naked function (When looking at it in Visual Studio's disassembly), it does not function (Access Violation Executing NULL).

It worked perfectly with the naked function, by the way.

Here is the shellcode I wrote:

0:  b8 26 00 00 00        mov    eax,0x26
5:  64 ff 15 c0 00 00 00  call   DWORD PTR fs:0xc0
c:  c3                           ret

And here is the code: Everything works fine. Memory gets allocated successfully, the problem is whenever I attempt to call NtOpenProcess: it attempts to execute a null pointer, resulting in an access execution violation.

typedef NTSTATUS(NTAPI * f_NtOpenProcess)(PHANDLE, ACCESS_MASK, OBJECT_ATTRIBUTES *, CLIENT_ID *);
 
INT
main(
    VOID
)
{
    HANDLE            hProcess  = NULL;
    OBJECT_ATTRIBUTES oaAttributes;
    memset(&oaAttributes,
           NULL,
           sizeof(oaAttributes));
    oaAttributes.Length         = sizeof(oaAttributes);
 
    CLIENT_ID        ciClient;
    ciClient.UniqueProcess      = GetCurrentProcessId();
    ciClient.UniqueThread       = NULL;
    
    BYTE Stub[] = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0x64, 0xFF, 0x15, 0x0C, 0x00, 0x00, 0x00, 0xC3 };
    *(DWORD*)(Stub + 1) = 0x26;
    PVOID Mem = VirtualAlloc(NULL, sizeof(Stub), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(Mem, &Stub, sizeof(Stub));
    DWORD Old = NULL;
    VirtualProtect(Mem, sizeof(Stub), PAGE_EXECUTE, &Old);
 
    f_NtOpenProcess NtOpenProcess = (f_NtOpenProcess)Mem;
 
    DWORD Status = NtOpenProcess(&hProcess,
                                 PROCESS_ALL_ACCESS,
                                 &oaAttributes,
                                 &ciClient);
 
    printf("Status: 0x%08X\nHandle: 0x%08X\n",
           Status,
           hProcess);
 
    getchar();
 
    return NULL;
}

If anyone is wondering why am I doing this, I am really bored and I like to mess around with code when I am :)


Solution

  • As noted by Micheal Petch, the shellcode was wrong. I only missed one byte (0x0C) that should be 0xC0.

    If anyone will ever attempt something so stupid and useless like I did, double-check your shellcode first!