Search code examples
cassemblyx86-64reverse-engineering

Assembly instruction reading, leaq


So I'm trying to compute the values of M and N in the following code with the assembly code given.

int array1[M][N];
int array2[N][M];

void copyelement(int i, int j) {
    array1[i][j] = array2[j][i];
}

Assembly:


copyelement:
    movslq      %esi, %rsi
    movslq      %edi, %rdi
    leaq        (%rdi,%rdi,8), %rax
    addq        %rsi, %rax
    leaq        (%rsi,%rsi,2), %rdx
    leaq        (%rsi,%rdx,4), %rdx
    addq        %rdx, %rdi
    leaq        array2(%rip), %rdx
    movl        (%rdx,%rdi,4), %ecx
    leaq        array1(%rip), %rdx
    movl        %ecx, (%rdx,%rax,4)
    ret

While reading through the assembly code, I got through till array2(%rip) and then I didn't know how to move forward.

At this point, according to my calculations I should have
%rdx = %rdi + (%rsi + %rax) + 4*((%rsi+%rax) + 2*(%rsi + %rax)).

Also I'm not quite sure how I would be able to get the array size from this.


Solution

  • I got through till array2(%rip) and then I didn't know how to move forward.

    Using that instruction, the address of array2 (or array2[0][0]) is written to the rdx register. Forget about the rip register here.

    The combination of that instruction plus the following one (movl) will read the array element ((int *)array2)[rdi]. The two instructions following will write the array element ((int *)array1)[rax].

    This means that rdi contains the value M*j+i and rax contains the value N*i+j.

    If the code has been compiled for System-V, rdi initally contained the value of i and rsi initially contained the value of j.

    EDIT

    okay I tried again, but I can't retrieve the exact value of M and N because the registers don't have any values loaded :/ am I missing something?

    First we check with i=0, j=1:

    This means that edi is initially 0 and esi is initially 1.

    If I did not make a mistake, rdi is 13 before the leaq array2 ... instruction.

    This means that M*j+i = M*1+0 = M = 13.

    Then we check with i=1, j=0.

    If I did not make a mistake, rax is 9 before the leaq array2 ... instruction.

    This means that N*i+j = N*1+0 = N = 9.