Contents

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 3

Contents

Exercise 3 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function mystery3:

1
2
3
4
5
6
7
8
01:             mystery3
02: 83 68         LDR             R3, [R0,#8]
03: 0B 60         STR             R3, [R1]
04: C3 68         LDR             R3, [R0,#0xC]
05: 00 20         MOVS            R0, #0
06: 4B 60         STR             R3, [R1,#4]
07: 70 47         BX              LR
08:             ; End of function mystery3

It is provided in Thumb mode, as we can see from the instruction width, which is consistently 16 bits. Furthermore, the decompilation is greatly facilitated thanks to the lack of any conditional statements. Any kind of NULL-checks, for instance, are omitted.

The function mystery3 takes two arguments in r0 and r1, as these registers are accessed without prior initialization. Both arguments are pointers to some unknown structure, as they are accessed in memory load and store operations with different offsets. The return value is always 0, as 0 is put into register r0 before exiting. Thus far, we arrive at the following function prototype:

1
BOOL mystery3 (struct1* arg1, struct2* arg2);

As far as the data types of the arguments are concerned, we can make the following statements about their composition:

1
2
3
4
5
6
7
struct1:
 field08_i //32 bit value
 field0C_i //32 bit value

struct2:
 field00_i //32 bit value
 field04_i //32 bit value

The function copies values of the first argument’s structure into the second element’s structure:

1
2
3
4
5
BOOL copyFirstToSecond(struct1* arg1, struct2* arg2) {
 arg2->field00  = arg1->field08;
 arg2->field04 = arg1->field0C;
 return 0;
}