[置顶] iphone 软解那点事 (二)

时间:2022-12-19 20:05:32
 

超雪核心代码  

 

  核心代码部分,相对来说比较难懂,需要有一定的 ARM 汇编, C 语言的基础才行,首先我们来看看 ultraSn0w解锁所用的 at 命令的详细内容,我们用一个二进制工具打开 ultraSn0w 的主程序,检索“ at+xapp ” , 可以看到如下内容。虽然 at 命令都需要是可见的字符,但是我们的注入代码并不能这样,所以有一部分还是 hex 码。

[置顶] iphone 软解那点事 (二)

 

  这么看比较难懂,那么我把这部分内容用 C 语言进行描述,大概如下。

 

[cpp] view plaincopy
  1. #pragma pack(push,1)  
  2.   
  3. typedef unsigned long   uint_32;  
  4. typedef unsigned char   byte;  
  5. typedef unsigned short  uint_16;  
  6.   
  7. typedef struct _tagUNLOCK_STRING   
  8. {  
  9.     char    at_cmd[9];  
  10.     uint_32 padding_data[9];  
  11.     uint_32 exploit_data[13];  
  12.     uint_16 payload_code[26];  
  13.     char    end_code;  
  14.     char    inject_code[800];  
  15. }sUNLOCK_STRING;  
  16.   
  17. /* for 05.13.04 */  
  18. sUNLOCK_STRING _unlock_at_cmd = {  
  19.     { 'a','t','+','x','a','p','p','=','"'},   // at+xapp="  
  20.     {  
  21.         0x41414141, 0x41414141, 0x41414141, 0x41414141, // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa  
  22.         0x41414141, 0x41414141, 0x41414141, 0x41414141,  
  23.         0x41414141  
  24.     },  
  25.     {  
  26.         0x2e2e2e2e,     // r4 padding  
  27.         0xffff1e80,     // r5 ? unknow ?  
  28.         0x2e2e2e2e,     // r6 padding  
  29.         0x2e2e2e2e,     // r7 padding  
  30.         0x20283c01,     // pc the exploit address which is running in thumb mode.   
  31.         0x20202020,     // padding data.  
  32.         0x20202020,     // padding data.  
  33.         0x406ca2b8,     // ? unknow   
  34.         0x01110110,     // ? unknow   
  35.         0x20266689,     // r4   
  36.         0x406ca358,     // r5  
  37.         0x401f443e,     // r6 inject_code address(exploit stack address)   
  38.         0xffff1e81      // pc "return pc address , unknow! sram? or interrupt LUT?  
  39.                         // pc will run on the ram which is overwrited by the payload code."  
  40.     },  
  41.     {  
  42.         0x2111, //MOVLS   R1, 0x110  
  43.         0x0109,   
  44.         0x3106, //ADDS    R1, #6  
  45.         0x0902, //LSLS    R1, R1, #8  
  46.         0x1c4a, //ADDS    R2, R1, #1  
  47. //loc_32  
  48.         0x2021, //MOVLS   R0, 0x22 ;'"'  
  49.         0x3001,   
  50.         0x7833, //LDRB    R3, [R6]  
  51.         0x4298, //CMP     R0, R3  
  52.         0x7870, //LDRB    R0, [R6,#1]  
  53.         0xd007, //BEQ     loc_4E;  
  54.         0x3b41, //SUBS    R3, #0x41 ; A  
  55.         0x3841, //SUBS    R0, #0x41 ; A  
  56.         0x011b, //LSLS    R3, R3, #4  
  57.         0x0b18, //ADDS    R3, R3, R0  
  58.         0x700b, //STRB    R3, [R1]  
  59.         0x3101, //ADDS    R1, #1  
  60.         0x3602, //ADDS    R6, #2  
  61.         0xe7f1, //B       loc_32  
  62. //loc_4e          
  63.         0x4790, //BLX     R2  
  64.         0x2001, //MOVLS   R0, 0  
  65.         0x3801,   
  66.         0x1c01, //ADDS    R1, R0, #0  
  67.         0x47a0, //BLX     R4  
  68.         0x46ad, //MOV     SP, R5  
  69.         0xbd7f  //POP     {R0-R6,PC}  
  70.     },  
  71.     '/"',  
  72.     "/x3B/"AALFAIEIAKKBCGKCFCBKAFELJIEHAGEICHKBEPKCFCBKACELJIEHADEIIAEHAALNNINKBDCAKADPED"  
  73.     "EAAADMEDEAMAEGMAEGPOFPCNOJAAAAAAPKPOJPLNOIDALFBBENIFLABBELCIBMGJEGPPCCJIEHAAJLANCLBBNBABJ"  
  74.     "JANELAKGIBKGAAEDDEKGIBKGAIKGIALELBDGAALELFDGAALELJDGAABCDMLGACACDAAJDCIBMGJEGPPCCAHELJIEH"  
  75.     "NPOHAAAABELEBOEAPINOBGCAIAAJDCEAAAPPAAABABAEACAEADAEAEAEEADKEDCAMAEGMAEGMAEGMAEGMAEGMAEGM"  
  76.     "AEGMAEGPOFPCNOJAAAAAAPKPOJPLNOIPALFBFELIACECEABIJLABIIABDENCABMAPBMKIEHAGBMJICAKIEHAACCEE"  
  77.     "CDBAEJMCGAADJDAKCDAFJDAMCDAAJCACJEAEJCAGJDAMEKABJGAACDALEMKAEHACBMAACIAENBAKEJDIBMAKELJIE"  
  78.     "HADOAAJEJDIBMAHELJIEHAJLAPALNCMAFBPEADMDCBECAIEDMEDEAKADPEDEACAMPBHCAJADMEDEAKEOEELCAJEDM"  
  79.     "EDEAGEGFHGHEGFGBGNDBAAAAAAAAEPELCBAAEFFCFCEPFCCACFGEAAAA/""  
  80. };  
  81.   
  82.       
  83. /* BBSendData( (char*)&_unlock_at_cmd ); */  

