首页
社区
课程
招聘
[分享]UVMSE-吊打苹果iOS加密代码,依此类推~
发表于: 2021-8-3 12:25 16825

[分享]UVMSE-吊打苹果iOS加密代码,依此类推~

2021-8-3 12:25
16825

图片

苹果从iOS10开始,就对自己的核心逻辑做了很强的加密,典型的就是字符串加密、间接跳转br、间接调用blr,静态分析和动态调试都十分低效。现在,通过UVMSE,我们可以分分钟解密它的加密代码,上结果:

1
https://gitee.com/geekneo/reverseapplecode/tree/master/bin

这个采样数据库是针对itunesstored kbsyn算法的一个子函数采样数据,该函数在计算kbsyn时会调用,属于加密代码,IDA的初始流程图如下:

图片

F5反编译:

1
2
3
4
void __fastcall sub_100274B50(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6)
{
  JUMPOUT(__CS__, (char *)&loc_100274B98 + dword_1002CA440[(a5 == 0 || a6 == 0) + 3]);
}

以看到,因为br这个间接调用,IDA是没办法把这个函数完整识别出来的。所以,我们需要使用UVMSE实现一次采样,如下:

图片

然后就可以看到该函数的执行流CFG,还好,并不是很复杂:

图片

再看看简化还原后的采样CFG,进一步减少了基本块:

图片

然后,我们导出重写后的函数扔进IDA里面看看效果,此时IDA已经可以正常分析该函数了:

图片

