3.69 Struct

★★★

You are charged with maintaining a large C program, and you come across the following code:

typedef struct {
    int first;
    a_struct a[CNT];
    int last;
} b_struct;

void test(long i, b_struct *bp) {
    int n = bp->first + bp->last;
    a_struct *ap = &bp->a[i];
    ap->x[ap->idx] = n;
}

The declarations of the compile-time constant CNT and the structure a_struct are in a file for which you do not have the necessary access privilege. Fortunately, you have a copy of the .o version of code, which you are able to disassemble with the OBJDUMP program, yielding the following disassembly:

0000000000000000 <test>:
    0: 8b 8e 20 01 00 00     mov 0x120(%rsi),%ecx
    6: 03 0e                 add (%rsi),%ecx
    8: 48 8d 04 bf             lea (%rdi,%rdi,4),%rax
    c: 48 8d 04 c6             lea (%rsi,%rax,8),%rax
   10: 48 8b 50 08             mov 0x8(%rax),%rdx
   14: 48 63 c9             movslq %ecx,%rcx
   17: 48 89 4c d0 10         mov %rcx,0x10(%rax,%rdx,8)
   1c: c3                     retq

Using your reverse engineering skills, deduce the following:

A. The value of CNT.

The offset of last in b_struct is 288, and in line 10, we retrive *(bp+8+40*i) to %rdx, so a_struct is align 8, and we know:

272<8+LCNT288272\lt 8+L\cdot CNT\le 288

and L=40, so CNT=7.

B. A complete declaration of struture a_struct. Assume that the only fields in this structure are idx and x, and that both of these contain signed values.

Line 7 converts %ecx to %rcx, convert n to long. And save n to 16+%rax+8*%rdx, %rax is bp+40i, and %rdx is bp+40i+8, so idx has type of long, and is the first field of a_struct. The type of x is also long, and has 4 elements.

typedef struct {
    long idx;
    long x[4];
} a_struct;

Last updated