首页
社区
课程
招聘
[分享]Unicorn/Qemu在Windows 64位下可能存在的内存映射问题
发表于: 1小时前 45

[分享]Unicorn/Qemu在Windows 64位下可能存在的内存映射问题

1小时前
45

昨天调试论坛的一个windows 64位混淆样本发生崩溃,利用windbg和agent强大的能力调试排查发现如下内容,仿真程序发生tcg崩溃。


vmpdump!tcg_op_remove_x86_64+0x2280:mov byte ptr [r11],dl   ds:00000161`80000000=??   ; 另一次 r11=0x00000229`80000000


根因是 Unicorn 2.1.4 在 Windows 上分配 JIT code buffer 时只调用 VirtualAlloc(NULL, size, MEM_RESERVE),没有限制基址。x64dbg 进程里,这块 1GiB 的 reserve 被分配到了 4GiB 对齐的高位地址(两次现场分别是 0x229_0000_0000、0x161_0000_0000),导致 TCG 的 32 位相对寻址和指针计算在 +2GiB 处溢出,code_ptr 变成 base + 0x8000_0000,tcg_out8 直接把字节写到未映射区。


QEMU 历史上有一个 SPARC64 的修复:code_gen_buffer 被映射到离 text segment 8GB 远的地方,导致 TCG 生成的 call 指令超出 2GB 范围而崩溃,修复方式是强制把 buffer 映射到 2GB 以下(MAP_FIXED 到 0x60000000)。c02K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2L8X3c8J5L8$3W2V1i4K6u0W2k6$3!0G2k6$3I4W2M7$3!0#2M7X3y4W2i4K6u0W2j5$3!0E0i4K6u0r3N6s2u0#2M7%4c8&6i4K6u0r3k6i4S2@1k6i4u0F1j5h3I4Q4x3V1k6I4k6h3#2#2i4K6u0r3i4K6u0n7i4K6u0r3y4r3y4V1x3K6q4S2k6o6t1$3y4r3t1I4x3e0t1%4y4r3j5I4z5e0W2T1j5X3b7^5k6e0V1$3y4o6M7@1k6o6S2U0k6r3f1$3x3r3x3@1x3W2)9J5y4e0g2q4i4K6t1#2x3U0q4Q4x3V1k6W2P5r3g2U0i4K6u0W2j5H3`.`.


这个 2GiB 是有明确来源的常量:

translate-all.c:750-751
#if defined(__x86_64__)
# define MAX_CODE_GEN_BUFFER_SIZE  (2 * GiB)
而 64 位宿主默认只分配 1GiB(translate-all.c:779)。我们没用 uc_ctl_set_tcg_buffer_size,全仓 grep 无调用,所以 buffer 实际是 1GiB。code_ptr 落在 base + 2GiB,已经越过了整个 1GiB reserve,原因就在于 32 位相对偏移计算发生溢出,直接落到了 2GiB 边界。

translate-all.c:999
 
return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
分配之后没有任何“必须落在 2GiB 以内”的校验;而 x86_64 TCG 的 goto_tb、jmp rel32 天然要求 code buffer 与宿主代码的距离在 ±2GiB 内。

最终修复正常




[招生]科锐逆向工程师培训(2026年11月13日实地,远程教学同时开班, 第57期)

最后于 56分钟前 被zZhouQing编辑 ,原因:
收藏
点赞 ・0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回