soffensive blog
Another blog about software security issues
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.
Exercise 5 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function called mystery5:
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 01: mystery5 02: 03 46 MOV R3, R0 03: 06 2B CMP R3, #6 04: 0D D0 BEQ loc_1032596 05: 07 2B CMP R3, #7 06: 09 D0 BEQ loc_1032592 07: 08 2B CMP R3, #8 08: 05 D0 BEQ loc_103258E 09: 09 2B CMP R3, #9 10: 01 D0 BEQ loc_103258A 11: 09 48 LDR R0, =aA ; "A" 12: 70 47 BX LR 13: loc_103258A 14: 07 48 LDR R0, =aB ; "B" 15: 70 47 BX LR 16: loc_103258E 17: 05 48 LDR R0, =ac ; "C" 18: 70 47 BX LR 19: loc_1032592 20: 03 48 LDR R0, =aD ; "D" 21: 70 47 BX LR 22: loc_1032596 23: 01 48 LDR R0, =aE ; "E" 24: 70 47 BX LR 25: ; End of function mystery5 All instructions have a width of 16 bits, so we are dealing with code in Thumb state.
Exercise 4 on page 79 of the book Practical Reverse Engineering specifies the following ARM disassembly of a function mystery4:
1 2 3 4 5 6 7 8 01: mystery4 02: 08 B9 CBNZ R0, loc_100C3DA 03: 00 20 MOVS R0, #0 04: 70 47 BX LR 05: loc_100C3DA 06: 50 F8 08 0C LDR.W R0, [R0,#–8] 07: 70 47 BX LR 08: ; End of function mystery4 The disassembly is in Thumb mode, as there are instructions having a width of 16 bits and some instructions specific to this mode (e.
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.
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 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.
This is the first blog post to a series of ARM challenges from the book Practical Reverse Engineering. In addition to the official ARM manual, the following web page turned out to be very helpful when solving the exercises, as it describes the different ARM instructions in great detail.
https://www.heyrick.co.uk/armwiki/Main_Page
Without further ado, let us explore the first function. The extract below shows the ARM disassembly of a function named mystery1, which we are supposed to decompile into C code.
Read the Virtual Memory chapter in Intel Software Developer Manual, Volume 3 and AMD64 Architecture Programmer’s Manual, Volume 2: System Programming. Perform a few virtual address to physical address translations yourself and verify the result with a kernel debugger. Explain how data execution prevention (DEP) works.
For this exercise, we first have to set up a remote kernel debugging session. (see https://codemetrix.net/windows-kernel-debugging-setup/, https://securityblog.gr/3253/debug-user-mode-processes-using-a-kernel-debugger/ and http://securityblog.gr/3023/windows-kernel-debugging/ for excellent explanations)
Our task:
If the current privilege level is encoded in CS, which is modifiable by user-mode code, why can’t user-mode code modify CS to change CPL?
For a change, this is now a more theoretical than hands-on challenge. In order to address the exercise appropriately, we have to make sure we understood it correctly.
CS (code segment) is the CPU segment register that contains the current ring level in bits 0 and 1.
Our task:
Sample L. Explain what function sub_1000CEA0 does and then decompile it back to C.
Here we have the function’s disassembly:
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 push ebp mov ebp, esp push edi mov edi, [ebp+8] xor eax, eax or ecx, 0FFFFFFFFh repne scasb add ecx, 1 neg ecx sub edi, 1 mov al, [ebp+0Ch] std repne scasb add edi, 1 cmp [edi], al jz short loc_1000CEC7 xor eax, eax jmp short loc_1000CEC9 loc_1000CEC7: mov eax, edi loc_1000CEC9: cld pop edi leave retn endp Firstly, the function takes two arguments, at ebp+0x8 (arg1) and ebp+0x0C (arg2) respectively.
Our task as formulated in exercise 8:
Sample H. Decompile sub_11732 and explain the most likely programming construct used in the original code.
The function’s disassembly:
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 sub_1172E: push esi mov esi, [esp+8] dec esi jz short loc_1175F dec esi jz short loc_11755 dec esi jz short loc_1174B sub esi, 9 jnz short loc_1176B mov esi, [eax+8] shr esi, 1 add eax, 0Ch jmp short loc_11767 ; --------------------------------------------------------------------------- loc_1174B: mov esi, [eax+3Ch] shr esi, 1 add eax, 5Eh jmp short loc_11767 ; --------------------------------------------------------------------------- loc_11755: mov esi, [eax+3Ch] shr esi, 1 add eax, 44h jmp short loc_11767 ; --------------------------------------------------------------------------- loc_1175F: mov esi, [eax+3Ch] shr esi, 1 add eax, 40h loc_11767: mov [ecx], esi mov [edx], eax loc_1176B: pop esi retn 4 Obviously, the sought-after programming construct in this case is a switch.