F5反编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
__int64 __fastcall sub_100274B50(int a1, __int64 a2, int a3, int a4, unsigned __int64 *a5, int *a6)
{
  BOOL v6; // w8
  char *v7; // x10
  int *v8; // x19
  unsigned __int64 *v9; // x23
  int v10; // w22
  __int64 v11; // x20
  int v12; // w24
  int v13; // w28
  int v14; // w10
  char *v15; // x10
  int v16; // w28
  int v17; // w10
  char *v18; // x10
  int v19; // w28
  __int64 v20; // x23
  int v21; // w8
  int v22; // w24
  __int64 v23; // x8
  int v24; // w10
  int v25; // w21
  char *v26; // x8
  char *v27; // x22
  int v28; // w9
  char *v29; // x8
  int v30; // w11
  int v31; // w21
  char *v32; // x8
  char *v33; // x8
  int v34; // w23
  int v35; // w8
  char *v36; // x8
  int v37; // w8
  int v38; // w9
  char *v39; // x9
  int v40; // w27
  BOOL v41; // w9
  int v42; // w10
  int v43; // w23
  char *v44; // x8
  int v45; // w21
  unsigned __int64 v46; // x0
  int v47; // w10
  int v48; // w23
  char *v49; // x8
  int v50; // w9
  int v51; // w14
  unsigned int v52; // w15
  int v53; // w13
  int v54; // w9
  int v55; // w12
  int v56; // w10
  char *v57; // x10
  unsigned __int64 v58; // x10
  unsigned int v59; // w13
  int v60; // w16
  char *v61; // x1
  __int64 v62; // x14
  BOOL v63; // w15
  int v64; // w12
  int v65; // t1
  unsigned int v66; // w15
  signed int v67; // w16
  int8x16_t v68; // q0
  int v69; // w1
  unsigned __int64 v70; // x3
  unsigned __int64 v71; // x2
  int8x16_t v72; // q2
  char *v73; // x1
  int v74; // w9
  bool v75; // zf
  BOOL v76; // w13
  signed int v77; // w14
  int v78; // w13
  int v79; // w14
  int v80; // w12
  __int64 v81; // x13
  int v82; // w13
  __int64 v83; // x14
  char *v84; // x13
  int v85; // w21
  __int64 v86; // x1
  unsigned __int64 *v88; // [xsp+0h] [xbp-C0h]
  int v89; // [xsp+10h] [xbp-B0h]
  __int64 v90; // [xsp+10h] [xbp-B0h]
  int *v91; // [xsp+18h] [xbp-A8h]
  int v92; // [xsp+24h] [xbp-9Ch]
  __int64 *v93; // [xsp+28h] [xbp-98h]
  int v94; // [xsp+34h] [xbp-8Ch]
  unsigned __int64 v95; // [xsp+38h] [xbp-88h]
  unsigned __int64 *v96; // [xsp+40h] [xbp-80h]
  __int64 *v97; // [xsp+48h] [xbp-78h]
  int *v98; // [xsp+50h] [xbp-70h]
  int v99; // [xsp+58h] [xbp-68h]
  int v100; // [xsp+5Ch] [xbp-64h]
 
  v89 = a4;
  v6 = a5 == 0LL || a6 == 0LL;
  v7 = (char *)&loc_100274B98 + dword_1002CA440[v6 + 3];
  v8 = a6;
  v9 = a5;
  v10 = a3;
  v11 = a2;
  v12 = a1;
  v13 = 250416724 * v6 + 4 * !v6 + 3;
  *a5 = 0LL;
  *a6 = 0;
  HIDWORD(v96) = v13 + 318538391 * ((unsigned __int64)&v96 ^ 0xA472A4EA) + 1085017171;
  sub_100275504(&v96);
  if ( (_DWORD)v96 == 818020368 )
    v14 = v13 + 1;
  else
    v14 = v13;
  v15 = (char *)&loc_100274BC4 + dword_1002CA440[v14];
  v16 = v13 + 250416720 * ((_DWORD)v96 != 818020368) - 7 * ((_DWORD)v96 == 818020368);
  HIDWORD(v96) = v16 + 344300003 * ((unsigned __int64)&v96 ^ 0x1BB52AD3);
  v97 = (__int64 *)&v91;
  sub_10028C214(&v96);
  if ( (_DWORD)v96 == 818020368 )
    v17 = v16 + 1;
  else
    v17 = v16;
  v18 = (char *)&loc_100274C60 + dword_1002CA440[v17];
  v88 = v9;
  v19 = v16 + 250416727 * ((_DWORD)v96 != 818020368) + (((_DWORD)v96 == 818020368) | 8 * ((_DWORD)v96 == 818020368));
  v20 = (__int64)v91;
  v21 = 1089068225 * v12 + 1917068697;
  v22 = 629865641 * ((unsigned __int64)&v96 ^ 0xB415044F);
  HIDWORD(v96) = v22 ^ v21;
  LODWORD(v97) = (v19 - 6) ^ v22;
  v98 = v91;
  v23 = (__int64)*(&off_10036E8E0 + v19 + 208);
  sub_10026BF54(&v96);
  HIDWORD(v96) = v22 ^ (1089068225 * HIDWORD(v11) + 1917068697);
  LODWORD(v97) = (v19 - 6) ^ v22;
  v98 = (int *)v20;
  sub_10026BF54(&v96);
  HIDWORD(v96) = v22 ^ (1089068225 * v11 + 1917068697);
  LODWORD(v97) = (v19 - 6) ^ v22;
  v98 = (int *)v20;
  sub_10026BF54(&v96);
  v98 = (int *)v20;
  HIDWORD(v96) = v22 ^ (1089068225 * v10 + 1917068697);
  LODWORD(v97) = (v19 - 6) ^ v22;
  sub_10026BF54(&v96);
  v98 = (int *)v20;
  HIDWORD(v96) = v22 ^ (1089068225 * v89 + 1917068697);
  LODWORD(v97) = (v19 - 6) ^ v22;
  sub_10026BF54(&v96);
  if ( (_DWORD)v96 == 818020368 )
    v24 = v19 + 1;
  else
    v24 = v19;
  v25 = -7 * ((_DWORD)v96 != 818020368) + v19 - 4 * ((_DWORD)v96 == 818020368);
  v26 = (char *)&loc_100274CD0 + dword_1002CA440[v24];
  v27 = (char *)*(&off_10036E8E0 + v19 + 155) - 6;
  v28 = 1870922891 * ((unsigned __int64)&v96 ^ 0x40116C51);
  HIDWORD(v96) = v28 ^ 0xE15FB441;
  v99 = v28 + 1526806456;
  v100 = (v25 - 4) ^ v28;
  v97 = (__int64 *)&v93;
  v98 = (int *)v20;
  v29 = (char *)*(&off_10036E8E0 + v25 + 199) - 14;
  sub_10027A810(&v96);
  if ( (_DWORD)v96 == 818020368 )
    v30 = v25 + 1;
  else
    v30 = v25;
  v31 = -3 * ((_DWORD)v96 != 818020368) + v25 + 6 * ((_DWORD)v96 == 818020368);
  v32 = (char *)&loc_100274E1C + dword_1002CA440[v30];
  v90 = v20;
  v98 = &v92;
  *(_QWORD *)&v99 = v93;
  LODWORD(v97) = v31 + 357855347 * ((unsigned __int64)&v96 ^ 0x17939E0) + 1288018446;
  v96 = &v95;
  sub_10028D8CC(&v96);
  HIDWORD(v98) = (v31 - 5) ^ 629865641 * ((unsigned __int64)&v96 ^ 0xB415044F);
  v96 = (unsigned __int64 *)&v94;
  v97 = v93;
  v33 = (char *)*(&off_10036E8E0 + v31 + 66) - 11;
  sub_100299998(&v96);
  LODWORD(v96) = v31 - 1785876119 * ((unsigned __int64)&v96 ^ 0x378C1BBF) - 6;
  v97 = v93;
  sub_10029F838(&v96);
  v34 = v31 + 4 * ((_DWORD)v98 != 818020368) + 2 * ((_DWORD)v98 == 818020368);
  if ( (_DWORD)v98 == 818020368 )
    v35 = v31 + 1;
  else
    v35 = v31;
  v36 = (char *)&loc_100274EBC + dword_1002CA440[v35];
  v37 = v34 + 2 * (v94 != 0) + ((v94 == 0) | 2 * (v94 == 0));
  if ( v94 )
    v38 = v31 + 4 * ((_DWORD)v98 != 818020368) + 2 * ((_DWORD)v98 == 818020368);
  else
    v38 = v34 + 1;
  v39 = (char *)&loc_100274FBC + dword_1002CA440[v38];
  v40 = v92;
  v41 = v92 == 862660833;
  v42 = v37 + 4 * (v92 != 862660833);
  if ( v92 == 862660833 )
    ++v37;
  v43 = v42 - v41;
  v44 = (char *)&loc_10027501C + dword_1002CA440[v37];
  v45 = v92 - 862660833;
  v46 = ((__int64 (__fastcall *)(_QWORD))((char *)*(&off_10036E8E0 + v42 - v41 + 204) - 2))((unsigned int)(v92 - 862660833));
  if ( v46 )
    v47 = v43;
  else
    v47 = v43 + 1;
  v48 = v43 - 2 * (v46 != 0) - ((v46 == 0) | 4 * (v46 == 0));
  v49 = (char *)&loc_10027505C + dword_1002CA440[v47];
  v50 = v40 - ((2 * v40 + 422161982) & 0x47D9921C) + 1887543341;
  v51 = v50 ^ 0x4D326F6D;
  v52 = 2 * v50 & 0xDDBD4CC6 ^ 0x45990004;
  v53 = v52 + (v50 ^ 0x4D326F6D);
  v54 = v53 + 402651648;
  v55 = (((v53 != -287398301) | (unsigned __int16)(4 * (v53 != -287398301))) & 0xFFEF | 16 * (v53 == -287398301)) + v48;
  if ( v53 == -287398301 )
    v56 = v48 + 1;
  else
    v56 = v48;
  v57 = (char *)&loc_1002750B4 + dword_1002CA440[v56];
  v58 = v95;
  v59 = v53 + 287398301;
  v60 = ((v59 > 0x1F) | 4 * (v59 > 0x1F)) + 250416704 * (v59 < 0x20) + v55;
  if ( v59 < 0x20 )
    ++v55;
  v61 = (char *)&loc_100275154 + dword_1002CA440[v55];
  v62 = v52 + v51 + 287398300;
  v63 = v95 < v46 + v62 + 1 && v46 < v95 + v62 + 1;
  v64 = v60 + 250416699 * (v63 + !v63);
  v65 = dword_1002CA440[v60 + v63];
  v66 = v59 & 0xFFFFFFE0;
  v67 = (v59 & 0xFFFFFFE0) - 32;
  v68.n128_u64[0] = 8246779703540740722LL;
  v68.n128_u64[1] = 8246779703540740722LL;
  while ( 1 )
  {
    v69 = v64 - 250416701;
    if ( !v67 )
      v69 = v64 - 250416700;
    v70 = v58 + (unsigned int)v62;
    v71 = v46 + (unsigned int)v62;
    v72 = veorq_s8(*(int8x16_t *)(v70 - 31), v68);
    *(int8x16_t *)(v71 - 15) = veorq_s8(*(int8x16_t *)(v70 - 15), v68);
    *(int8x16_t *)(v71 - 31) = v72;
    v64 -= 250416701 * (v67 == 0);
    v73 = (char *)&loc_100275210 + dword_1002CA440[v69 + 4];
    if ( v67 >= 0 )
      break;
    LODWORD(v62) = v62 - 32;
    v67 -= 32;
  }
  v74 = v54 - v66;
  v75 = v59 == v66;
  v76 = v59 == v66;
  v77 = !v75;
  v78 = 250416701 * v77 + 8 * v76;
  if ( v75 )
    v79 = v64 + 1;
  else
    v79 = v64;
  v80 = v78 + v64;
  v81 = dword_1002CA440[v79];
  do
  {
    v82 = v80 - 250416701;
    v83 = (unsigned int)(v74-- - 115253348);
    if ( v74 == 115253347 )
      v82 = v80 - 250416700;
    *(_BYTE *)(v46 + v83) = *(_BYTE *)(v58 + v83) ^ 0x72;
    v80 -= 250416693 * (v74 == 115253347);
    v84 = (char *)&loc_100275298 + dword_1002CA440[v82 + 6];
  }
  while ( v74 < 115253347 );
  *v88 = v46;
  *v8 = v45;
  v85 = v80 - 32;
  v97 = v93;
  LODWORD(v96) = v80 - 32 - 1277345827 * ((unsigned __int64)&v96 ^ 0xE4E0F794);
  sub_1002A79C0(&v96, v73);
  LODWORD(v96) = v85 - 1277345827 * ((unsigned __int64)&v96 ^ 0xE4E0F794);
  v97 = (__int64 *)v90;
  sub_1002A79C0(&v96, v86);
  return 0LL;
}

可以看到,重写后的br、blr均修复为b、bl等正常的函数调用,进一步就可以递归分析整个算法的来龙去脉。

UVMSE用户手册可以在这里下载:

1
https://gitee.com/yunyoo/vsusermanual

Have  fun~



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费
支持
分享
最新回复 (1)
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
nice
2021-8-3 14:49
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册