在函数指针中转换 shellcode

Cast shellcode inside function pointer

我正在尝试在 32 位上执行系统调用,但出现问题。

我最初有一个裸函数作为我的存根并使用内联汇编,但是当我试图将它变成 shellcode 时,尽管它是裸函数的 1 对 1 副本(在 Visual Studio 的反汇编),它不起作用(访问冲突执行 NULL)。

顺便说一句,它与 naked 函数完美配合。

这是我写的shellcode:

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

这是代码:一切正常。内存分配成功,问题是每当我尝试调用 NtOpenProcess 时:它试图执行空指针,导致访问执行冲突。

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;
}

如果有人想知道我为什么要这样做,我真的很无聊,我喜欢在闲暇时乱搞代码:)

正如 Micheal Petch 所指出的,shellcode 是错误的。 我只漏了一个字节 (0x0C),应该是 0xC0。

如果有人像我一样尝试做如此愚蠢和无用的事情,请先仔细检查您的 shellcode!