首页
社区
课程
招聘
[原创]某锁机APP脱壳笔记。
发表于: 2017-8-6 22:34 11408

[原创]某锁机APP脱壳笔记。

2017-8-6 22:34
11408

分析锁机样本中发现加了壳,硬着头皮撸了一遍,样本所使用加固为腾讯乐固,壳版本为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 RegisterNativesjclass clazzconst JNINativeMethod * methodsjint nMethods

 

根据参数可知注册了五个函数,函数名分别为。

 

 

 

java层中首先调用Jniload函数,load函数获取PID,获取sdk版本,获取vm.version, 判断是art还是dalvik虚拟机,执行不同的加载方案,我这里是dalvik虚拟机,执行方案2

 

 

 

 

跟进,在执行解密dex文件前,首先获取原始dex文件的位置,之后获取文件的偏移位置,分配内存,解密的dex文件。在这里我尝试dumpdump出的dex文件没有内容,可能姿势不对,继续单步跟了下去。

 

 

 

 

根据Log信息定位dex加载到内存中的位置。

 

 

 

分配内存空间,初始化dex内存结构。

 

 

 


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

上传的附件:
收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/08/25
最新回复 (5)
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
能否分析下art  下的内存加载dex
2017-8-9 17:31
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
能给下样本吗
2017-8-10 11:50
0
雪    币: 3542
活跃值: (239)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
同求样本apk练手
2017-8-10 17:33
0
雪    币: 5633
活跃值: (7309)
能力值: ( LV15,RANK:531 )
在线值:
发帖
回帖
粉丝
5
你说dump出的dex文件没有内容,我在那里dump了也只有dex头,我估计可能那里还没有解密完吧
2017-8-27 19:09
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
能否分析下art    下的内存加载dex
2017-8-28 21:25
0
游客
登录 | 注册 方可回帖
返回
//