分析锁机样本中发现加了壳,硬着头皮撸了一遍,样本所使用加固为腾讯乐固,壳版本为2.10.3.1。
使用乐固加固后会在Lib文件夹下生成如下文件。
加固的核心功能在libshella-2.10.3.1.so中,libBugly.so主要功能为监控程序异常数据,故不关注。
修复so后,直接将so,拖入ida,如下图所示,JNI_OnLoad函数被加密,.init 与.init_array也无法显示。
修复工具地址为:http://bbs.pediy.com/thread-192874.htm
直接动态挂上IDA,在linker的.init_array调用出下好断点。
关于如何定位这里简单说一下,搜索字符串[ Calling %s @ %p for '%s' ],BLX R4就是调用出。
断点触发后运行到init_array位置。
看一下流程图,应该是被llvm混淆过。
来到函数尾部粗略看了看代码,调用了如下图中几个函数,在mprotect_0处断下后,代码解密完毕。
其中createthread创建了一个反调试线程,这里我直接nop了,粗略看了几眼。
反调试线程函数伪代码如下:
int __fastcall sub_6232D0B4(int a1)
{
void *v1; // r1@48
signed int v2; // r2@48
int v4; // r0@54
int v5; // r0@54
int v6; // r1@54
int v7; // r0@54
int v8; // r0@55
void *v9; // r2@55
unsigned __int8 v10; // zf@55
signed int v11; // r0@55
void *v12; // r1@60
signed int v13; // r2@60
void *v14; // r1@65
signed int v15; // r2@65
int v16; // r2@71
int v17; // r0@71
int v18; // r0@73
int v19; // r0@74
void *v20; // r2@74
signed int v21; // r0@74
int v22; // r0@79
int v23; // r0@79
unsigned int v24; // r1@79
int v25; // r0@79
unsigned int v26; // r2@79
int v27; // r0@80
void *v28; // r2@80
unsigned __int8 v29; // nf@80
signed int v30; // r0@80
int v31; // r0@85
int *v32; // r1@86
int *v33; // r3@86
int v34; // r2@86
unsigned int v35; // r0@86
void *v36; // r2@86
signed int v37; // r0@86
int v38; // r0@91
int v39; // r0@91
int v40; // r0@92
int v41; // [sp+0h] [bp-4A0h]@54
int v42; // [sp+4h] [bp-49Ch]@92
int v43; // [sp+8h] [bp-498h]@91
int v44; // [sp+Ch] [bp-494h]@91
int v45; // [sp+10h] [bp-490h]@91
int v46; // [sp+14h] [bp-48Ch]@86
int v47; // [sp+18h] [bp-488h]@85
int v48; // [sp+1Ch] [bp-484h]@85
unsigned int v49; // [sp+20h] [bp-480h]@79
void *v50; // [sp+24h] [bp-47Ch]@79
int v51; // [sp+28h] [bp-478h]@79
int v52; // [sp+2Ch] [bp-474h]@79
int v53; // [sp+30h] [bp-470h]@79
int v54; // [sp+34h] [bp-46Ch]@79
int v55; // [sp+38h] [bp-468h]@73
int v56; // [sp+3Ch] [bp-464h]@71
int v57; // [sp+40h] [bp-460h]@71
int v58; // [sp+44h] [bp-45Ch]@54
int v59; // [sp+48h] [bp-458h]@54
int v60; // [sp+4Ch] [bp-454h]@54
int v61; // [sp+50h] [bp-450h]@54
void *v62; // [sp+54h] [bp-44Ch]@2
int v63; // [sp+58h] [bp-448h]@1
void *v64; // [sp+5Ch] [bp-444h]@1
char *v65; // [sp+60h] [bp-440h]@1
void *v66; // [sp+64h] [bp-43Ch]@1
void *v67; // [sp+68h] [bp-438h]@1
char v68; // [sp+6Ch] [bp-434h]@1
char v69; // [sp+6Dh] [bp-433h]@1
char v70; // [sp+6Eh] [bp-432h]@1
char v71; // [sp+6Fh] [bp-431h]@1
char v72; // [sp+70h] [bp-430h]@1
char v73; // [sp+71h] [bp-42Fh]@1
char v74; // [sp+72h] [bp-42Eh]@1
char v75; // [sp+73h] [bp-42Dh]@1
char v76; // [sp+74h] [bp-42Ch]@1
char v77; // [sp+75h] [bp-42Bh]@1
char v78; // [sp+76h] [bp-42Ah]@1
char v79; // [sp+77h] [bp-429h]@1
char v80; // [sp+78h] [bp-428h]@1
char v81; // [sp+79h] [bp-427h]@1
char v82; // [sp+7Ah] [bp-426h]@1
char v83; // [sp+7Bh] [bp-425h]@1
int v84; // [sp+7Ch] [bp-424h]@54
char v85; // [sp+80h] [bp-420h]@71
int v86; // [sp+480h] [bp-20h]@55
int v87; // [sp+484h] [bp-1Ch]@1
int v88; // [sp+488h] [bp-18h]@1
int v89; // [sp+48Ch] [bp-14h]@1
v88 = a1;
++dword_62330398;
v66 = &unk_6232FF38;
v65 = &v68;
v64 = &unk_6232FF38;
unk_623303A8 = malloc_0(1024);
v63 = sub_6232B17C();
unk_623303AC = sub_6232B4E8(0, v88, unk_623303A4);
v82 = unk_623302EF ^ 0xD7;
v74 = unk_623302E7 ^ 0x9D;
v72 = unk_623302E5 ^ 0xC6;
v77 = unk_623302EA ^ 0xC3;
v80 = unk_623302ED ^ 0xBB;
v69 = unk_623302E2 ^ 0x81;
v78 = unk_623302EB ^ 0xD7;
v75 = unk_623302E8 ^ 0x95;
v70 = unk_623302E3 ^ 0xB5;
v81 = unk_623302EE ^ 0xDA;
v68 = unk_623302E1 ^ 0xF5;
v76 = unk_623302E9 ^ 0x9B;
v79 = unk_623302EC ^ 0xF2;
v73 = unk_623302E6 ^ 0xEA;
v71 = unk_623302E4 ^ 0xB7;
v83 = unk_623302F0;
v87 = opendir(&v68);
v89 = v87;
v67 = (void *)-1296986714;
do
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
v62 = v67;
if ( (signed int)v67 > -1437465226 )
break;
if ( v62 == (void *)-1866223142 )
v67 = (void *)812103489;
}
if ( (signed int)v62 > -1296986715 )
break;
if ( v62 == (void *)-1437465225 )
{
*((_BYTE *)&v41 - 7) = byte_62330331;
*((_BYTE *)&v41 - 18) = byte_62330326 ^ 0x8E;
*((_BYTE *)&v41 - 9) = byte_6233032F ^ 0xB4;
*((_BYTE *)&v41 - 19) = byte_62330325 ^ 0xD3;
*((_BYTE *)&v41 - 13) = byte_6233032B ^ 0xBB;
*((_BYTE *)&v41 - 24) = unk_62330320 ^ 0x90;
*((_BYTE *)&v41 - 22) = byte_62330322 ^ 0xE0;
*((_BYTE *)&v41 - 16) = byte_62330328 ^ 0xE9;
*((_BYTE *)&v41 - 11) = byte_6233032D ^ 0xF0;
*((_BYTE *)&v41 - 8) = byte_62330330 ^ 0xB8;
*((_BYTE *)&v41 - 20) = byte_62330324 ^ 0xF7;
*((_BYTE *)&v41 - 12) = byte_6233032C ^ 0xC2;
*((_BYTE *)&v41 - 14) = byte_6233032A ^ 0xED;
*((_BYTE *)&v41 - 17) = byte_62330327 ^ 0x9B;
*((_BYTE *)&v41 - 23) = byte_62330321 ^ 0x84;
*((_BYTE *)&v41 - 15) = byte_62330329 ^ 0xE5;
*((_BYTE *)&v41 - 10) = byte_6233032E ^ 0xDB;
*((_BYTE *)&v41 - 21) = byte_62330323 ^ 0xBC;
v19 = sub_6232B7B8(&v41 - 6);
v20 = (void *)936246879;
v10 = v19 == 0;
v21 = 0;
if ( !v10 )
v21 = 1;
if ( v21 )
v20 = &unk_53451D86;
v67 = v20;
}
}
if ( (signed int)v62 <= 2011994327 )
break;
if ( v62 == (void *)2011994328 )
{
v40 = ((int (__fastcall *)(signed int))unk_623223E4)(1);
v67 = (void *)-1437465225;
v42 = v40;
}
}
if ( (signed int)v62 <= 1892825734 )
break;
if ( v62 == (void *)1892825735 )
{
v16 = v86 + 19;
*((_BYTE *)&v41 - 21) = byte_62330303 ^ 0x83;
*((_BYTE *)&v41 - 17) = byte_62330307 ^ 0x95;
*((_BYTE *)&v41 - 13) = byte_6233030B ^ 0xD5;
*((_BYTE *)&v41 - 20) = byte_62330304 ^ 0xE0;
*((_BYTE *)&v41 - 11) = byte_6233030D ^ 0xB5;
*((_BYTE *)&v41 - 24) = unk_62330300 ^ 0xE4;
*((_BYTE *)&v41 - 3) = byte_62330315 ^ 0xAB;
*((_BYTE *)&v41 - 10) = byte_6233030E ^ 0x93;
*((_BYTE *)&v41 - 9) = byte_6233030F ^ 0xBD;
*((_BYTE *)&v41 - 15) = byte_62330309 ^ 0xE5;
*((_BYTE *)&v41 - 16) = byte_62330308 ^ 0xCB;
*((_BYTE *)&v41 - 22) = byte_62330302 ^ 0xE6;
*((_BYTE *)&v41 - 18) = byte_62330306 ^ 0xC8;
*((_BYTE *)&v41 - 12) = byte_6233030C ^ 0x8F;
*((_BYTE *)&v41 - 23) = byte_62330301 ^ 0x85;
*((_BYTE *)&v41 - 5) = byte_62330313 ^ 0xB1;
*((_BYTE *)&v41 - 6) = byte_62330312 ^ 0xE7;
*((_BYTE *)&v41 - 4) = byte_62330314 ^ 0xE0;
*((_BYTE *)&v41 - 14) = byte_6233030A ^ 0xB7;
*((_BYTE *)&v41 - 19) = byte_62330305 ^ 0x8F;
*((_BYTE *)&v41 - 7) = byte_62330311 ^ 0xAD;
*((_BYTE *)&v41 - 8) = byte_62330310 ^ 0xD1;
*((_BYTE *)&v41 - 2) = byte_62330316;
v57 = sprintf_0(&v85, &v41 - 6, v16);
v17 = add_watch(v84, &v85, 4095);
v67 = (void *)-1866223142;
v56 = v17;
}
}
if ( (signed int)v62 > -1215902312 )
break;
if ( v62 == (void *)-1296986714 )
{
v1 = (void *)-870557634;
v2 = 0;
if ( !v89 )
v2 = 1;
if ( v2 )
v1 = (void *)363810945;
v67 = v1;
}
}
if ( (signed int)v62 > -870557635 )
break;
if ( v62 == (void *)-1215902311 )
{
v32 = (int *)((char *)v66 + 1132);
v33 = (int *)((char *)v66 + 1140);
++*((_DWORD *)v66 + 280);
v34 = *v32;
v46 = *v33;
v35 = sub_6232B4E8(0, v88, v34);
v36 = (void *)2011994328;
v10 = v46 == v35;
v37 = 0;
if ( !v10 )
v37 = 1;
if ( v37 )
v36 = &unk_4791A5A5;
v67 = v36;
}
}
if ( (signed int)v62 > 248389379 )
break;
if ( v62 == (void *)-870557634 )
{
v61 = 4095;
v84 = init();
v60 = v84;
v4 = fcntl_0(v84, 3, 0);
v5 = fcntl_0(v60, 4, v4 | 0x800);
v6 = v84;
*((_BYTE *)&v41 - 14) = byte_623302F3 ^ 0xFB;
*((_BYTE *)&v41 - 7) = byte_623302FA ^ 0xC7;
*((_BYTE *)&v41 - 3) = byte_623302FE ^ 0xA4;
*((_BYTE *)&v41 - 6) = byte_623302FB ^ 0xCD;
*((_BYTE *)&v41 - 8) = byte_623302F9 ^ 0xDF;
*((_BYTE *)&v41 - 12) = byte_623302F5 ^ 0xC2;
*((_BYTE *)&v41 - 11) = byte_623302F6 ^ 0xAD;
*((_BYTE *)&v41 - 9) = byte_623302F8 ^ 0xB5;
*((_BYTE *)&v41 - 10) = byte_623302F7 ^ 0xBB;
*((_BYTE *)&v41 - 16) = unk_623302F1 ^ 0xDF;
*((_BYTE *)&v41 - 5) = byte_623302FC ^ 0xF0;
*((_BYTE *)&v41 - 4) = byte_623302FD ^ 0xE9;
*((_BYTE *)&v41 - 2) = byte_623302FF;
*((_BYTE *)&v41 - 13) = byte_623302F4 ^ 0xEA;
*((_BYTE *)&v41 - 15) = byte_623302F2 ^ 0x93;
v59 = v5;
v7 = add_watch(v6, &v41 - 4, v61);
v67 = (void *)812103489;
v58 = v7;
}
}
if ( (signed int)v62 > 363810944 )
break;
if ( v62 == (void *)248389380 )
{
*((_BYTE *)&v41 - 6) = byte_62330334 ^ 0x99;
*((_BYTE *)&v41 - 5) = byte_62330335 ^ 0xA1;
*((_BYTE *)&v41 - 4) = byte_62330336;
*((_BYTE *)&v41 - 8) = unk_62330332 ^ 0xA3;
*((_BYTE *)&v41 - 7) = byte_62330333 ^ 0xD8;
*((_BYTE *)&v41 - 10) = byte_6233034B ^ 0xE8;
*((_BYTE *)&v41 - 12) = byte_62330349 ^ 0x94;
*((_BYTE *)&v41 - 16) = unk_62330345 ^ 0x9B;
*((_BYTE *)&v41 - 13) = byte_62330348 ^ 0xA8;
*((_BYTE *)&v41 - 14) = byte_62330347 ^ 0x8C;
*((_BYTE *)&v41 - 11) = byte_6233034A ^ 0xDC;
*((_BYTE *)&v41 - 6) = byte_6233034F;
*((_BYTE *)&v41 - 8) = byte_6233034D ^ 0x9B;
*((_BYTE *)&v41 - 7) = byte_6233034E ^ 0xBF;
*((_BYTE *)&v41 - 15) = byte_62330346 ^ 0x89;
*((_BYTE *)&v41 - 9) = byte_6233034C ^ 0x80;
v48 = sub_62322228(6, &v41 - 2, &v41 - 4);
v31 = raise(9);
v67 = (void *)-1215902311;
v47 = v31;
}
}
if ( (signed int)v62 <= 812103488 )
break;
if ( (signed int)v62 > 936246878 )
{
if ( (signed int)v62 > (signed int)&unk_43EA34CA )
{
if ( (signed int)v62 > (signed int)&unk_57D1BE0A )
{
if ( v62 == &unk_57D1BE0B )
{
v18 = closedir(v87);
v67 = (void *)-1437465225;
v55 = v18;
}
}
else if ( (signed int)v62 > (signed int)&unk_53451D85 )
{
if ( v62 == &unk_53451D86 )
{
*((_BYTE *)&v41 - 4) = byte_62330336;
*((_BYTE *)&v41 - 6) = byte_62330334 ^ 0x99;
*((_BYTE *)&v41 - 7) = byte_62330333 ^ 0xD8;
*((_BYTE *)&v41 - 8) = unk_62330332 ^ 0xA3;
*((_BYTE *)&v41 - 5) = byte_62330335 ^ 0xA1;
*((_BYTE *)&v41 - 12) = byte_6233033B ^ 0xB0;
*((_BYTE *)&v41 - 6) = byte_62330341 ^ 0xE3;
*((_BYTE *)&v41 - 14) = byte_62330339 ^ 0xE9;
*((_BYTE *)&v41 - 16) = unk_62330337 ^ 0x94;
*((_BYTE *)&v41 - 10) = byte_6233033D ^ 0xF5;
*((_BYTE *)&v41 - 13) = byte_6233033A ^ 0xEE;
*((_BYTE *)&v41 - 7) = byte_62330340 ^ 0xDE;
*((_BYTE *)&v41 - 8) = byte_6233033F ^ 0x83;
*((_BYTE *)&v41 - 9) = byte_6233033E ^ 0xD8;
*((_BYTE *)&v41 - 3) = byte_62330344;
*((_BYTE *)&v41 - 11) = byte_6233033C ^ 0xD4;
*((_BYTE *)&v41 - 4) = byte_62330343 ^ 0x9C;
*((_BYTE *)&v41 - 5) = byte_62330342 ^ 0xE2;
*((_BYTE *)&v41 - 15) = byte_62330338 ^ 0xCE;
v54 = sub_62322228(6, &v41 - 2, &v41 - 4);
v22 = getpid_0();
v53 = kill_0(v22, 9);
v23 = raise(9);
v24 = *((_DWORD *)v66 - 8) & 0xFFFFF000;
v52 = v23;
v25 = mprotect_0(v24, 0x2000, 3);
v26 = *((_DWORD *)v66 - 8) & 0xFFFFF000;
v51 = v25;
v50 = (void *)936246879;
v49 = v26;
aeabi_memset8(1074606080, 0x2000, 0);
v67 = v50;
}
}
else if ( (signed int)v62 > (signed int)&unk_4B2A5020 )
{
if ( v62 == &unk_4B2A5021 )
{
v12 = (void *)-1866223142;
v13 = 0;
if ( *(_BYTE *)(v86 + 18) & 4 )
v13 = 1;
if ( v13 )
v12 = &unk_43EA34CB;
v67 = v12;
}
}
else if ( v62 == &unk_43EA34CB )
{
v14 = (void *)1892825735;
v15 = 0;
if ( 46 == *(_BYTE *)(v86 + 19) )
v15 = 1;
if ( v15 )
v14 = &unk_45BD5515;
v67 = v14;
}
else if ( v62 == &unk_45BD5515 )
{
v67 = (void *)812103489;
}
else if ( v62 == &unk_4791A5A5 )
{
*((_BYTE *)&v41 - 5) = byte_62330335 ^ 0xA1;
*((_BYTE *)&v41 - 4) = byte_62330336;
*((_BYTE *)&v41 - 6) = byte_62330334 ^ 0x99;
*((_BYTE *)&v41 - 8) = unk_62330332 ^ 0xA3;
*((_BYTE *)&v41 - 7) = byte_62330333 ^ 0xD8;
*((_BYTE *)&v41 - 5) = byte_62330353 ^ 0xB6;
*((_BYTE *)&v41 - 6) = byte_62330352 ^ 0xA8;
*((_BYTE *)&v41 - 8) = unk_62330350 ^ 0xCA;
*((_BYTE *)&v41 - 3) = byte_62330355 ^ 0xBF;
*((_BYTE *)&v41 - 7) = byte_62330351 ^ 0xD6;
*((_BYTE *)&v41 - 2) = byte_62330356;
*((_BYTE *)&v41 - 4) = byte_62330354 ^ 0xD9;
v45 = sub_62322228(6, &v41 - 2, &v41 - 2);
v38 = getpid_0();
v44 = kill_0(v38, 9);
v39 = raise(9);
v67 = (void *)2011994328;
v43 = v39;
}
}
else if ( v62 == (void *)936246879 )
{
v27 = read_0(v84, &v85, 1024);
v28 = (void *)-1215902311;
v10 = v27 == 0;
v29 = v27 < 0;
v30 = 0;
if ( !(v29 | v10) )
v30 = 1;
if ( v30 )
v28 = (void *)248389380;
v67 = v28;
}
}
else if ( v62 == (void *)812103489 )
{
v8 = readdir(v87);
v9 = &unk_57D1BE0B;
v86 = v8;
v10 = v8 == 0;
v11 = 0;
if ( !v10 )
v11 = 1;
if ( v11 )
v9 = &unk_4B2A5021;
v67 = v9;
}
}
}
while ( v62 != (void *)363810945 );
return 0;
}
之后根据偏移定位到JNI_OnLoad函数调用处,这中间好像还有两三处反调试,直接nop掉即可。
在JNI_OnLoad中发现有一个分支再次调用了JNI_OnLoad。
跟进,反汇编有些问题,不贴伪代码了。
其中init函数初始化了一些字符串,register_nativers这个函数大家应该都很熟悉了。
register_nativers函数原型如下:
jint RegisterNatives(jclass clazz,const JNINativeMethod * methods,jint nMethods)
根据参数可知注册了五个函数,函数名分别为。
在java层中首先调用Jni的load函数,load函数获取PID,获取sdk版本,获取vm.version, 判断是art还是dalvik虚拟机,执行不同的加载方案,我这里是dalvik虚拟机,执行方案2。
跟进,在执行解密dex文件前,首先获取原始dex文件的位置,之后获取文件的偏移位置,分配内存,解密的dex文件。在这里我尝试dump,dump出的dex文件没有内容,可能姿势不对,继续单步跟了下去。
根据Log信息定位dex加载到内存中的位置。
分配内存空间,初始化dex内存结构。
内存结构如下图所示,标红处为真实dex文件起始位置,此处即可dump
DalvikLoad函数伪代码如下:
int v3; // r6@1
int v4; // r0@2
int v5; // r4@2
int v6; // r0@2
int v7; // r0@2
int v8; // r0@2
int v9; // r7@2
int v10; // ST00_4@3
int v11; // ST00_4@3
int v12; // r0@5
int v13; // ST00_4@5
const char *v14; // r1@6
const char *v15; // r2@6
int v16; // r0@16
int v17; // r5@16
_DWORD *v18; // r3@16
int v19; // ST00_4@17
int v20; // ST00_4@18
const char *v21; // r1@20
const char *v22; // r2@20
int v23; // r4@21
int v24; // r1@23
const char *v25; // r1@24
const char *v26; // r2@24
int v27; // r4@34
int v28; // ST14_4@40
int v29; // r0@40
int v30; // r1@41
int v31; // r1@44
int v32; // r5@47
int v33; // ST00_4@47
int v34; // r0@48
int v35; // ST00_4@49
int v36; // r5@49
int v37; // r4@53
int v38; // r4@57
int v39; // r2@61
int v40; // r3@62
int v41; // r3@64
int v42; // r3@65
int v43; // r3@66
int v44; // r1@67
int v45; // r3@67
int v46; // r5@67
int v47; // r2@68
int v48; // r5@80
int v49; // r2@80
int v50; // r0@82
int v51; // r4@85
int v52; // r0@87
int v53; // r5@87
int m; // r4@87
int v55; // r0@89
int v56; // r2@90
const char *v57; // r3@90
int v58; // ST00_4@90
int v59; // r1@90
int v60; // r0@90
int v61; // r0@79
int i; // r4@79
int v63; // r0@93
int v64; // r5@95
int v65; // r0@95
int j; // r4@95
int v67; // r0@97
int v68; // r5@98
int v69; // r4@98
int v70; // r0@98
int k; // r4@98
int v72; // r0@100
int v73; // r5@101
int v74; // r4@101
int v75; // r7@101
int v76; // r0@101
int v77; // r0@101
int l; // r4@101
int v79; // r0@103
int v80; // r4@104
int v81; // r0@104
int v82; // ST00_4@105
int v83; // ST00_4@106
_DWORD *result; // r0@108
int v85; // [sp+10h] [bp-180h]@3
int v86; // [sp+10h] [bp-180h]@79
int v87; // [sp+14h] [bp-17Ch]@5
signed int v88; // [sp+14h] [bp-17Ch]@40
int v89; // [sp+14h] [bp-17Ch]@98
int v90; // [sp+18h] [bp-178h]@3
int v91; // [sp+18h] [bp-178h]@13
int v92; // [sp+1Ch] [bp-174h]@1
signed int v93; // [sp+1Ch] [bp-174h]@36
int v94; // [sp+1Ch] [bp-174h]@54
int v95; // [sp+20h] [bp-170h]@1
int v96; // [sp+24h] [bp-16Ch]@3
int v97; // [sp+24h] [bp-16Ch]@98
int v98; // [sp+28h] [bp-168h]@13
int v99; // [sp+2Ch] [bp-164h]@2
signed int v100; // [sp+2Ch] [bp-164h]@54
int v101; // [sp+30h] [bp-160h]@3
int v102; // [sp+34h] [bp-15Ch]@13
int v103; // [sp+38h] [bp-158h]@2
int v104; // [sp+3Ch] [bp-154h]@13
int v105; // [sp+40h] [bp-150h]@40
int v106; // [sp+44h] [bp-14Ch]@3
int v107; // [sp+4Ch] [bp-144h]@95
int v108; // [sp+50h] [bp-140h]@40
int v109; // [sp+54h] [bp-13Ch]@2
_DWORD *v110; // [sp+5Ch] [bp-134h]@1
int v111; // [sp+60h] [bp-130h]@37
char v112; // [sp+64h] [bp-12Ch]@53
int v113; // [sp+78h] [bp-118h]@53
char v114; // [sp+7Ch] [bp-114h]@53
int v115; // [sp+90h] [bp-100h]@53
char v116; // [sp+94h] [bp-FCh]@37
int v117; // [sp+A8h] [bp-E8h]@37
signed int v118; // [sp+B4h] [bp-DCh]@40
int v119; // [sp+174h] [bp-1Ch]@1
v3 = a1;
v92 = a3;
v119 = *dword_62282DA4;
v110 = dword_62282DA4;
v95 = (unk_6226ACF8)(a1);
if ( !v95 )
goto LABEL_108;
v4 = (unk_6226A980)(v3, "com/tencent/StubShell/TxAppEntry");
v5 = v4;
v6 = (unk_6226C90C)(v3, v4, "mSrcPath", "Ljava/lang/String;");
v103 = (unk_6226C91A)(v3, v5, v6);
v99 = (unk_6226AEC0)(v3, v103);
v7 = (unk_6226C90C)(v3, v5, "mPKName", "Ljava/lang/String;");
v8 = (unk_6226C91A)(v3, v5, v7);
v109 = (unk_6226AEC0)(v3, v8);
v9 = unk_62282DA8;
if ( dword_622836F8 > 10 )
{
v10 = *(unk_62282DA8 + 248);
v106 = (unk_6226AF4C)(v3, v95, *(unk_62282DA8 + 240), *(unk_62282DA8 + 244));
v11 = *(v9 + 220);
v101 = (unk_6226AF4C)(v3, v106, *(v9 + 212), *(v9 + 216));
v96 = (unk_6226A9C6)(v3, v101);
v90 = 0;
v85 = 0;
while ( 1 )
{
if ( v90 >= v96 )
{
v91 = 0;
v104 = 0;
v102 = 0;
v98 = 0;
goto LABEL_33;
}
v12 = (unk_6226A9D4)(v3, v101, v90);
v13 = *(v9 + 232);
v87 = (unk_6226AF4C)(v3, v12, *(v9 + 224), *(v9 + 228));
if ( !v87 )
break;
v85 = (unk_6226B87C)(v3, v87, *(v9 + 236), *(v9 + 424));
if ( !v85 )
{
v85 = (unk_6226BA5C)(v3, v87, *(v9 + 236), *(v9 + 424));
if ( !v85 )
{
v14 = "SecShell";
v15 = "SetDexClassLoaderCookie GetIntField fail";
goto LABEL_10;
}
}
if ( *v85 && !(unk_6227B18C)(*v85) )
{
v91 = 0;
v104 = 0;
v102 = 0;
v98 = 0;
goto LABEL_33;
}
LABEL_14:
++v90;
}
v14 = "SecShell";
v15 = "SetDexClassLoaderCookie GetObjectField fail:pDexPathListElementsClassName";
LABEL_10:
Log(3, v14, v15);
goto LABEL_14;
}
v16 = (unk_6226A980)(v3, *(unk_62282DA8 + 456));
v17 = (unk_6226C8B6)(v3, v95, v16);
v18 = (v9 + 204);
if ( v17 )
{
v19 = *(v9 + 208);
v98 = (unk_6226AF4C)(v3, v95, *(v9 + 456), *v18);
v102 = (unk_6226AF4C)(v3, v95, *(v9 + 456), "mPaths");
v104 = (unk_6226AF4C)(v3, v95, *(v9 + 456), "mFiles");
v91 = (unk_6226AF4C)(v3, v95, *(v9 + 456), "mZips");
}
else
{
v20 = *(v9 + 208);
v98 = (unk_6226AF4C)(v3, v95, *(v9 + 200), *v18);
v104 = (unk_6226AF4C)(v3, v95, *(v9 + 200), "mFiles");
v102 = 0;
v91 = (unk_6226AF4C)(v3, v95, *(v9 + 200), "mZips");
}
if ( !v98 )
{
v21 = "SecShell";
v22 = "SetDexClassLoaderCookie GetObjectField fail:pmDexs";
goto LABEL_51;
}
v23 = 0;
v96 = (unk_6226A9C6)(v3, v98);
v85 = 0;
while ( 1 )
{
if ( v23 >= v96 )
{
v101 = 0;
v106 = 0;
goto LABEL_33;
}
v24 = (unk_6226A9D4)(v3, v98, v23);
if ( !v24 )
{
v25 = "SecShell";
v26 = "SetDexClassLoaderCookie GetObjectArrayElement fail";
LABEL_27:
Log(3, v25, v26);
goto LABEL_30;
}
v85 = (unk_6226B87C)(v3, v24, *(v9 + 236), *(v9 + 424));
if ( !v85 )
{
v25 = "SecShell";
v26 = "SetDexClassLoaderCookie GetIntField fail";
goto LABEL_27;
}
if ( *v85 && !(unk_6227B18C)(*v85) )
break;
LABEL_30:
++v23;
}
v101 = 0;
v106 = 0;
LABEL_33:
if ( v92 )
v27 = v92 - 40;
else
v27 = (unk_6226E5A4)(v109, "classes.dex", 0);
v93 = 0;
if ( !v27 )
{
(unk_6226E6E8)(&v116, v99, &v111);
Log(3, "SecShell", "strSrcPath:%s");
(unk_6226EC54)(&v116);
Log(3, "SecShell", "strSrcPath:%s");
v27 = (unk_6226E5A4)(v117, "classes.dex", 0);
(unk_6226E6A4)(&v116);
if ( v27 )
{
v93 = 0;
}
else
{
v27 = (unk_6226D964)(v85) - 40;
v93 = 1;
}
}
v28 = (unk_6226C9BA)(v27 + 40);
Log(3, "SecShell", "orgDexOffset:%d");
(unk_6227B1FC)(&v116, 0, 224);
v108 = v27 + v28 + 40;
(unk_6227B27C)(&v116, v27 + v28 + 40, 224);
(unk_622743D8)(&unk_62283248, &v116, 224, 32);
v105 = v27 + v28 + 40;
v88 = v118;
v29 = Log(3, "SecShell", "fileSize:%d");
if ( v93 )
{
v30 = v88;
if ( v88 & 0xFFF )
v30 = (v88 / 4096 + 1) << 12;
v29 = (unk_6227B1DC)(v27, v30, 3);
if ( v29 )
{
v31 = v88;
if ( v88 & 0xFFF )
v31 = (v88 / 4096 + 1) << 12;
v29 = (unk_6227B1DC)(v27, v31, 5);
}
}
v32 = (unk_6226CDBC)(v29);
v33 = *(unk_6227B3DC)(v32);
Log(3, "SecShell", "mRes:%d error:%d");
if ( v32 != -1 || (v34 = Log(3, "SecShell", "wrong code1"), (unk_6226CE0C)(v34) != -1) )
{
LABEL_53:
(unk_622743D8)(&unk_62283248, v105, 224, 32);
(unk_6226E6E8)(&v112, "/data/data/", &v111);
(unk_6226E81A)(&v112, v109);
(unk_6226E9D4)(&v114, &v112, "/mix.so");
(unk_6226E81A)(&v112, "/mix.dex");
v37 = sub_6226ADB0(v3, v113);
sub_6226ADB0(v3, v115);
if ( (unk_6226D4A8)(v3, v103, v113)
&& (v94 = (unk_6226AAD0)(
v3,
"dalvik/system/DexFile",
"loadDex",
"(Ljava/lang/String;Ljava/lang/String;I)Ldalvik/system/DexFile;")) != 0 )
{
v103 = v37;
v100 = 0;
}
else
{
Log(3, "SecShell", "load mix.dex failed");
(unk_6226E938)(&v112, v99);
v94 = (unk_6226AAD0)(
v3,
"dalvik/system/DexFile",
"loadDex",
"(Ljava/lang/String;Ljava/lang/String;I)Ldalvik/system/DexFile;");
Log(3, "SecShell", "load org.dex end");
v100 = 1;
}
v38 = (unk_6226B87C)(v3, v94, *(v9 + 236), *(v9 + 424));
if ( !v38 )
{
v38 = (unk_6226BA5C)(v3, v94, *(v9 + 236), *(v9 + 424));
if ( !v38 )
Log(3, "SecShell", "testCookie is null");
}
if ( v100 )
{
v39 = dword_622836F8;
}
else
{
v39 = dword_622836F8;
if ( dword_622836F8 > 10 )
{
v40 = *(*(v38 + 8) + 4);
goto LABEL_67;
}
}
v41 = *(v38 + 12);
if ( v39 == 8 )
v42 = *(v41 + 36);
else
v43 = *(v41 + 40);
LABEL_67:
v111 = 0;
(unk_6226D850)(v3, v105, v88, &v111);
v45 = v111;
v46 = *(v111 + 4);
if ( v100 )
{
*(v38 + 8) = v111;
*(v38 + 4) = 1;
if ( dword_622836F8 == 10 )
*(v85 + 16) = v105;
}
else
{
v47 = dword_622836F8;
if ( dword_622836F8 > 10 )
{
if ( dword_622836F8 <= 18 && (unk_6226CE60)(v100, v44, dword_622836F8) )
(unk_6227227C)(*(*(v38 + 8) + 4), v46, dword_622836F8);
else
(unk_62272290)(*(*(v38 + 8) + 4), v46, dword_622836F8);
LABEL_78:
if ( dword_622836F8 <= 10 )
{
v61 = (unk_6226A980)(v3, "dalvik/system/DexFile");
v86 = (unk_6226C928)(v3, v96 + 1, v61, 0);
(unk_6226A9E2)(v3, v86, 0, v94);
for ( i = 0; i < v96; (unk_6226A9E2)(v3, v86, i, v63) )
v63 = (unk_6226A9D4)(v3, v98, i++);
if ( v102 )
{
v64 = (unk_6226A9C6)(v3, v102);
v65 = (unk_6226A980)(v3, "java/lang/String");
v107 = (unk_6226C928)(v3, v64 + 1, v65, 0);
(unk_6226A9E2)(v3, v107, 0, v103);
for ( j = 0; j < v64; (unk_6226A9E2)(v3, v107, j, v67) )
v67 = (unk_6226A9D4)(v3, v102, j++);
}
v68 = (unk_6226A9C6)(v3, v104);
v69 = (unk_6226A980)(v3, "java/io/File");
v89 = (unk_6226C928)(v3, v68 + 1, v69, 0);
v70 = (unk_6226A9AE)(v3, v69, "<init>", "(Ljava/lang/String;)V");
v97 = (unk_6226A994)(v3, v69, v70, v103);
(unk_6226A9E2)(v3, v89, 0, v97);
for ( k = 0; k < v68; (unk_6226A9E2)(v3, v89, k, v72) )
v72 = (unk_6226A9D4)(v3, v104, k++);
v73 = (unk_6226A9C6)(v3, v91);
v74 = (unk_6226A980)(v3, "java/util/zip/ZipFile");
v75 = (unk_6226C928)(v3, v73 + 1, v74, 0);
v76 = (unk_6226A9AE)(v3, v74, "<init>", "(Ljava/io/File;)V");
v77 = (unk_6226A994)(v3, v74, v76, v97);
(unk_6226A9E2)(v3, v75, 0, v77);
for ( l = 0; l < v73; (unk_6226A9E2)(v3, v75, l, v79) )
v79 = (unk_6226A9D4)(v3, v91, l++);
v80 = unk_62282DA8;
v81 = (unk_6226A980)(v3, *(unk_62282DA8 + 456));
if ( (unk_6226C8B6)(v3, v95, v81) )
{
v82 = *(v80 + 208);
(unk_6226B008)(v3, v95, *(v80 + 456), *(v80 + 204));
(unk_6226B008)(v3, v95, *(v80 + 456), "mPaths");
(unk_6226B008)(v3, v95, *(v80 + 456), "mFiles");
v56 = *(v80 + 456);
v60 = v3;
v59 = v95;
v57 = "mZips";
}
else
{
v83 = *(v80 + 208);
(unk_6226B008)(v3, v95, *(v80 + 200), *(v80 + 204));
(unk_6226B008)(v3, v95, *(v80 + 200), "mFiles");
v56 = *(v80 + 200);
v60 = v3;
v59 = v95;
v57 = "mZips";
}
goto LABEL_91;
}
v48 = (unk_6226A980)(v3, "dalvik/system/DexPathList$Element");
v49 = (unk_6226A9AE)(v3, v48, "<init>", "(Ljava/io/File;Ljava/util/zip/ZipFile;Ldalvik/system/DexFile;)V");
if ( v49
|| ((unk_6226C8AC)(v3),
(v49 = (unk_6226A9AE)(v3, v48, "<init>", "(Ljava/io/File;Ljava/io/File;Ldalvik/system/DexFile;)V")) != 0) )
{
v50 = (unk_6226A994)(v3, v48, v49);
}
else
{
(unk_6226C8AC)(v3);
if ( !(unk_6226A9AE)(v3, v48, "<init>", "(Ljava/io/File;ZLjava/io/File;Ldalvik/system/DexFile;)V") )
{
v51 = 0;
LABEL_87:
v52 = (unk_6226A980)(v3, "dalvik/system/DexPathList$Element");
v53 = (unk_6226C928)(v3, v96 + 1, v52, 0);
(unk_6226A9E2)(v3, v53, 0, v51);
for ( m = 0; m < v96; (unk_6226A9E2)(v3, v53, m, v55) )
v55 = (unk_6226A9D4)(v3, v101, m++);
v56 = *(v9 + 212);
v57 = *(v9 + 216);
v58 = *(v9 + 220);
v59 = v106;
v60 = v3;
LABEL_91:
(unk_6226B008)(v60, v59, v56, v57);
dword_62283728 = (*(*v3 + 84))(v3, v94);
Log(3, "SecShell", &unk_6227F13A);
(unk_6226E6A4)(&v114);
(unk_6226E6A4)(&v112);
goto LABEL_108;
}
v50 = (unk_6226A994)(v3, v48);
}
v51 = v50;
goto LABEL_87;
}
*(v38 + 4) = 1;
*(v38 + 8) = v45;
if ( v47 == 10 )
*(v85 + 16) = v105;
}
*(v38 + 12) = 0;
goto LABEL_78;
}
Log(3, "SecShell", "wrong code");
v35 = (unk_6227B32C)("/dev/zero", 2);
v36 = (unk_6227B44C)(0, v88);
(unk_6227B38C)(v35);
if ( v36 )
{
(unk_6227B28C)(v36, v108, v88);
v105 = v36;
goto LABEL_53;
}
v21 = "SecShell";
v22 = "mmap fail";
LABEL_51:
Log(3, v21, v22);
LABEL_108:
result = v110;
if ( v119 != *v110 )
sub_6227B24C(v110);
return result;
}
文档写的有些流水账,只是调试过程中的一些记录,各位看官勿喷。如有误欢迎交流与指点。
同时脱壳过程中参考了论坛上各位大佬们的帖子,学习了许多。
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界