soffensive blog

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 11

Exercise 11 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery11 - the last exercise of the ARM chapter:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
01: 010185B0             mystery11
02: 010185B0 2D E9 F8 4F   PUSH.W   {R3R11,LR}
03: 010185B4 0D F2 20 0B   ADDW     R11, SP, #0x20
04: 010185B8 B0 F9 5A 30   LDRSH.W  R3, [R0,#0x5A]
05: 010185BC 07 46         MOV      R7, R0
06: 010185BE 90 46         MOV      R8, R2
07: 010185C0 00 EB 83 03   ADD.W    R3, R0, R3,LSL#2
08: 010185C4 D3 F8 84 A0   LDR.W    R10, [R3,#0x84]
09: 010185C8 7B 8F         LDRH     R3, [R7,#0x3A]
10: 010185CA 89 46         MOV      R9, R1
11: 010185CC CB B9         CBNZ     R3, loc_1018602
12: 010185CE B0 F9 5A 40   LDRSH.W  R4, [R0,#0x5A]
13: 010185D2 17 F1 20 02   ADDS.W   R2, R7, #0x20
14: 010185D6 00 EB 44 03   ADD.W    R3, R0, R4,LSL#1
15: 010185DA B3 F8 5C 50   LDRH.W   R5, [R3,#0x5C]
16: 010185DE 00 EB 84 03   ADD.W    R3, R0, R4,LSL#2
17: 010185E2 D3 F8 84 00   LDR.W    R0, [R3,#0x84]
18: 010185E6 83 89         LDRH     R3, [R0,#0xC]
19: 010185E8 06 6C         LDR      R6, [R0,#0x40]
20: 010185EA 03 EB 45 03   ADD.W    R3, R3, R5,LSL#1
21: 010185EE 9B 19         ADDS     R3, R3, R6
22: 010185F0 1C 78         LDRB     R4, [R3]
23: 010185F2 5B 78         LDRB     R3, [R3,#1]
24: 010185F4 43 EA 04 24   ORR.W    R4, R3, R4,LSL#8
25: 010185F8 43 8A         LDRH     R3, [R0,#0x12]
26: 010185FA 23 40         ANDS     R3, R4
27: 010185FC 99 19         ADDS     R1, R3, R6
28: 010185FE FD F7 8D FF   BL       sub_101651C

29: 01018602      loc_1018602
30: 01018602 BA 8E         LDRH     R2, [R7,#0x34]
31: 01018604 BB 6A         LDR      R3, [R7,#0x28]
32: 01018606 D0 18         ADDS     R0, R2, R3
33: 01018608 9A F8 02 30   LDRB.W   R3, [R10,#2]
34: 0101860C 0B B1         CBZ      R3, loc_1018612
35: 0101860E 00 22         MOVS     R2, #0
36: 01018610 00 E0         B        loc_1018614

37: 01018612      loc_1018612
38: 01018612 3A 6A         LDR      R2, [R7,#0x20]

39: 01018614      loc_1018614
40: 01018614 FB 8E         LDRH     R3, [R7,#0x36]
41: 01018616 B8 F1 00 0F   CMP.W    R8, #0
42: 0101861A 01 D0         BEQ      loc_1018620
43: 0101861C 80 18         ADDS     R0, R0, R2
44: 0101861E 9B 1A         SUBS     R3, R3, R2

45: 01018620      loc_1018620
46: 01018620 C9 F8 00 30   STR.W    R3, [R9]
47: 01018624 BD E8 F8 8F   POP.W    {R3R11,PC}
48: 01018624             ; End of function mystery11

According to the exercise description, the called subroutine sub_101651C in line 28 takes three arguments and does not return anything. Thus, we know the registers R0, R1 and R2 are prepared and passed to the function.

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 10

Exercise 10 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery10:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
01:             mystery10
02: 2D E9 70 48   PUSH.W   {R4R6,R11,LR}
03: 0D F2 0C 0B   ADDW     R11, SP, #0xC
04: 37 F0 CC F9   BL       __security_push_cookie
05: 84 B0         SUB      SP, SP, #0x10
06: 0D 46         MOV      R5, R1
07: 00 24         MOVS     R4, #0
08: 10 2D         CMP      R5, #0x10
09: 16 46         MOV      R6, R2
10: 0C D3         BCC      loc_1010786
11: 1A 4B         LDR      R3, =__imp_GetSystemTime
12: 68 46         MOV      R0, SP
13: 1B 68         LDR      R3, [R3]
14: 98 47         BLX      R3
15: 00 9B         LDR      R3, [SP,#0x1C+var_1C]
16: 10 24         MOVS     R4, #0x10
17: 33 60         STR      R3, [R6]
18: 01 9B         LDR      R3, [SP,#0x1C+var_18]
19: 73 60         STR      R3, [R6,#4]
20: 02 9B         LDR      R3, [SP,#0x1C+var_14]
21: B3 60         STR      R3, [R6,#8]
22: 03 9B         LDR      R3, [SP,#0x1C+var_10]
23: F3 60         STR      R3, [R6,#0xC]

24:      loc_1010786
25: 2B 1B         SUBS     R3, R5, R4
26: 04 2B         CMP      R3, #4
27: 04 D3         BCC      loc_1010796
28: 11 4B         LDR      R3, =__imp_GetCurrentProcessId
29: 1B 68         LDR      R3, [R3]
30: 98 47         BLX      R3
31: 30 51         STR      R0, [R6,R4]
32: 04 34         ADDS     R4, #4

33:      loc_1010796
34: 2B 1B         SUBS     R3, R5, R4
35: 04 2B         CMP      R3, #4
36: 04 D3         BCC      loc_10107A6
37: 0C 4B         LDR      R3, =__imp_GetTickCount
38: 1B 68         LDR      R3, [R3]
39: 98 47         BLX      R3
40: 30 51         STR      R0, [R6,R4]
41: 04 34         ADDS     R4, #4

42:      loc_10107A6
43: 2B 1B         SUBS     R3, R5, R4
44: 08 2B         CMP      R3, #8
45: 09 D3         BCC      loc_10107C0
46: 07 4B         LDR      R3, =__imp_QueryPerformanceCounter
47: 68 46         MOV      R0, SP
48: 1B 68         LDR      R3, [R3]
49: 98 47         BLX      R3
50: 00 9B         LDR      R3, [SP,#0x1C+var_1C]
51: 32 19         ADDS     R2, R6, R4
52: 33 51         STR      R3, [R6,R4]
53: 01 9B         LDR      R3, [SP,#0x1C+var_18]
54: 08 34         ADDS     R4, #8
55: 53 60         STR      R3, [R2,#4]

56:      loc_10107C0
57: 20 46         MOV      R0, R4
58: 04 B0         ADD      SP, SP, #0x10
59: 37 F0 A4 F9   BL              __security_pop_cookie
60: BD E8 70 88   POP.W    {R4R6,R11,PC}
61:             ; End of function mystery10

Although the function looks complicated at first, we notice it does not contain any kind of loops and only executes sequentially with a couple of conditionals.

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 9

Exercise 9 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery9:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
01:             mystery9
02: 2D E9 30 48   PUSH.W   {R4,R5,R11,LR}
03: 0D F2 08 0B   ADDW     R11, SP, #8
04: 09 4D         LDR      R5, =byteArray
05: 06 E0         B        loc_100E312

06:      loc_100E304
07: 0B 78         LDRB     R3, [R1]
08: 5A 5D         LDRB     R2, [R3,R5]
09: 63 5D         LDRB     R3, [R4,R5]
10: 93 42         CMP      R3, R2
11: 04 D1         BNE      loc_100E318
12: 01 30         ADDS     R0, #1
13: 01 31         ADDS     R1, #1

14:      loc_100E312
15: 04 78         LDRB     R4, [R0]
16: 00 2C         CMP      R4, #0
17: F5 D1         BNE      loc_100E304

18:      loc_100E318
19: 0B 78         LDRB     R3, [R1]
20: 5A 5D         LDRB     R2, [R3,R5]
21: 03 78         LDRB     R3, [R0]
22: 5B 5D         LDRB     R3, [R3,R5]
23: 98 1A         SUBS     R0, R3, R2
24: BD E8 30 88   POP.W    {R4,R5,R11,PC}
25:             ; End of function mystery9

First of all, mystery9 has a striking similarity to the previously decompiled function mystery8. Its disassembly uses Thumb mode, as we can see for instance from the 16 bit instruction width.

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 8

Exercise 8 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery8:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
01:             mystery8
02: 2D E9 78 48   PUSH.W   {R3R6,R11,LR}
03: 0D F2 10 0B   ADDW     R11, SP, #0x10
04: 0C 4E         LDR      R6, =byteArray
05: 09 E0         B        loc_100E34C

06:      loc_100E338
07: 05 78         LDRB     R5, [R0]
08: 01 3A         SUBS     R2, #1
09: 4D B1         CBZ      R5, loc_100E352
10: 0B 78         LDRB     R3, [R1]
11: 9C 5D         LDRB     R4, [R3,R6]
12: AB 5D         LDRB     R3, [R5,R6]
13: A3 42         CMP      R3, R4
14: 04 D1         BNE      loc_100E352 
15: 01 30         ADDS     R0, #1
16: 01 31         ADDS     R1, #1

17:      loc_100E34C
18: 00 2A         CMP      R2, #0
19: F3 DC         BGT      loc_100E338
20: 01 3A         SUBS     R2, #1

21:      loc_100E352
22: 00 2A         CMP      R2, #0
23: 01 DA         BGE      loc_100E35A
24: 00 20         MOVS     R0, #0
25: 04 E0         B        locret_100E364

26:      loc_100E35A
27: 0B 78         LDRB     R3, [R1]
28: 9A 5D         LDRB     R2, [R3,R6]
29: 03 78         LDRB     R3, [R0]
30: 9B 5D         LDRB     R3, [R3,R6]
31: 98 1A         SUBS     R0, R3, R2

32:      locret_100E364
33: BD E8 78 88   POP.W    {R3R6,R11,PC}
34:             ; End of function mystery8

The function was compiled in Thumb mode, as we can see from the presence of 16 bit instructions, PUSH and POP instructions and Thumb-specific instructions, e.g. CBZ and instructions with the .W suffix.

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 7

Exercise 7 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery7:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
01:             mystery7
02: 02 46         MOV      R2, R0
03: 08 B9         CBNZ     R0, loc_100E1D8
04: 00 20         MOVS     R0, #0
05: 70 47         BX       LR 

06:      loc_100E1D8
07: 90 F9 00 30   LDRSB.W  R3, [R0]
08: 02 E0         B        loc_100E1E4

09:      loc_100E1DE
10: 01 32         ADDS     R2, #1
11: 92 F9 00 30   LDRSB.W  R3, [R2]

12:      loc_100E1E4
13: 00 2B         CMP      R3, #0
14: FA D1         BNE      loc_100E1DE
15: 10 1A         SUBS     R0, R2, R0
16: 6F F3 9F 70   BFC.W    R0, #0x1E, #2
17: 70 47         BX       LR
18:             ; End of function mystery7

Again, the function provided is executed in Thumb mode, due to several 16 bit instructions and instructions specific to Thumb mode such as CBNZ and the .W suffix such as in line 7, 11 and 16.

Practical Reverse Engineering Exercise Solutions: Page 79 / Exercise 6

Exercise 6 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery6:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
01:             mystery6
02: 2D E9 18 48   PUSH.W   {R3,R4,R11,LR}
03: 0D F2 08 0B   ADDW     R11, SP, #8
04: 04 68         LDR      R4, [R0]
05: 00 22         MOVS     R2, #0
06: 00 2C         CMP      R4, #0
07: 06 DD         BLE      loc_103B3B6

08:      loc_103B3A8
09: 50 F8 04 3F   LDR.W    R3, [R0,#4]!
10: 8B 42         CMP      R3, R1
11: 06 D0         BEQ      loc_103B3BE
12: 01 32         ADDS     R2, #1
13: A2 42         CMP      R2, R4
14: F8 DB         BLT      loc_103B3A8

15:      loc_103B3B6
16: 00 20         MOVS     R0, #0
17: 00 21         MOVS     R1, #0

18:      locret_103B3BA
19: BD E8 18 88   POP.W    {R3,R4,R11,PC}

20:      loc_103B3BE
21: B2 F1 20 03   SUBS.W   R3, R2, #0X20
22: 01 21         MOVS     R1, #1
23: 99 40         LSLS     R1, R3
24: 01 23         MOVS     R3, #1
25: 13 FA 02 F0   LSLS.W   R0, R3, R2
26: F5 E7         B        locret_103B3BA
27:             ; End of function mystery6

Due to the presence of 16 bit instructions, instructions having the .W suffix and function prologue and epilogue with PUSH and POP respectively, we are dealing with code in Thumb state.