Microsoft Word - iOSAppReverseEngineering.docx

(Romina) #1

Also, it needs to restore these 3 registers from stack before it ends execution, to make sure foo()


can work correctly. Let’s look at some pseudo code:


// foo()
foo:
// Push A, B, C, D into stack, save their values
push {A, B, C, D}
// Use A ~ D
move A, #1 // A = 1
move B, #2 // B = 2
move C, #3 // C = 3
call bar
move D, global_var0
// global_var1 = A + B + C + D
add A, B // A = A + B, notice A’s value
add A, C // A = A + C, notice A’s value
add A, D // A = A + D, notice A’s value
move global_var1, A
// Pop A, B, C, D out of stack, restore their values
pop {A-D}
return

// bar()
bar:
// Push A、B、C into the stack, store their values
push {A-C}
// Use A ~ C
move A, #2 // Do you know what this instruction do?
move B, #5
move C, A
add C, B // C = 7
// global_var0 = A + B + C (== 2 * C)
add C, C
move global_var0, C // A = 2,B = 5,C = 14

// Do you get the meaning of push and pop now?
pop {A-C}
return

Let’s shortly explain this snippet of pseudo code: firstly, foo() sets registers A, B and C to 1, 2


and 3 respectively, then calls bar(), which changes values of A, B and C as well sets global_var0,


a global variable, to the sum of registers A, B and C. If we directly use the current values of A, B


and C to calculate the value of global_var1 for now, then the result would be wrong. So before


executing bar(),values of A, B and C should be pushed into stack first, and pop them out after


the execution of bar() for restoration, then we can get a correct global_var1. Notice that, for the


same reason, foo() has done the same operations on A, B, C and D, which saves its callers’ days.


-^ Preserved registers


Some registers in ARM processors must preserve their values after a function call, as shown


below:

Free download pdf