【问题标题】:Loading a PE in memory for emulation在内存中加载 PE 以进行仿真
【发布时间】:2026-02-23 18:35:01
【问题描述】:

我目前正在开发一个代码模拟器,更多的是为了好玩,使用 libemu 作为这个模拟器的核心。

我真正想要实现的唯一一件事就是将整个 PE 加载到内存中并让它撕裂。

所以我建立了一个包含以下项目的小 TODO 列表:

  • 读取标头 ◦检查 PE 是否有效(x86 平台)
  • 提取所需数据以设置内存段
  • 将所有导入的函数挂钩到我的自定义 API。
  • 设置EIP正常工作
  • 构建堆栈段(设置 esp 和 ebp)
  • 设置标志

我已经设法在一天内完成了大部分工作。尽管我似乎在正确设置堆栈段方面存在问题。目前我使用以下代码段设置我的寄存器:

/* Set Registers */
entry_point = pe->nt_header->AddressOfEntryPoint;
emu_cpu_eip_set(cpu, entry_point);
emu_cpu_reg32_set(cpu, eax, 0x00
emu_cpu_reg32_set(cpu, ecx, 0x00);   
emu_cpu_reg32_set(cpu, edx, entry_point); 
emu_cpu_reg32_set(cpu, ebx, 0x00);       
emu_cpu_reg32_set(cpu, ebp, (0x0095f000 - 0x1000 / 2));        
emu_cpu_reg32_set(cpu, esp, emu_cpu_reg32_get(cpu, ebp));  
emu_cpu_reg32_set(cpu, esi, 0x00);

emu_cpu_reg32_set(cpu, edi, 0x00);     

emu_cpu_eflags_set(cpu, 0x0000246);

我认为问题出在 ebp 寄存器中。这些值看起来很奇怪,但 PyEmu 似乎也使用它们。我认为问题在于堆栈的使用的原因很好,它是硬编码的,其次是崩溃的代码是 83 65 f8 00,转换为 00692D67,dword ptr [ebp-8], 0 in Assembler。

我认为堆栈是使用 NTLoader 为 PE 文件设置的。但我似乎找不到它或有关此的文档。

非常感谢任何有关如何继续的指示。

  • 罗宾

ps。 我已经在几个板上交叉发布了这个,以增加答案的机会。我已经阅读了很多关于加载 PE 文件的旧 Windows 文档,但它们都只是指向标头中的 SP 段。但由于那不是 ESP,我怀疑它是堆栈的基础 (EBP)。

可以在 OpenRCE 上找到一个交叉帖子:http://www.openrce.org/forums/posts/2171 另一个交叉帖子可以在 SysInternals 找到:http://forum.sysinternals.com/topic28898_post138041.html#138041

【问题讨论】:

  • @Downvoter 关心添加评论,您为什么对此投反对票?这样,OP 可以在必要时实际改进问题。 ;-)
  • @Stolas 你写过关于这项工作的博客吗?或者你有什么好的参考可以分享?我正在寻找一个非常相似的解决方案,在虚拟非windows环境中加载一个win32-dl​​l并调用一些函数
  • @Alex 不抱歉。

标签: x86 kernel emulation portable-executable


【解决方案1】:

问题似乎是堆栈位于不同的内存偏移量中。

【讨论】: