
01/17/2004, 12:59 AM
#199
Here is an example of my take I understanding on of the funcs in the firmware (SIMLockCheckNetworkLock).
Hope this will help others to go on ...
Basically what it does is that it get a 6 byte string input and check it against an encrypted string that is decrypted on the fly using the decrypt function.
It uses also a func called BATTMgrResumeCharging ... probably something wrong here with the addressing ...
Well not that much here .. except that I'm wondering if simply modify the code so that SIMLockCheckNetworkLock returns always 1 would not do the trick ;)
Before doing so, I'll dig a bit more into other funcs ... but oh god I don't have time !
3a1078 :b5b0 µ° : PUSH { R4,R5,R7, LR } // Save R4,R5,R7 on stack  save LR as well for function call return
3a107a :45d5 EÕ : CMP SP, H2 // Check on all funcs ... probably some heap overflow check
3a107c :da01 Ú. : BGE 3a1082 //
3a107e :f00af863: BL 3ab148 (Routine (11 calls)) //
3a1082 :1c07 .. : MOV R7, R0 // R7 = R0 (1st parameter, let's call it Parm1), so R7 = Parm1
3a1084 :b083 °ƒ : ADD SP, #000c // Reserve 12 bytes on the stack for function usage
3a1086 :482c H, : LDR R0, #003f8060 // Load a structure pointer into R0, let's call it Ptr1
3a1088 :7cc0 À : LDRB R0, [R0, #13] // R0 = *((char *)Ptr1 + 13) , let's call it Ptr1>Byte1
3a108a :ab02 «. : ADD R3, SP, #0008 // R3 points on the 9th char of the 12 we reserved on stack (let's call this LocByte1), so R3 = &LocByte1
3a108c :7018 p. : STRB R0, [R3, #0] // LocByte1 = R0 = Ptr1>Byte1
3a108e :207f : MOV R0, #7f // R0 = #7f
3a1090 :03c0 .À : LSL R0, R0, #.15 // R0 = R0<<15 = #7f0000, let's cal it PtrByte2 (a special reserver part of the memory ? Why is it computed like this ?)
3a1092 :7800 x. : LDRB R0, [R0, #0] // R0 = PtrByte2[0]
3a1094 :2501 %. : MOV R5, #1 // R5 = 1
3a1096 :2800 (. : CMP R0, #0 // if (R0 == 0)
3a1098 :d004 Ð. : BEQ 3a10a4 // Goto Branch1
3a109a :1c38 .8 : MOV R0, R7 // R0 = Parm1 (R0 is used as 1st parm for function calls)
3a109c :f6b7fba4: BL 2587e8 (Routine (4 calls)) // R0 = Routine1(Parm1)
3a10a0 :2800 (. : CMP R0, #0 // if (R0 == 0)
3a10a2 :d001 Ð. : BEQ 3a10a8 // Goto Branch2
Branch1
3a10a4 :1c28 .( : MOV R0, R5 // R0 = R5 = 1
3a10a6 :e044 àD : B 3a1132 // goto Branch8 (return (1))
Branch2
3a10a8 :2101 !. : MOV R1, #1 // R1 = 1
3a10aa :a802 ¨. : ADD R0, SP, #0008 // R0 = &LocByte1, LocByte1 = Ptr1>Byte1
3a10ac :f000fc37: BL 3a191e (Routine (11 calls)) // DecryptData(&LocByte1, 1) (call using a reference, not a direct value)
3a10b0 :2400 $. : MOV R4, #0 // R4 = 0
3a10b2 :a802 ¨. : ADD R0, SP, #0008 // R0 = &LocByte1 (modified)
3a10b4 :7800 x. : LDRB R0, [R0, #0] // R0 = LocByte1
3a10b6 :2800 (. : CMP R0, #0 // if (LocByte1 <= 0)
3a10b8 :dd3a Ý: : BLE 3a1130 // goto Branch7 (return(0))
Branch6
3a10ba :0060 .` : LSL R0, R4, #.1 // R0 = R4 << 1 = 0 ??? I don't understand ...
3a10bc :1900 .. : ADD R0, R0, R4 // R0 += R4
3a10be :0040 .@ : LSL R0, R0, #.1 // R0 = R0 << 1 = 0 ???
3a10c0 :4b1e K. : LDR R3, #003f8074 // R3 = Ptr2
3a10c2 :18c1 .Á : ADD R1, R0, R3 // R1 = &Ptr2>Data1
3a10c4 :4668 Fh : MOV R0, SP // R0 = stack pointer = LocString2 (points on the 1st char of the 12 we reserved on stack)
3a10c6 :2206 ". : MOV R2, #6 // R2 = 6
3a10c8 :f005fa2c: BL 3a6524 (Routine (13 calls)) // BATTMgrResumeCharging(LocString2 , &Ptr2>Data1, 6)
3a10cc :4668 Fh : MOV R0, SP // R0 = stack pointer = LocString2
3a10ce :2106 !. : MOV R1, #6 // R1 = 6
3a10d0 :f000fc25: BL 3a191e (Routine (11 calls)) // DecryptData(LocString2 , 6)
3a10d4 :a800 ¨. : ADD R0, SP, #0000 // R0 = LocString2
3a10d6 :7800 x. : LDRB R0, [R0, #0] // R0 = LocString2[0] (modified by DecryptData)
3a10d8 :7839 x9 : LDRB R1, [R7, #0] // R1 = Parm1[0]
3a10da :4288 Bˆ : CMP R0, R1 // if (LocString2[0] != Parm1[0])
3a10dc :d121 Ñ! : BNE 3a1122 // goto Branch3
3a10de :a800 ¨. : ADD R0, SP, #0000 // R0 = LocString2
3a10e0 :7840 x@ : LDRB R0, [R0, #1] // R0 = LocString2[1]
3a10e2 :7879 xy : LDRB R1, [R7, #1] // R1 = Parm1[1]
3a10e4 :4288 Bˆ : CMP R0, R1 // if (LocString2[1] != Parm1[1])
3a10e6 :d11c Ñ. : BNE 3a1122 // goto Branch3
3a10e8 :a800 ¨. : ADD R0, SP, #0000 // R0 = LocString2
3a10ea :7880 x€ : LDRB R0, [R0, #2] // R0 = LocString2[2]
3a10ec :78b9 x¹ : LDRB R1, [R7, #2] // R1 = Parm1[2]
3a10ee :4288 Bˆ : CMP R0, R1 // if (LocString2[1] != Parm1[1])
3a10f0 :d117 Ñ. : BNE 3a1122 // goto Branch3
3a10f2 :a800 ¨. : ADD R0, SP, #0000 //
3a10f4 :78c0 xÀ : LDRB R0, [R0, #3] //
3a10f6 :78f9 xù : LDRB R1, [R7, #3] //
3a10f8 :4288 Bˆ : CMP R0, R1 // if (LocString2[3] != Parm1[3])
3a10fa :d112 Ñ. : BNE 3a1122 // goto Branch3
3a10fc :a801 ¨. : ADD R0, SP, #0004 //
3a10fe :7800 x. : LDRB R0, [R0, #0] //
3a1100 :7939 y9 : LDRB R1, [R7, #4] //
3a1102 :4288 Bˆ : CMP R0, R1 // if (LocString2[4] != Parm1[4])
3a1104 :d10d Ñ. : BNE 3a1122 // goto Branch3
3a1106 :a801 ¨. : ADD R0, SP, #0004
3a1108 :78402800: : x@(. // ?????  probably a problem with the disassembler ...
3a110c :d0ca ÐÊ : BEQ 3a10a4
3a110e :a801 ¨. : ADD R0, SP, #0004
3a1110 :7840 x@ : LDRB R0, [R0, #1]
3a1112 :7979 yy : LDRB R1, [R7, #5]
3a1114 :4288 Bˆ : CMP R0, R1 // if (LocString2[5] != Parm1[5])
3a1116 :d101 Ñ. : BNE 3a111c // goto Branch4
3a1118 :2001 . : MOV R0, #1 // R0 = 1
3a111a :e000 à. : B 3a111e // goto Branch5
Branch4
3a111c :2000 . : MOV R0, #0 // R0 = 0
Branch5
3a111e :2800 (. : CMP R0, #0 // if (R0 != 0)
3a1120 :d1c0 ÑÀ : BNE 3a10a4 // goto Branch1 (return(1))
Branch3
3a1122 :1c60 .` : ADD R0, R4, #1 // RO = R4 + 1
3a1124 :06040e24: AND R4, R0, #000000ff // R4 = R0 & #ff
3a1128 :a802 ¨. : ADD R0, SP, #0008 // R0 = &LocByte1
3a112a :7800 x. : LDRB R0, [R0, #0] // R0 = LocByte1
3a112c :4284 B„ : CMP R4, R0 // if(R4 == R0)
3a112e :dbc4 ÛÄ : BLT 3a10ba // goto Branch6
Branch7
3a1130 :2000 . : MOV R0, #0 // return(0)
Branch8
3a1132 :b003 °. : ADD SP, #000c // Liberate the 12 bytes on the stack
3a1134 :bdb0 ½° : POP { R4,R5,R7, PC } // Restore registers and return
^ end routine


