【发布时间】:2016-08-28 21:15:17
【问题描述】:
我想编写一些汇编代码,它可以找出它是在 x86 还是 x64 二进制文件中运行(我想做这种奇怪的事情的原因是我会在任何给定的二进制文件中注入这段代码,并且当代码运行时,它将确定应该执行哪种系统调用并运行该部分代码。没有恶意,只是在传递到实际入口点之前的“hello world”作为练习)。
无论如何,我想到的一个“解决方案”如下:
- 读取堆栈指针指向通用寄存器 X
- 推0
- 读取堆栈指针到 GP 寄存器 Y
- 从 X 中减去 Y(将结果存储在 X 中)
- 弹出到 Y(修复堆栈)
- X 具有寄存器大小,相应地表现
这是我能得到的最接近的:
0: 54 push rsp
1: 54 push rsp
2: 5b pop rbx
3: 58 pop rax
4: 48 29 d8 sub rax,rbx <---
7: 83 f8 08 cmp eax,0x8
a: 74 ?? je 64_bit_code_addr
这会为 x86 生成相同的字节,除了地址 0x4 处的 0x48。如何以独立于架构的方式编写该指令?或者我还有什么其他的解决方案可以达到这个效果?
(请不要提供开箱即用的解决方案,例如“您可以通过检查ELF文件的EI_CLASS偏移量来确定可执行文件的类”等)
【问题讨论】:
-
实现检查堆栈增量的最短方法是
mov eax, esp/push rbp/sub eax, esp/cmp eax, 4/je mode_32bit。如果 RSP 的低 32 位环绕,这仍然有效。您可以从lea eax, [rsp-4]开始保存 CMP,然后在 SUB 之后测试 ZF。作为奖励,现在您的函数已经在堆栈中保存了一个寄存器以释放它以供使用。但另请参阅此副本,它使用与 Harold 的答案相同的想法。