溢出用的 at 命令大概分为 6 部分:

1 、 at_cmd :

   这部分是 at 命令的起始部分,也就是前面我们说的 at+xapp 命令。

2 、 padding_data :

   这部分数据没有实际的意义,只是为了让执行 at+xapp 命令函数堆栈溢出的填充代码。

3 、 exploit_data :

   这部分是一个关键的部分,其中主要填充了溢出后要给寄存器, r4 , r5, r6,pc 的地址,以及 Inject code 部分的内存地址。其中还有一些未知的部分,这部分在后续的解锁过程中都要攻克。那么这部分怎么溢出的呢 ?

先看一段汇编指令。一般 ARM 的函数调用返回时候的反汇编代码大概如下。

 

[c-sharp] view plaincopy
  1. ROM:2028A234                 PUSH    {R4-R7,LR}  
  2. ROM:2028A236                 LDR     R6, =0x40255230  
  3.     ………………………………………………  
  4. ROM:2028A24A                 CMP     R0, #0  
  5. ROM:2028A24C                 BNE     loc_2028A252  
  6. ROM:2028A24E                 LSLS    R0, R5, #0  
  7. ROM:2028A250                 POP     {R4-R7,PC}  

   关键的是对堆栈操作的代码 PUSH 和 POP ,程序返回的时候会把堆栈的内容,返回到寄存器 R4-R7 , PC

当然这里面存的应该是上一个函数使用的中间值,可是如果我们溢出之后,他就是我们想要的内容喽, PC 将跳转到我们想要的地方。如果是一个 B  [SP] (不符合语法)就是最理想的了,因为这样我们可以马上跳回堆栈执行我们溢出部分的代码了,可是事情不会有那么好地,所以我们要寻觅一个类似这样功能的代码,去哪里找,只能在基带原有的代码里面找,看看我们的程序调到了那里?看上面的溢出结构就知道了是0x20283c01 一个奇数的地址,说明这里应该是 thumb 指令,那这部分是啥呢,我们需要解密基带的代码!基带的代码在那里呢?且听下回分解。

 

