Saturday, 2 December 2017

Practical Reverse Engineering Exercise Solutions: Page 78 / Exercise 2

Exercise 2 of the ARM chapter has a rather short disassembly compared to the first exercise. Again, we are tasked with the decompilation of the provided function mystery2.

The disassembly is as follows:

01:             mystery2
02: 28 B1         CBZ      R0, loc_C672

03: 90 F8 63 00   LDRB.W   R0, [R0,#0x63]
04: 00 38         SUBS     R0, #0
05: 18 BF         IT NE
06: 01 20         MOVNE    R0, #1
07: 70 47         BX              LR

08:             loc_C672
09: 01 20         MOVS     R0, #1
10: 70 47         BX              LR
11:             ; End of function mystery2

First of all, we notice that the function has been compiled in Thumb mode, as there are several instructions having a width of 16 bits, which is not possible in ARM mode. Furthermore, the instructions CBZ and IT are specific to Thumb mode and not available in ARM mode.

The function takes one argument, which is passed in register r0. In line 3, a single byte is loaded from memory at address (r0+0x63), so we can infer the argument is a structure with a character field at offset 0x63. The preliminary structure definition is given below:

unknownStructure: 
   field63_c;


The function returns either 0 or 1 in the register 0, so we can specify the return type to be of type BOOL. We arrive at the following function prototype:

BOOL checkOffset63IsNotSet(unknownStructure* arg);

In line 2, it is checked whether the passed argument is equal to 0, i.e. NULL. When it equals to NULL, the function returns 1 or TRUE.

In the block beginning with line 3, a single byte is loaded from address (r0+0x63) and stored in r0. Afterwards it is compared against 0 (line 4) and in case of inequality, 1 is stored in r0 (line 6).

To summarize, the function indicates to the caller whether the field at offset 0x63 of the passed structure is not set. 

This very simple function can be written in C as follows:

BOOL mystery2 (unknownStructure* arg) {
if (arg == NULL) {
return TRUE;
}

char unknownByte = arg->field63_c;
if (unknownByte != 0)  {
return TRUE;
}

return FALSE;
}


No comments:

Post a Comment