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

热补丁填充是否始终为16的倍数?多余填充字节能否被shellcode安全使用?

提问内容

我使用/hotpatch和/FUNCTIONPADMIN:195编译选项生成了Windows可执行文件,该配置会在main()函数起始位置前添加195字节的填充。

// Windows x86 无 null 字节 WinExec 启动计算器 shellcode
char shellcode[195] = 
"\x89\xe5\x83\xec\x20\x31\xdb\x64\x8b\x5b\x30\x8b\x5b\x0c\x8b\x5b"
"\x1c\x8b\x1b\x8b\x1b\x8b\x43\x08\x89\x45\xfc\x8b\x58\x3c\x01\xc3"
"\x8b\x5b\x78\x01\xc3\x8b\x7b\x20\x01\xc7\x89\x7d\xf8\x8b\x4b\x24"
"\x01\xc1\x89\x4d\xf4\x8b\x53\x1c\x01\xc2\x89\x55\xf0\x8b\x53\x14"
"\x89\x55\xec\xeb\x32\x31\xc0\x8b\x55\xec\x8b\x7d\xf8\x8b\x75\x18"
"\x31\xc9\xfc\x8b\x3c\x87\x03\x7d\xfc\x66\x83\xc1\x08\xf3\xa6\x74"
"\x05\x40\x39\xd0\x72\xe4\x8b\x4d\xf4\x8b\x55\xf0\x66\x8b\x04\x41"
"\x8b\x04\x82\x03\x45\xfc\xc3\xba\x78\x78\x65\x63\xc1\xea\x08\x52"
"\x68\x57\x69\x6e\x45\x89\x65\x18\xe8\xb8\xff\xff\xff\x31\xc9\x51"
"\x68\x2e\x65\x78\x65\x68\x63\x61\x6c\x63\x89\xe3\x41\x51\x53\xff"
"\xd0\x31\xc9\xb9\x01\x65\x73\x73\xc1\xe9\x08\x51\x68\x50\x72\x6f"
"\x63\x68\x45\x78\x69\x74\x89\x65\x18\xe8\x87\xff\xff\xff\x31\xd2"
"\x52\xff\xd0";

int main(int argc, char* argv[])
{
    char (*jmp)() = (char*)&main - sizeof(shellcode);
    jmp();
}

我将上述shellcode写入了main()起始地址前195字节的二进制镜像区域中。反汇编后发现实际存在13字节的额外0xCC填充:

00401000: CC CC CC CC CC CC CC CC CC CC CC CC CC 89 E5 83  IIIIIIIIIIIII%†Ÿ
  00401010: EC 20 31 DB 64 8B 5B 30 8B 5B 0C 8B 5B 1C 8B 1B   1Ud<[0<[.<[.<.
  00401020: 8B 1B 8B 43 08 89 45 FC 8B 58 3C 01 C3 8B 5B 78  <.<C.%E<X<.A<[x
  00401030: 01 C3 8B 7B 20 01 C7 89 7D F8 8B 4B 24 01 C1 89  .A<{ .€%}o<K$.A%
  00401040: 4D F4 8B 53 1C 01 C2 89 55 F0 8B 53 14 89 55 EC  M“<S..A%Ud<S.%U
  00401050: EB 32 31 C0 8B 55 EC 8B 7D F8 8B 75 18 31 C9 FC  ‰21A<U<}o<u.1
  00401060: 8B 3C 87 03 7D FC 66 83 C1 08 F3 A6 74 05 40 39  <<Ø.}fŸA.¢Ýt.@9
  00401070: D0 72 E4 8B 4D F4 8B 55 F0 66 8B 04 41 8B 04 82  Dr„<M“<Udf<.A<.,
  00401080: 03 45 FC C3 BA 78 78 65 63 C1 EA 08 52 68 57 69  .EA§xxecAˆ.RhWi
  00401090: 6E 45 89 65 18 E8 B8 FF FF FF 31 C9 51 68 2E 65  nE%e.Š,˜˜˜1Qh.e
  004010A0: 78 65 68 63 61 6C 63 89 E3 41 51 53 FF D0 31 C9  xehcalc%aAQS˜D1
  004010B0: B9 01 65 73 73 C1 E9 08 51 68 50 72 6F 63 68 45  1.essA‚.QhProchE
  004010C0: 78 69 74 89 65 18 E8 87 FF FF FF 31 D2 52 FF D0  xit%e.ŠØ˜˜˜1OR˜D
_main:
  004010D0: 66 90              xchg        ax,ax     ; 热补丁机制的一部分
  004010D2: 55                 push        ebp
  004010D3: 8B EC              mov         ebp,esp
  004010D5: 51                 push        ecx
  004010D6: B8 D0 10 40 00     mov         eax,offset _main
  004010DB: 2D C3 00 00 00     sub         eax,0C3h
  004010E0: 89 45 FC           mov         dword ptr [ebp-4],eax
  004010E3: FF 55 FC           call        dword ptr [ebp-4]
  004010E6: 33 C0              xor         eax,eax
  004010E8: 8B E5              mov         esp,ebp
  004010EA: 5D                 pop         ebp
  004010EB: C3                 ret

如果热补丁填充始终为16的倍数,那么这些额外的字节是否可以被shellcode安全使用?
运行该可执行文件可正常启动Windows计算器,运行效果见截图:
shellcode_calc_exe


解答

这13字节的额外0xCC填充完全可以被shellcode安全使用,具体说明如下:

  • /FUNCTIONPADMIN选项本身就会把用户指定的填充长度向上对齐到16字节边界,你指定的195字节向上取16的倍数为208字节,差值正好是你观测到的13字节,这部分内存和你原本申请的195字节属于同一块链接器预留的热补丁专属内存区域,属性为可读可执行,不会被程序其他逻辑占用。
  • 你当前的195字节shellcode刚好占用了这块208字节预留区的尾部空间,前面的13字节属于同一块预留内存的未使用部分,只要后续写入的shellcode总长度不超过208字节,使用这部分空间不会出现内存越界问题。
  • 注意:这个对齐逻辑仅在使用相同版本MSVC编译器、保留/hotpatch和/FUNCTIONPADMIN:195配置的前提下稳定,如果更换编译环境或修改编译参数,需要重新测算对齐后的总预留空间大小,避免shellcode越界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:18:03