如何解决逆向工程和解释汇编代码
我很难对这个汇编代码进行逆向工程来推断数组维度的值。
我得到了
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),您将看到实际的 imul
。 https://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 举报,一经查实,本站将立刻删除。