Arrays 逆向工程与汇编代码解释
我在逆向工程这个汇编代码以推断数组维度的值时遇到了困难 我被给予Arrays 逆向工程与汇编代码解释,arrays,assembly,x86,reverse-engineering,gnu-assembler,Arrays,Assembly,X86,Reverse Engineering,Gnu Assembler,我在逆向工程这个汇编代码以推断数组维度的值时遇到了困难 我被给予 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][
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,%rdx), %eax
leaq (%r9,%r8,2), %rdx
leaq array2(%rip), %rcx
salq $4, %rdx
movzwl 12(%rcx,%rdx), %edx
subl %edx, %eax
ret
这里的问题是,我不确定如何从汇编代码中找到A和B的值
感谢所有帮助:)
谢谢:)索引二维数组必须按
sizeof(struct vec3[a])
缩放第一个索引:array1
是一个数组数组,每个较小的数组都有a
元素。所以你看看asm,看看它乘以了什么
给定,struct vec3数组1[2][A]代码>,
array1[i1][j1].x
与平面1D阵列的地址数学相同:array1[(i1*a)+j1].x
。在C中,我们按元素而不是字节索引,因此asm也必须按sizeof(struct vec3)
进行缩放。这显然是sal$4,%reg
指令所做的,因为在填充对齐后,结构大小为16字节
请注意,前导尺寸[2]
根本不在计算中;这只是告诉你你有多少总空间。是后面的尺寸设置了几何图形;不同行中相同列之间的跨距
如果您还没有看到C如何编译不同的A和B值,请尝试使用一些示例值,看看当您将A或B增加1时会发生什么变化。非常适合玩这样的东西
e、 g.使用质数3和7表示A和B,因此即使不改变数字,也可以看到哪些是它们的倍数
除了GCC太聪明了,它不会这么简单:例如,RCX+RCX*2
=RCX*3,而不是使用imul$3、%RCX、%rdx
。如果对A和B使用大的非简单数字,如12345,您将看到实际的imul
我使用了gcc-fpie
使其使用位置无关代码:一个RIP相对LEA将数组地址获取到寄存器中,而不是像array1(%rcx,%rdx,2)
这样的寻址模式,这些模式要求数组地址(在.data或.bss部分)与机器代码中的32位符号扩展disp32相匹配
我还使用了\uuuu属性(ms_abi))
来像代码一样使用Windows x64调用约定,因为Godbolt编译器资源管理器上的GCC是针对Linux的。(MSVC是Godbolt上唯一默认以Windows为目标的编译器,但它不会以AT&t语法输出。)好的!这行代码“leaq array1(%rip),%rax”的作用是什么?在asm代码中,这部分“array1[i1][j1].x”对应于“@MeganDarcy”:它将array1
的地址放入RAX中。类似于mov$array1,%eax
,除了它在独立于位置的代码中工作(这是现代发行版上的gcc默认值-这就是为什么我在Godbolt链接中使用-fpie
来匹配您的asm。没有它,您将看到gcc使用类似array1(%rcx,%rdx)的寻址模式
,利用符号地址与其他寄存器一起用作32位符号扩展绝对地址的功能。)好的,谢谢!我说A是3,B是12,对吗?不太确定如何获得B值still@MeganDarcy字体不是12;这看起来与asm不同,需要更多的LEAs乘以3,然后再乘以4才能添加到j1
。顺便说一句,我刚刚更新了我答案中的Godbolt链接以使用\uuuu属性((ms_abi))
-很抱歉,昨天我没有注意到您的代码使用的是Windows调用约定,而不是x86-64 System V;您的第一个参数是RCX,而不是RDI。(我想写一个关于这类问题的一般答案,而不是为你做家庭作业)。无论如何,您可以通过查找到达R8D的vari2
的乘数来找到B值。