Shellcode 在映射到进程时导致访问冲突

Shellcode causes an Access Violation upon mapping into process

所以在 64 位进程中创建远程线程后,我正在映射我的 shellcode:

push rax
push r9
push r8
push rdx
push rcx
push r11

push 0x00000000
push 0x00000000
mov  r9,  0
mov  r8,  StartRoutine
mov  rdx, 0
mov  rcx, 0

mov  rax, CreateThread
call rax

add  rsp, 8*2 ;clear shadow space

pop r11
pop rcx
pop rdx
pop r8
pop r9
pop rax

mov r15, PreviousRip
jmp r15 ;return to previous instruction pointer

你在上面看到的名字是占位符,在我映射我的 shellcode 之前被替换

但是,在 shellcode 运行后,我得到一个 Access violation 错误,因为 ret 指令出错 rip

对我来说,这表明堆栈是corrupted/unbalanced,但是我仔细检查了shellcode前后的堆栈地址是相同的,我还检查了我的shellcode前后的所有通用寄存器并成功恢复。

如果您在现有程序中的任意两个任意指令之间异步 运行 this,您需要确保 save/restore ALL 架构不保留调用的状态,就像中断处理程序一样。

您错过了 r10rflagsXMM0..51https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160

为了安全,您还需要确保保留完整的 32 字节的影子 space,这样 DLL 函数就不会踩到您的任何保存的寄存器值。你说你的测试表明现在这不是问题,但未来的某些 Windows 版本可能有 DLL 函数确实利用了影子 space.


脚注 1:还有 x87 st0..7 或 MM0..7。和 AVX YMM0..15,尽管 Windows API 函数不太可能受到 运行 vzeroupper 或任何东西的影响。或触摸 AVX-512 ZMM0..31 或 k0..7。所以你可以不做 xsave / xrstor 而只是保存 XMM0..5.