Reverse Engineering for Beginners

(avery) #1

CHAPTER 18. ARRAYS CHAPTER 18. ARRAYS


; allocate place in local stack for 4 values of int type
SUB SP, SP, #0x10
MOV R9, 0xFC2 ; a
ADD R9, PC
LDR.W R9, [R9]
STR R0, [SP,#0x10+x]
STR R1, [SP,#0x10+y]
STR R2, [SP,#0x10+z]
STR R3, [SP,#0x10+value]
LDR R0, [SP,#0x10+value]
LDR R1, [SP,#0x10+z]
LDR R2, [SP,#0x10+y]
LDR R3, [SP,#0x10+x]
MOV R12, 2400
MUL.W R3, R3, R12
ADD R3, R9
MOV R9, 120
MUL.W R2, R2, R9
ADD R2, R3
LSLS R1, R1, #2 ; R1=R1<<2
ADD R1, R2
STR R0, [R1] ; R1 - address of array element
; deallocate chunk in local stack, allocated for 4 values of int type
ADD SP, SP, #0x10
BX LR


Non-optimizing LLVM saves all variables in local stack, which is redundant. The address of the array element is calculated
by the formula we already saw.


ARM + Optimizing Xcode 4.6.3 (LLVM) (Thumb mode)


Listing 18.28: Optimizing Xcode 4.6.3 (LLVM) (Thumb mode)

_insert
MOVW R9, #0x10FC
MOV.W R12, #2400
MOVT.W R9, #0
RSB.W R1, R1, R1,LSL#4 ; R1 - y. R1=y<<4 - y = y16 - y = y15
ADD R9, PC ; R9 = pointer to a array
LDR.W R9, [R9]
MLA.W R0, R0, R12, R9 ; R0 - x, R12 - 2400, R9 - pointer to a. R0=x2400 + ptr to a
ADD.W R0, R0, R1,LSL#3 ; R0 = R0+R1<<3 = R0+R1
8 = x2400 + ptr to a + y158 =
; ptr to a + y
304 + x6004
STR.W R3, [R0,R2,LSL#2] ; R2 - z, R3 - value. address=R0+z
4 =
; ptr to a + y304 + x6004 + z*4
BX LR


The tricks for replacing multiplication by shift, addition and subtraction which we already saw are also present here.


Here we also see a new instruction for us:RSB(Reverse Subtract). It works just asSUB, but it swaps its operands with each
other before execution. Why?SUBandRSBare instructions, to the second operand of which shift coefficient may be applied:
(LSL#4). But this coefficient can be applied only to second operand. That’s fine for commutative operations like addition
or multiplication (operands may be swapped there without changing the result). But subtraction is a non-commutative
operation, soRSBexist for these cases.


TheLDR.W R9, [R9]instruction works likeLEA(A.6.2 on page 887) in x86, but it does nothing here, it is redundant.
Apparently, the compiler did not optimize it out.


MIPS


My example is tiny, so the GCC compiler decided to put theaarray into the 64KiB area addressable by the Global Pointer.


Listing 18.29: Optimizing GCC 4.4.5 (IDA)

insert:
; $a0=x
; $a1=y
; $a2=z

Free download pdf