4 、 payload_code :

   这部分是一个装载器,他将在溢出之后被 cpu 执行,主要作用是用来对后续的 Inject code 进行解码,并跳转到 Inject Code 处继续执行。我直接贴出了程序的二进制编码和汇编代码的注释,可以参考一下。反汇编我是使用 IDA Pro ,一个神器啊,当年不知道帮助我破解了多少 WindowMobile 的程序,嘿嘿 ~

   大家仔细看这部分二进制码,有没有发现其中没有一个字节是 0 ,为什么要这样呢?因为 at 指令是一个字符串,那么字符串的默认约定就是 0 代表字符串的结束。如果我们在发给基带的命令中夹有了 0 ,那么就会被程序无情了认为字符串结束而达不到溢出的目的了,所以这部分代码要写的非常精巧。要对汇编的二进制编码很熟悉才行。而且这部分也写不了太大,因为我们很难避免一个程序不写出一个 0 出来。可以看出大神门的功底了得。这部分代码是 thumb 代码,因为 ARM 代码都是 4 字节的,遍地都是 0 啊 ~

   大家说了,汇编也很难懂,那好我翻译成 C 语言大概就是类似下面的代码。如果你说 c 语言也很难懂,那对不起了,先学学再过来看。

 

[cpp] view plaincopy
  1. typedef void (*jmp_fun)();  
  2.   
  3. void Decode( byte* des, char *src )  
  4. {  
  5.     byte l, h;  
  6.   
  7.     while( *src != '"' ){  
  8.         h = *(src++) - 'A';  
  9.         l = *src - 'A';  
  10.         *(des++) = (h << 4) + l;  
  11.     }  
  12.   
  13.     *(jmp_fun)des)();  
  14. }  

 

哈哈,一下子变得这么精炼了,高级语言的诞生绝对是程序届的革命啊。内容很容易懂了吧,就是把 Inject代码两个字符串分别减去 A 然后拼成一个字节,最终所有的字符串全部转换为二进制代码了。解码之后,payload 部分完成了使命,跳转到 Inject 部分继续执行。

 

6 、 Inject_code

   一大堆字符串,看起来来好像没啥规律,不过仔细看看有规律哦,没有大于 V 的字符,嘿嘿 ~ 如果上面的说明你看懂了,你也就知道为什么了! 通过 payload 部分解码之后,出场的将是 ultraSn0w 的核心解锁的代码了。就好比一个绝色美女,已经脱光了所有的外衣,接下来的事情就非常让人期待了 ~~~ 那我们来看看金玉其外的里面是什么?  

……

……

……

……

……

一大堆不知所云的汇编代码。

 

