Thursday, August 28, 2008

First Block - One thing I like about the first block is the instruction ordering. Clearly instructions are ordered for best performance (by a compiler), not easiest reading. Instructions 10, 11, and 12 are a nice example of doing an ADD while the expensive LDR instruction burns through cycles and then storing the instruction on the stack. I should look into the cycle count of LDR.

1) STMDB R4!, {R4, R5, R6, R7, LR} - Instructions 1-3 are a standard function start, save off registers and make room on the stack
2) ADD R7, SP, #0xC
3) SUB SP, SP, #0x10
4) LDR R3, [PC, #0xF0]
5) LDR R2, [PC, #0xF0] - I believe is loading a large number likely a 64 bit number into two registers. The PC is being used to pull a constant that is in the instruction stream and dropping it into R2 and R3. The instruction 5 is getting the constant at the same location as instruction 4 but the PC has incremented by 4 (bytes).
6) STR R3, [SP, #0] - Then line 6 shoves the R3 value onto the stack.
7) LDR R3, [R0, #0x28] - So the value of R0 was passed as a function parameter? That plus 0x28 (Decimal 40) is loaded into R3. Note: R0-R3 are the registers used for parameter passing.
8) MOV R4, R0 - Then R0 is moved to R4. That is a parameter passed to the function and copied to R4. Probably for safe keeping.
9) STR R3, [SP, #4] - So now that new value from 7 is shoved on the stack.
10) LDR R3, [R0, 0x48] - R0 + 0x48 (Decimal 78) address stored into R3
11) ADD R6, R0, #0x28 - Yet again the R0 passed value is being used in conjunction with a constant to put a value in R6.
12) STR R3, [SP, #8] - The value from instruction 10 is stored on the stack.
13) LDR R3, [PC, #0xD4] - Looks like another constant is being grabbed at 0xD4 (Decimal 212) added with the PC and stored in R3
14) MOV R0, #0xD - This is a constant (13 decimal) place in R0 for the upcoming function call.
15) MOV R1, #0 - R1 is being cleared, or at the least a value of 0 for the upcoming function call is being readied.
16) LDR R5, [R3, #0] - This value comes from instruction 13, that constant from instruction 13 is now being used to get another value and store it in R5.
17) LDR R3, [R5, #0] - The value from instruction 16 is now used to fill R3 again.
18) STR R3, [SP, #0xC] - Value from instruction 18 loaded onto stack. Stack is full.
19) MOV R3, R2 - Move R2 value from instruction 5 to R3
20) BL #-0x54ED - Branch and Link (Basically calling a function with the parameters passed in R0-R3. Value is negative because it occurs some where (Decimal 21741 bytes?) earlier. Values available to the called function are from Instructions 14 (R0), 15 (R1), 5 (R2), 17 (R3). R2 and R3 have the same value.
21) LDR R3, [R5, #0] - The value from instruction 16 is used to recreate the value in R3.
22) CMPS R3, #1 - Value of R3 is compared to 1.
23) BEQ #6 - Branch if equal to 1 to 6.

2 Comments:

Blogger yiourkas said...

I think what happens next is the interesting part. It looks like a switch-like statement to me. The fact that all paths end at the same piece of code + the fact all paths do somehow similar tasks in similar order, combined with the glory that this piece of code has gained, makes me think that this is the code that decides if the iPhone will be locked or not.

August 28, 2008 at 2:02 PM  
Blogger yiourkas said...

Here's another interesting thing I noticed:

LDR R3, [PC, #F0] ; Let's call PC+0xF0 our heap
LDR R2, [PC, #F0] ; R2 = heap + 4

ok, so you said that is loading a big number, or two small ones. Either way, I suppose it is a 32-bit arch, right? So some lines down, when it does:

LDR R3, [PC, #0xD4]

The number of instructions between LDR R2, [PC, #F0] and LDR R3, [PC, #0xD4] is 7 = 0x1C bytes

In decimal: heap is 240 bytes after the first call. R3 loads this value. R2 loads the next memory area (244 bytes from the first LDR). And after 32 bytes, R3 is loaded with the memory location with offset 0xD4=212.
212 + 32 + 4 = 248 bytes from the first LDR.
So these three LDR instructions load the memory area @ +240, +244, +248 bytes from the first LDR.

Now the +248 bytes area, looks like a pointer to pointer:
LDR R5, [R3, 0] ; R3 points to R5 and
LDR R3, [R5, 0] ; R5 points to the "thing" that is loaded in R3


Additionally:
The stack space that is allocated at the beginning (SP += 0x10) is filled with:

[R0] (also R4 points to the original address of it)
[R0 + 40bytes] (also R6 points to the original address of it)
[R0 + 72bytes]
[that pointer to pointer thing]


I am a little confused about what's going afterwords.
Do you have any idea what does BEQ #6 do? (shouldn't it be a multiple of 4 ???)

cheers

August 29, 2008 at 10:38 AM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home