微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

逆向工程和解释汇编代码

如何解决逆向工程和解释汇编代码

我很难对这个汇编代码进行逆向工程来推断数组维度的值。

我得到了

struct vec3 {
  long z;
  int x;
  unsigned short y;

};

struct vec3 array1[2][A];
struct vec3 array2[8][B];
int arrayfunc(int i1,int j1,int i2,int j2){
   return array1[i1][j1].x  + array1[i1][j1].y - array2[i2][j2].y;
}

这是提供的 C 代码,成员数据 x,y,z 的类型未知,但这是我推断出来的。

arrayfunc:
    leaq    array1(%rip),%rax
    movslq  %ecx,%rcx
    movslq  %edx,%r10
    movslq  %r9d,%r9
    leaq    (%rcx,%rcx,2),%rdx
    movslq  %r8d,%r8
    movq    %rax,%rcx
    addq    %r10,%rdx
    salq    $4,%rdx
    movzwl  12(%rax,%rdx),%eax
    addl    8(%rcx,%eax
    leaq    (%r9,%r8,%rdx
    leaq    array2(%rip),%rcx
    salq    $4,%rdx
    movzwl  12(%rcx,%edx
    subl    %edx,%eax
    ret    

这里的问题是我不确定如何从汇编代码中找到 A 和 B 的值。

始终感谢任何和所有帮助:)

谢谢:))

解决方法

索引二维数组必须将第一个索引缩放 sizeof(struct vec3[A])array1 是一个数组数组,每个较小的数组都有 A 元素。所以你看看 asm,看看它乘以什么。

给定,struct vec3 array1[2][A];
array1[i1][j1].x 是与平面一维数组相同的地址数学:array1[ (i1*A) + j1 ].x。在 C 中,我们按元素而不是字节索引,因此 asm 也必须按 sizeof(struct vec3) 进行缩放。这显然是 sal $4,%reg 指令正在执行的操作,因为在填充对齐后结构大小为 16 字节。

请注意,前导维度 [2] 根本不参与计算;这只是告诉你你有多少总空间。设置几何图形的是后来的维度;不同行中同一列之间的步幅。


如果您还没有看到 C 如何针对不同的 A 和 B 值进行编译,请尝试一些示例,看看当您将 A 或 B 增加 1 时会发生什么变化。https://godbolt.org/ 非常适合玩像那样的东西。

例如https://godbolt.org/z/zrecTcqMs 对 A 和 B 使用质数 3 和 7,因此即使不更改数字,您也可以看到哪些是哪些的倍数。

除了 GCC 太聪明了,不能这么简单:它是 multiplying using one or two LEA,例如RCX + RCX*2 = RCX*3,例如不使用 imul $3,%rcx,%rdx。如果您对 A 和 B 使用大的非简单数字(如 12345),您将看到实际的 imulhttps://godbolt.org/z/4G3qc5d5E


我使用 gcc -fpie 使其使用位置无关代码:一个 RIP 相对 LEA 将数组地址放入寄存器,而不是像 array1(%rcx,%rdx,2) 这样需要数组地址的寻址模式(在 . data 或 .bss 部分)以适合机器代码中的 32 位符号扩展 disp32。

我还使用 __attribute__((ms_abi)) 来像您的代码一样使用 Windows x64 调用约定,因为 Godbolt 编译器资源管理器上的 GCC 是针对 Linux 的。 (MSVC 是 Godbolt 上唯一一个默认针对 Windows 的编译器,但它不会以 AT&T 语法输出。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。