通过装配查找数组的尺寸

时间:2016-09-17 19:06:31

标签: c assembly multidimensional-array x86 reverse-engineering

我有一个分配来对程序集进行反向工程,以便在以下代码中找到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);
}

编译此程序时,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

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

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

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

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

将在发现它的作用方面起主要作用,但我不知道如何处理它。

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

1 个答案:

答案 0 :(得分:6)

那个x86-64 AT& T语法(助记符源,目标),x86-64 System V ABI(rdi中的第一个arg,请参阅此approximate summary of that calling convention,或找到更好ABI的链接标签wiki中的docs(包括官方标准)。

你在呼唤什么"功能"是装配说明。每一个都组装成一台机器指令。

提示:你的意见是关于哪个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)

x86-64系统中的

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