[c-sharp] view plaincopy
  1. ; Segment type: Pure code  
  2.         AREA ROM, CODE, READWRITE, ALIGN=0  
  3.         CODE16  
  4.         PUSH    {LR}  
  5.         LDR R0, =0x40492FC0  
  6.         ADR R1, loc_30  
  7.         ADR R2, unk_A0  
  8.         SUBS    R2, R2, R1  
  9.         LDR R3, =0x2040882C  
  10.         BLX R3  
  11.         LDR R0, =0x40492C20  
  12.         ADR R1, loc_B0  
  13.         ADR R2, 0x150  
  14.         SUBS    R2, R2, R1  
  15.         LDR R3, =0x2040882C  
  16.         BLX R3  
  17.         LDR R0, =0x40492C20  
  18.         BLX R0  
  19.         POP {PC}  
  20. ; ---------------------------------------------------------------------------  
  21. dword_20    DCD 0x2040882C      ; DATA XREF: ROM:0000000A_r  
  22.                     ; ROM:00000016_r  
  23. dword_24    DCD 0x40492FC0      ; DATA XREF: ROM:00000002_r  
  24. dword_28    DCD 0x40492C20      ; DATA XREF: ROM:0000000E_r  
  25.                     ; ROM:0000001A_r  
  26.         DCB 0xC0 ; À  
  27.         DCB 0x46 ; F  
  28.         DCB 0xC0 ; À  
  29.         DCB 0x46 ; F  
  30. ; ---------------------------------------------------------------------------  
  31.         CODE32  
  32.   
  33. loc_30                  ; DATA XREF: ROM:00000004_o  
  34.         STMFD   SP!, {R1-R12,LR}  
  35.         BLX sub_3C  
  36. ; ---------------------------------------------------------------------------  
  37.         LDMFD   SP!, {R1-R12,PC}  
  38.         CODE16  
  39.   
  40. ; =============== S U B R O U T I N E =======================================  
  41.   
  42. ; Attributes: noreturn  
  43.   
  44. sub_3C                  ; CODE XREF: ROM:00000034_p  
  45.   
  46. var_20      = -0x20  
  47. var_1C      = -0x1C  
  48.   
  49.         PUSH    {R4,R5,LR}  
  50.         LDR R5, =0x401E829C  
  51.         SUB SP, SP, #0x14  
  52.   
  53. loc_42                  ; CODE XREF: sub_3C+44_j  
  54.         LDR R3, =0x2042FFD8 ; NU_Receive_From_Mailbox  
  55.         ADDS    R0, R5, #0  
  56.         MOV R1, SP      ; message void*  
  57.         MOVS    R2, #0xFF   ; timeout  
  58.         BLX R3      ; NU_Receive_From_Mailbox  
  59.         LDR R3, [SP,#0x20+var_20] ; [SP]  
  60.         CMP R3, #0xD  
  61.         BNE loc_76  
  62.         LDR R1, [SP,#0x20+var_1C] ; [SP+4]  
  63.         LDR R3, =0x40301650 ; sec_task_var1  
  64.         LDR R2, [R1]  
  65.         STR R2, [R3]  
  66.         ADDS    R3, #4  
  67.         LDR R2, [R1,#4]  
  68.         STR R2, [R3]  
  69.         LDR R2, [R1,#8]  
  70.         LDR R3, =0x100FF00  
  71.         STR R3, [R2]  
  72.         LDR R3, =0x4020401  
  73.         STR R3, [R2,#4]  
  74.         LDR R3, =0x4040403  
  75.         STR R3, [R2,#8]  
  76.         MOVS    R3, #1  
  77.         STR R3, [R1,#0xC]  
  78.         MOVS    R3, #0x20 ; ' '  
  79.         STR R3, [SP,#0x20+var_20]  
  80.   
  81. loc_76                  ; CODE XREF: sub_3C+14_j  
  82.         ADDS    R0, R5, #0  
  83.         MOV R1, SP  
  84.         MOVS    R2, #0xFF  
  85.         LDR R3, =0x20430040  
  86.         BLX R3  
  87.         B   loc_42      ; NU_Receive_From_Mailbox  
  88. ; End of function sub_3C  
  89.   
  90. ; ---------------------------------------------------------------------------  
  91.         DCB    0  
  92.         DCB    0  
  93. dword_84    DCD 0x401E829C      ; DATA XREF: sub_3C+2_r  
  94. dword_88    DCD 0x2042FFD8      ; DATA XREF: sub_3C:loc_42_r  
  95. dword_8C    DCD 0x40301650      ; DATA XREF: sub_3C+18_r  
  96. dword_90    DCD 0x100FF00       ; DATA XREF: sub_3C+26_r  
  97. dword_94    DCD 0x4020401       ; DATA XREF: sub_3C+2A_r  
  98. dword_98    DCD 0x4040403       ; DATA XREF: sub_3C+2E_r  
  99. dword_9C    DCD 0x20430040      ; DATA XREF: sub_3C+40_r  
  100. unk_A0      DCB 0xC0 ; À        ; DATA XREF: ROM:00000006_o  
  101.         DCB 0x46 ; F  
  102.         DCB 0xC0 ; À  
  103.         DCB 0x46 ; F  
  104.         DCB 0xC0 ; À  
  105.         DCB 0x46 ; F  
  106.         DCB 0xC0 ; À  
  107.         DCB 0x46 ; F  
  108.         DCB 0xC0 ; À  
  109.         DCB 0x46 ; F  
  110.         DCB 0xC0 ; À  
  111.         DCB 0x46 ; F  
  112.         DCB 0xC0 ; À  
  113.         DCB 0x46 ; F  
  114.         DCB 0xC0 ; À  
  115.         DCB 0x46 ; F  
  116. ; ---------------------------------------------------------------------------  
  117.         CODE32  
  118.   
  119. loc_B0                  ; DATA XREF: ROM:00000010_o  
  120.         STMFD   SP!, {R1-R12,LR}  
  121.         BLX loc_BC  
  122.         LDMFD   SP!, {R1-R12,PC}  
  123. ; ---------------------------------------------------------------------------  
  124.         CODE16  
  125.   
  126. loc_BC                  ; CODE XREF: ROM:000000B4_p  
  127.         PUSH    {R4-R7,LR}  
  128.         LDR R3, =0x401ED3B8  
  129.         MOVLS   R4, 0x800  
  130.         SUB SP, SP, #0x24  
  131.         STRH    R0, [R3]  
  132.         LDR R5, =0x201493F0  
  133.         ADDS    R0, R4, #0  
  134.         ADDS    R7, R1, #0  
  135.         BLX R5  
  136.         ADDS    R6, R0, #0  
  137.         MOVS    R0, #0x98 ; '・  
  138.         BLX R5  
  139.         MOVS    R2, #0  
  140.         MOVS    R3, #0x44 ; 'D'  
  141.         LDR R1, =0x40492CA4  
  142.         STR R2, [R0,#0xC]  
  143.         STR R3, [SP,#0xC]  
  144.         MOVS    R3, #0xA  
  145.         STR R3, [SP,#0x14]  
  146.         MOVS    R3, #0xC  
  147.         STR R2, [SP]  
  148.         STR R4, [SP,#8]  
  149.         STR R2, [SP,#0x10]  
  150.         STR R3, [SP,#0x18]  
  151.         LDR R2, =0x40492FC0  
  152.         STR R6, [SP,#4]  
  153.         MOVS    R3, #0  
  154.         LDR R4, =0x2043E5B4  
  155.         BLX R4  
  156.         ADDS    R2, R0, #0  
  157.         CMP R0, #0  
  158.         BNE loc_108  
  159.         LDR R1, =0x40492CB0  
  160.         ADDS    R0, R7, #0  
  161.         LDR R3, =0x204B11F0  
  162.         BLX R3  
  163.         B   loc_110  
  164. ; ---------------------------------------------------------------------------  
  165.   
  166. loc_108                 ; CODE XREF: ROM:000000FC_j  
  167.         LDR R1, =0x40492CB4  
  168.         ADDS    R0, R7, #0  
  169.         LDR R3, =0x204B11F0  
  170.         BLX R3  
  171.   
  172. loc_110                 ; CODE XREF: ROM:00000106_j  
  173.         ADD SP, SP, #0x24  
  174.         POP {R4-R7,PC}  
  175. ; ---------------------------------------------------------------------------  
  176. dword_114   DCD 0x401ED3B8      ; DATA XREF: ROM:000000BE_r  
  177. dword_118   DCD 0x201493F0      ; DATA XREF: ROM:000000C8_r  
  178. dword_11C   DCD 0x40492CA4      ; DATA XREF: ROM:000000DA_r  
  179. dword_120   DCD 0x40492FC0      ; DATA XREF: ROM:000000EE_r  
  180. dword_124   DCD 0x2043E5B4      ; DATA XREF: ROM:000000F4_r  
  181. dword_128   DCD 0x40492CB0      ; DATA XREF: ROM:000000FE_r  
  182. dword_12C   DCD 0x204B11F0      ; DATA XREF: ROM:00000102_r  
  183.                     ; ROM:0000010C_r  
  184. dword_130   DCD 0x40492CB4      ; DATA XREF: ROM:loc_108_r  
  185. aDevteam1   DCB "devteam1",0  
  186.         DCB    0  
  187.         DCB    0  
  188.         DCB    0  
  189. aOk     DCB "OK!",0  
  190. aErrorD     DCB "ERROR %d",0  
  191.         DCB    0  
  192. ; ROM       ends  

 

 

  哈哈,贴了这么长的代码,有点骗稿费的嫌疑啊,没事接下来马上将其变成美丽的 C 妹妹。不过在这之前先来点前奏,用语言叙述一下原理,据大神的 wiki 上介绍,基带里面运行了一个完整的操作系统名字叫Nucleus ,是由 ATI 公司开发的,实时嵌入式操作系统,据说相当的稳定安全(苹果是不是图这个来的,可惜自己代码漏洞太多。)。我也没有用过,因为这个是一个商业系统,只对授权的公司开放源代码,但是如果你想找源码,还是有滴! ultrasn0w 的解锁代码,实际上创建了一个截获解锁事件监视 task (通过调用Nucleus 的 API )。经过处理之后,替换掉你 SIM 卡的传递过来的数据,将可以通过验证的数据向下传递,让基带认为你这个是一个合法的可以使用的 SIM 卡。从而达到软解的目的。站在了前人的肩膀上来看这个过程很简单吧,可以想象当初一穷二白的时候,大神们突破重围是会有多么艰辛。

  讲道这里可能有人会说,那这部分代码不是每回都一样了?为何每次解锁都要等那么久,其实这部分核心代码是不会有大变化了,但是每次基带升级之后其中的一些地址会发生变化,因为苹果为了修复漏洞重新编译了代码,所有函数的 link 地址都将发生细微的变化,而我们必须找出当初一一对应的关系。才能保证系统调用是好用的。好了,说了这么多现在看翻译后的解锁 C 代码。

 

  

[cpp] view plaincopy
  1. NU_MAILBOX  sec_mailbox;  
  2. UNSIGNED    sec_task_ver1;  
  3. UNSIGNED    sec_task_ver2;  
  4.   
  5.   
  6. void task_jmp ( void )  
  7. {  
  8.     task_creator();  
  9. }  
  10.   
  11. VOID task_creator( void )  
  12. {  
  13.     VOID        *stack_addr;  
  14.     NU_TASK     *task;  
  15.     OPTION      priority;  
  16.     OPTION      preempt;  
  17.     UNSIGNED    time_slice;  
  18.     OPTION      auto_start;  
  19.     UNSIGNED    stack_size;  
  20.     char        task_name[] = "yifengling0";  
  21.       
  22.       
  23.     stack_size  = 0x800;  
  24.     stack_addr  = malloc( stack_size );  
  25.     task        = (NU_TASK*)(malloc( sizeof(NU_TASK) ) );  
  26.     priority    = 0x44;  
  27.     preempt     = NU_PREEMPT;  
  28.     time_slice  = 0;  
  29.     auto_start  = NU_START;  
  30.   
  31.     NU_Create_Task( task, task_name, (PF_task_entry)(unlock_task),  
  32.              1, p, stack_addr, stack_size, priority, time_slice, preempt, auto_start);  
  33.   
  34. }  
  35.   
  36. static  VOID unlock_task (UNSIGNED argc, VOID *argv )  
  37. {  
  38.     S_SEC_MESSAGE   msg;  
  39.   
  40.     while(1){  
  41.         NU_Receive_From_Mailbox( sec_mailbox, &msg, 0xFF );  
  42.   
  43.         if( msg.message0 == 0x0D ){  
  44.             *(sec_task_var1) = msg.message1.field0;  
  45.             *(sec_task_var2) = msg.message1.field1;  
  46.             msg.message1.field2[0] = data1; //0x100FF00  
  47.             msg.message1.field2[1] = data2; //0x4020401  
  48.             msg.message1.field2[2] = data3; //0x4040403  
  49.             msg.message1.field3 = 1;  
  50.             msg.message0 = 0x20;  
  51.         }  
  52.   
  53.         NU_Send_To_Mailbox( sec_mailbox, &msg, 0xFF );  
  54.     }  
  55. }