-
-
[分享]UVMSE-吊打苹果iOS加密代码,依此类推~
-
发表于:
2021-8-3 12:25
16482
-
[分享]UVMSE-吊打苹果iOS加密代码,依此类推~
苹果从iOS10开始,就对自己的核心逻辑做了很强的加密,典型的就是字符串加密、间接跳转br、间接调用blr,静态分析和动态调试都十分低效。现在,通过UVMSE,我们可以分分钟解密它的加密代码,上结果:
https://gitee.com/geekneo/reverseapplecode/tree/master/bin
这个采样数据库是针对itunesstored kbsyn算法的一个子函数采样数据,该函数在计算kbsyn时会调用,属于加密代码,IDA的初始流程图如下:
F5反编译:
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反编译:
__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用户手册可以在这里下载:
https://gitee.com/yunyoo/vsusermanual
Have fun~
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课