通过装配查找数组的尺寸

J M*_*Mei 3 c x86 assembly reverse-engineering multidimensional-array

我有一个分配逆向工程的程序,以便在下面的代码中找到R,S和T的值.假设R,S和T是用声明的常量#define.

long int A[R][S][T];
int store_ele(int h, int i, int j, long int *dest)
{
   A[h][i][j] = *dest;
   return sizeof(A);
}
Run Code Online (Sandbox Code Playgroud)

编译该程序时,GCC会生成以下汇编代码(使用-O2):

 store_ele:
    movslq    %esi, %rsi          //%rsi = h
    movslq    %edi, %rdi          //%rdi = i
    movq    (%rcx), %rax          //moves the value from %rcx to %rax
    leaq    (%rdi,%rdi,4), %rdi   //%rdi = 4 * i + i
    leaq    (%rsi,%rsi,4), %rcx   //%rcx = 4 * h + h
    movslq    %edx, %rdx          //%rdx = j
    leaq    (%rcx,%rdi,4), %rcx   //%rcx = 4 * %rdi + %rcx  = 4 * (4 * i + i) + (4 * h + h) 
    addq    %rcx, %rdx            //adds something to j
    movq    %rax, A(,%rdx,8)      //moves some value
    movl    $1120, %eax           //%eax = 1120
    ret                           //returns %eax
Run Code Online (Sandbox Code Playgroud)

我想问一下我对装配的理解是否正确,我们非常感谢任何提示或帮助!

编辑:我不知道它叫什么,但我们的教授.定义movq: source, destination和其他类似的汇编指令,其中第一个参数是源,第二个参数是目标

编辑2:最大的问题是如何根据程序集找到三个常量的值.我认为

movq   %rax, A(,%rdx,8) //moves some value
movl   $1120, %eax      //%eax = 1120
ret                     //returns %eax
Run Code Online (Sandbox Code Playgroud)

它将发挥主要作用,找出它的作用,但我不知道如何处理它.

编辑3:不知道我是否应该给出答案,但如果有人可能有同样的问题,我得到T = 5,S = 4,R = 7,其中R = 1120/T*S*8,我得到了T和S来自我从这个帖子得到的帮助中的匹配系数.

Pet*_*des 6

这是x86-64 AT&T语法(助记符源,目标),x86-64 System V ABI(rdi中的第一个arg,请参阅该调用约定的近似摘要,或找到更好的ABI文档(包括官方标准)的链接在标签的wiki).

您所谓的"功能"是装配说明.每个组装到一个机器指令.


提示:你的评论是关于哪个arg是错误的.检查ABI是否有arg-passing命令.

既然您知道声明是long int A[R][S][T]:

A[h][i][j]等价于*(A[h][i] + j),A[h][i]数组类型(大小[T]).递归地应用这个A[h][i][j]等价于*(base_pointer + S*T*h + T*i + j)(其中base_pointer只是一个long*,出于C指针数学的目的,在这种情况下隐式地按sizeof(long)进行缩放).

您似乎正在研究LEA如何相乘的正确轨道,因此您可以找到T,然后使用它来找到S(通过除以h的因子).

然后找R,看看函数的返回值,即R*S*T * sizeof(long).

sizeof(long)在x86-64系统中,V ABI是8个字节.当然,数组中的偏移量也会缩放8个字节,因此在获取S和T值时不要忘记将其计算出来.