【问题标题】:Need help which deciphering 64 bit Intel Assembly instructions to C [closed]需要帮助将 64 位英特尔汇编指令解密为 C [关闭]
【发布时间】:2017-02-23 00:32:11
【问题描述】:

我有一个函数:

long foo(long x, long y, long z);

我从 GCC 获得了这个程序集输出,我正试图弄清楚是什么 发生将其转换为 C 函数。

我是组装新手,完全不知道这里发生了什么。

富:

subq   %rdx %rsi
imulq  %rsi %rdi 
movq   %rsi %rax 
salq   $63  %rax
sarq   $63  %rax
xorq   %rdi %rax 

x,y,z 分别传入寄存器 %rdi, %rsi, & %rdx

【问题讨论】:

  • 你没有说清楚你需要什么帮助。你知道subq 做什么吗?如果是这样,您是否能够将第一条指令翻译成等效的 C?如果有,你得到了什么?如果不是,这样做有什么问题?
  • 提示:移位将 rax 的低位广播到 rax 中的每个位。 This answer 也使用算术移位作为比特广播,但使用它有条件地将其他结果归零,而不是异或。
  • 响应我需要帮助的问题,我不知道从哪里开始。

标签: c assembly x86-64 reverse-engineering


【解决方案1】:

您需要了解 SystemV ABI 兼容系统(例如 POSIX/linux)的 x86_64 调用约定,才能将给定的寄存器映射到函数原型中的参数。尽管这是作为先决条件给出的,但查阅更详细解释这一点的参考资料会很有帮助:http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64


另外,由于代码使用%rdi,我们知道

  1. 这是不是 windows,因为 windows ABI 不使用rdi 作为其任何“传入寄存器”参数
  2. 我们知道我们正在使用“AT&T 语法”[因为 % 前缀] 而不是“英特尔语法”...
  3. ...所以目标寄存器是指令中最右边的

所有指令上的“q”后缀表示“四字”(即 64 位)。在 Windows 下,long 是 32 位 [图 :-)],所以,这绝对是 SysV,因为在 Windows 下,第一条指令将是 32 位指令,使用 32 位寄存器名称 [and 实际的寄存器会有所不同]:

    subl    %edx %esi

大部分 asm 指令应该是直观的。

请注意,由于long,这些操作对有符号整数起作用。

结合所有这些,这是一个示例程序:

// x86_64 calling convention:
//   arg 0: %rdi
//   arg 1: %rsi
//   arg 2: %rdx
//   arg 3: %rdx
//   arg 4: %r8
//   arg 5: %r9

long
foo(long x,long y,long z)
// x -- %rdi
// y -- %rsi
// z -- %rdx
{
    long ret;

    // subq   %rdx %rsi
    y -= z;

    // imulq  %rsi %rdi
    x *= y;

    // movq   %rsi %rax
    ret = x;

    // salq   $63  %rax
    ret <<= 63;

    // sarq   $63  %rax
    ret >>= 63;

    // xorq   %rdi %rax
    ret ^= x;

    return ret;
}

[以movq开头]这两个移位操作是一个小“技巧”​​。

第一个salq 将第 0 位左移到第 63 位,即 符号 位。 sarq 是一个 算术 右移,它在左侧的 sign 位中移动。最终效果是所有位都将设置为符号位。

所以,这相当于:

xor_mask = (x & 1) ? -1 : 0;

【讨论】:

  • 问题的最后一行表明他们被赋予了调用约定 arg->register 映射。此外,您可能想清楚带有 AT&T 语法的 gcc 在 Windows 上确实有效,并且是 % 告诉我们 AT&T 语法,使用 RDI 传递第一个 arg 告诉我们我们正在使用一切-但是-Windows SystemV ABI。
  • 另外,Windows x86-64 ABI 有 32 位 long。但是,是的,您实际上不需要花费太多时间来确定调用约定,因为问题中已经给出了。
  • @PeterCordes 我已经根据你的 cmets 修改了答案
  • 确实,指出深奥的细节是我最喜欢的消遣之一。 :) 红色区域总是出现在关于使用内联 asm 做一些不明智的事情的 SO 问题中。
  • @PeterCordes 确实,指出深奥的细节是我最喜欢的消遣之一。 这不是很加拿大...你是“麻烦制造者”吗? :-)
猜你喜欢
  • 1970-01-01
  • 2015-09-29
  • 2021-04-13
  • 2011-03-25
  • 1970-01-01
  • 2017-03-02
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多