【问题标题】:How can I determine at runtime whether ASM code is running in x86 or x64 CPU? [duplicate]如何在运行时确定 ASM 代码是在 x86 还是 x64 CPU 中运行? [复制]
【发布时间】: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 的答案相同的想法。

标签: linux assembly elf


【解决方案1】:

它可以简单得多,在 32 位代码中使用 REX.W 是一个 DEC:

48 90

在 64 位代码中是:

rex.w nop   ; still a nop

在 32 位代码中:

dec eax
nop

当然,在它前面加上xor eax, eax 之类的东西。

【讨论】:

  • 哇,太棒了!所以像: 31 c0 48 90 85 c0 74 XY ... 如果 x64 会跳到下面的 0xXY 字节。很棒的提示,谢谢!
  • 甚至更短:xor / rex jz。查看我的链接副本。
  • 我当然没想到会这么短 :) 有趣的是,我最初的尝试似乎也能奏效。
猜你喜欢
  • 2017-09-02
  • 1970-01-01
  • 2023-03-03
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 2014-03-07
  • 2022-12-06
相关资源
最近更新 更多