查看原文
其他

某壳分析+修复

Roselia 看雪学院 2019-05-26



声明



仅限技术讨论,不得用于非法途径,后果自负。

分析中有什么错误欢迎大家指出



Java层分析



java层简单分析下流程,重点放在so文件分析


加固效果主要把类方法抽取(其实并没有抽取,还是在dex文件中,只是修改了accessFlags和codeoff)




通过查看AndroidManifest文件application被修改成壳入口的文件(此壳加固的原apk必须自己声明Application文件,否则会加固失败,加固网站也不会提示,只是在加固apk中有文本提示,感觉用户体验不是很好)




这里可以根据壳入口点自己跟着走一遍,我只说下大体流程吧




当执行完application就该执行AndroidManifest声明的activity,执行activity先执行里面的方法static方法,dofixc方法最终会执行到native的soInit和dofixs来修复方法



Native方法分析



通过java层分析,最终会加载libzuma.so


soinit方法分析,f5大法好


此壳f5一些函数损坏不是很严重,大部分都保留原样


方法大部分都是修复的,我只大体说下函数作用,其他具体自己看代码



主要3个方法


1. ali::AndroidDevice::AndroidDevice(androidDevice, env1);

主要判断sdk和dalvik还是art


AndroidDevice *__fastcall ali::AndroidDevice::AndroidDevice(int androidDevice, JNIEnv *env)
{
 AndroidDevice *androidDevice1; // r4
 JNIEnv *env1; // r7
 int v4; // r6
 int v5; // r0
 int v6; // r0
 _JNIEnv *v7; // r1
 _BOOL4 v8; // r0

 androidDevice1 = (AndroidDevice *)androidDevice;
 env1 = env;
 v4 = androidDevice + 4;
 *(_DWORD *)(androidDevice + 20) = androidDevice + 4;
 *(_DWORD *)(androidDevice + 24) = androidDevice + 4;
 std::priv::_String_base<char,std::allocator<char>>::_M_allocate_block(androidDevice + 4, 16);
 *(_BYTE *)androidDevice1->field_14 = 0;
 androidDevice1->systemModeAddr = 0;
 androidDevice1->field_30 = 0;
 androidDevice1->field_34 = 0;
 androidDevice1->dexAddr = 0;
 androidDevice1->field_3C = 0;
 androidDevice1->field_40 = 0;
 androidDevice1->env = (int)env1;
 std::string::operator=(v4, &unk_28EB8);
 androidDevice1->systemModeBoolean = 0;
 androidDevice1->system_sdk_version = ali::AndroidDevice::get_system_sdk_version((ali::AndroidDevice *)androidDevice1);// 魅族5.0.1->21
 v5 = ali::AndroidDevice::get_runtime_by_mmap((ali::AndroidDevice *)androidDevice1);// 获取系统模式dalvik返回1 art返回2
 v6 = ali::AndroidDevice::get_system_runtime((ali::AndroidDevice *)androidDevice1, v5);// 如果上边判断不出是dalvik还是art继续判断
 androidDevice1->systemMode = v6;
 androidDevice1->systemModeBoolean = (unsigned int)(v6 - 1) >= 1;// dalvik=false art=true
 if ( j_strstr(androidDevice1->systemModeContent, "libaoc.so") )
   androidDevice1->isYunOs = 1;
 else
   androidDevice1->isYunOs = ali::check_for_yun_os((JNIEnv *)androidDevice1->env, v7);// 有ro.yunos.version的话返回1
 v8 = ali::check_for_yun_os_TV((ali *)androidDevice1->env, v7);
 androidDevice1->isYunOsTv = v8;               // yun_os_tv返回1
 if ( v8 )
   androidDevice1->isYunOs = 1;
 return androidDevice1;
}


2.ali::AppInfo::AppInfo(appinfo, (_JNIEnv *)env1, (int)&v38);

主要是获取一些文件目录


AppInfo *__fastcall ali::AppInfo::AppInfo(ali::AppInfo *appinfo, _JNIEnv *env, int a3)
{
 AppInfo *appinfo1; // r4
 _JNIEnv *env1; // ST08_4
 char *v5; // r7
 const char **v6; // ST0C_4
 const char *v7; // r2

 appinfo1 = (AppInfo *)appinfo;
 env1 = env;
 v5 = (char *)appinfo + 0x18;
 v6 = (const char **)a3;
 std::string::string((int)appinfo);
 std::string::string((int)v5);
 std::string::string((int)&appinfo1->nativeLibraryDir);
 std::string::string((int)&appinfo1->sourceDir);
 std::string::operator=((std::string *)appinfo1, v6);
 std::string::operator=(v5, &unk_28EB8);
 std::string::operator=(&appinfo1->nativeLibraryDir, &unk_28EB8);
 std::string::operator=(&appinfo1->sourceDir, &unk_28EB8);
 appinfo1->field_60 = 0;
 ali::AppInfo::initAppInfo((ali::AppInfo *)appinfo1, env1, v7);
 return appinfo1;
}


3. ali::ZumaInfo::ZumaInfo(zumaInfo, (const char **)&v38);


读取zumadata信息到内存,然后把libzumadata信息读取出来,对应3个部分,头部,类信息,方法信息


ZumaInfo *__fastcall ali::ZumaInfo::ZumaInfo(ZumaInfo *zumaInfo, const char **a2)
{
 ZumaInfo *zumaInfo1; // r4
 const char **v3; // r3
 const char *v4; // r1
 const char *v5; // r2

 zumaInfo1 = zumaInfo;
 v3 = a2;
 zumaInfo->zumaDataPathEnd = (int)zumaInfo;
 zumaInfo->zumaDataPathStart = (int)zumaInfo;
 zumaInfo->zero = 0;
 if ( a2 != (const char **)zumaInfo )
 {
   v4 = a2[5];
   v5 = v3[4];
   if ( v5 != v4 )
     std::string::_M_append((std::string *)zumaInfo, v4, v5);// /data/data/com.kangkai.test/files/ali-s/libzumadata.so加到zumainfo中
 }
 zumaInfo1->zumaDataMemory = ali::ZumaInfo::mmap_datafile_to_memory(zumaInfo1);// /data/data/com.kangkai.test/files/ali-s/libzumadata.so加入到内存
 ali::ZumaInfo::gen_dex_info_list(zumaInfo1);
 ali::ZumaInfo::gen_clazz_info_list(zumaInfo1);
 ali::ZumaInfo::gen_method_info_list(zumaInfo1);
 return zumaInfo1;
}


ali::ZumaInfo::gen_dex_info_list(zumaInfo1)

读取信息到开辟的dexcount*0x2c的内存中


int __fastcall ali::ZumaInfo::gen_dex_info_list(ZumaInfo *zumaInfo)
{
 int dexCount; // r7
 ZumaInfo *zumaInfo1; // r4
 int v3; // r0
 int i; // r1
 int nextOffset1; // r0
 ZumaHeader *zumaHeader; // r3
 int v7; // r6
 int nextOffset; // r5
 int v9; // r6
 int v10; // r2
 int zumaDataMemory; // [sp+10h] [bp-20h]
 int dexCount1; // [sp+14h] [bp-1Ch]

 dexCount = zumaInfo->dexCount;
 zumaInfo1 = zumaInfo;
 v3 = j_malloc(0x2C * dexCount);
 zumaInfo1->zumaDataHeader = v3;
 if ( !v3 )
 {
   logoutRecord(
     "gen_dex_info_list",
     68,
     6,
     "RecordLog",
     "dex_count (%d),dex_info_list_size (%d)",
     dexCount,
     0x2C * dexCount);
   my_abort("jni/base/zuma-info.cpp", "gen_dex_info_list", 69, "malloc dex_info_list error");
 }
 j_memset(zumaInfo1->zumaDataHeader, 0, 0x2C * dexCount);
 i = 0;
 nextOffset1 = 0;
 zumaDataMemory = zumaInfo1->zumaDataMemory;
 dexCount1 = zumaInfo1->dexCount;
 while ( i != dexCount1 )                      // 把zumadata.so+4开始到0x18内容拷贝出来
 {
   zumaHeader = (ZumaHeader *)(zumaInfo1->zumaDataHeader + 0x2C * i);
   v7 = *(_DWORD *)(zumaDataMemory + nextOffset1 + 0x14);
   ++i;
   zumaHeader->field_0 = *(_DWORD *)(zumaDataMemory + nextOffset1 + 4);
   zumaHeader->field_4 = *(_DWORD *)(zumaDataMemory + nextOffset1 + 8);
   zumaHeader->field_8 = *(_DWORD *)(zumaDataMemory + nextOffset1 + 0xC);
   nextOffset = *(_DWORD *)(zumaDataMemory + nextOffset1 + 0x10);
   zumaHeader->classLength = v7;
   v9 = *(_DWORD *)(zumaDataMemory + nextOffset1 + 0x18);
   v10 = *(_DWORD *)(zumaDataMemory + nextOffset1 + 0x1C);
   zumaHeader->field_14 = nextOffset;
   zumaHeader->methodLength = v9;
   zumaHeader->field_20 = nextOffset1 + v10;
   zumaHeader->hex20 = 0x20;
   zumaHeader->dexAddr = 0;
   nextOffset1 += nextOffset;
 }
 return nextOffset1;
}


ali::ZumaInfo::gen_clazz_info_list(zumaInfo1)


把信息读取到开辟的内存中,然后会把内存中的数据排序


int __fastcall ali::ZumaInfo::gen_clazz_info_list(ZumaInfo *zumaInfo)
{
 int v1; // r3
 int dexCount; // r1
 ZumaInfo *zumaInfo1; // r4
 int i; // r5
 int v5; // r2
 int v6; // r0
 int v7; // r3
 int zumaData20; // r5
 int v9; // r6
 ZumaHeader *zumaHeader; // r3
 unsigned __int8 *v11; // r1
 int *v12; // r7
 int v13; // r0
 int zumaClass; // r3
 unsigned __int8 *v15; // r1
 int zumaClass1; // r7
 unsigned __int8 *v17; // r1
 unsigned __int8 *v18; // r1
 int v19; // r0
 int zumaClass2; // r3
 unsigned int v22; // [sp+4h] [bp-2Ch]
 int v23; // [sp+8h] [bp-28h]
 int v24; // [sp+Ch] [bp-24h]
 int v25; // [sp+10h] [bp-20h]

 v1 = 0;
 dexCount = zumaInfo->dexCount;
 zumaInfo1 = zumaInfo;
 for ( zumaInfo->zumaDataClassLength = 0;
       ;
       zumaInfo->zumaDataClassLength = i + *(_DWORD *)(zumaInfo->zumaDataHeader + v5 + 0xC) )
 {
   i = zumaInfo->zumaDataClassLength;          // 0x2cb
   if ( v1 == dexCount )
     break;
   v5 = 0x2C * v1++;
 }
 v6 = j_malloc(0x14 * i);                      // 0x37DC
 zumaInfo1->zumaClass = v6;
 j_memset(v6, 0, 0x14 * i);
 v7 = 0;
 v22 = 0;
 v25 = 0;
 while ( 1 )
 {
   v24 = v7;
   if ( v22 >= zumaInfo1->dexCount )
     break;
   zumaData20 = zumaInfo1->zumaDataMemory + v25 + *(_DWORD *)(zumaInfo1->zumaDataHeader + 0x2C * v22 + 0x18);// 读取zumadata从0x20位置开始
   v9 = 0x14 * v7;
   v23 = v7;
   while ( 1 )                                 // 把zumadata从0x20信息拷贝到classinfo
                                               // 0x10大小原样拷贝,从0x10开始拷贝zumadata20+0x10地址
   {
     zumaHeader = (ZumaHeader *)(zumaInfo1->zumaDataHeader + 0x2C * v22);
     v11 = (unsigned __int8 *)zumaHeader->classLength;// 0x2cb类信息大小
     if ( v23 - v24 >= (unsigned int)v11 )
       break;
     v12 = (int *)(zumaInfo1->zumaClass + v9);
     v13 = ali::readUint32((ali *)zumaData20, v11);
     zumaClass = zumaInfo1->zumaClass;
     *v12 = v13;
     *(_DWORD *)(zumaClass + v9 + 4) = ali::readUint32((ali *)(zumaData20 + 4), v15);
     zumaClass1 = zumaInfo1->zumaClass + v9;
     *(_DWORD *)(zumaClass1 + 8) = ali::readUint32((ali *)(zumaData20 + 8), v17);
     v19 = ali::readUint32((ali *)(zumaData20 + 0xC), v18);
     zumaClass2 = zumaInfo1->zumaClass + v9;
     *(_DWORD *)(zumaClass2 + 0xC) = v19;
     *(_DWORD *)(zumaClass2 + 0x10) = zumaData20 + 0x10;
     zumaData20 += 4 * (v19 + 4);
     ++v23;
     v9 += 0x14;
   }
   v25 += zumaHeader->field_14;
   ++v22;
   v7 = v23;
 }
 return ali::quicksort_Clazz_Info_Struct(zumaInfo1->zumaClass, 0, zumaInfo1->zumaDataClassLength - 1);
}


ali::ZumaInfo::gen_method_info_list(zumaInfo1)


看具体注释吧


int __fastcall ali::ZumaInfo::gen_method_info_list(ZumaInfo *zumaInfo)
{
 int v1; // r3
 int v2; // r1
 ZumaInfo *zumaInfo1; // r5
 int v4; // r4
 int v5; // r2
 int v6; // r0
 int result; // r0
 ZumaHeader *zumaHeader; // r3
 int v9; // r4
 int zumaData90f0; // r4
 int v11; // r6
 ZumaHeader *zumaHeader1; // r3
 unsigned __int8 *v13; // r1
 int *v14; // r7
 int v15; // r0
 int methodInfo1; // r3
 unsigned __int8 *v17; // r1
 int methodInfo2; // r7
 unsigned __int8 *v19; // r1
 ali *v20; // r0
 int methodInfo3; // r7
 unsigned __int8 *v22; // r1
 unsigned int v23; // [sp+4h] [bp-2Ch]
 int v24; // [sp+8h] [bp-28h]
 int v25; // [sp+Ch] [bp-24h]
 int v26; // [sp+10h] [bp-20h]
 int v27; // [sp+14h] [bp-1Ch]

 v1 = 0;
 v2 = zumaInfo->dexCount;
 zumaInfo1 = zumaInfo;
 for ( zumaInfo->zumaDataMethodLength = 0;
       ;
       zumaInfo->zumaDataMethodLength = v4 + *(_DWORD *)(zumaInfo->zumaDataHeader + v5 + 0x10) )
 {
   v4 = zumaInfo->zumaDataMethodLength;        // 0x1906
   if ( v1 == v2 )
     break;
   v5 = 0x2C * v1++;
 }
 v6 = j_malloc(0x14 * v4);                     // 0x1f478
 zumaInfo1->methodInfo = v6;
 result = j_memset(v6, 0, 0x14 * v4);
 v23 = 0;
 v26 = 0;
 v24 = 0;
 while ( v23 < zumaInfo1->dexCount )
 {
   v25 = 0x2C * v23;
   zumaHeader = (ZumaHeader *)(zumaInfo1->zumaDataHeader + 0x2C * v23);
   v9 = 4 * zumaHeader->methodLength + 0x10 * zumaHeader->classLength;// 0x6418+0x2cb0=90c8
   if ( v9 & 0xF )                             // 0x8
     v9 = v9 + 0x10 - (v9 & 0xF);              // 0x90c8+0x10-0x8=0x90d0
   zumaData90f0 = zumaInfo1->zumaDataMemory + v26 + zumaHeader->hex20 + v9;// 0x90d0+0x20=0x90f0
   v27 = v24;
   v11 = 20 * v24;
   while ( 1 )                                 // method 0x0->*zudaData90f0 0x4->*zudaData90f0+0x4 0x8->*zudaData90f0+0x8
                                               // 0xc->*zudaData90f0+0xc+*zumaHeader+0x20
                                               // 0x10->*zumaHeader
   {
     zumaHeader1 = (ZumaHeader *)(zumaInfo1->zumaDataHeader + v25);
     v13 = (unsigned __int8 *)zumaHeader1->methodLength;
     if ( v24 - v27 >= (unsigned int)v13 )
       break;
     v14 = (int *)(zumaInfo1->methodInfo + v11);
     v15 = ali::readUint32((ali *)zumaData90f0, v13);
     methodInfo1 = zumaInfo1->methodInfo;
     *v14 = v15;
     *(_DWORD *)(methodInfo1 + v11 + 0x10) = *(_DWORD *)(zumaInfo1->zumaDataHeader + v25);
     *(_DWORD *)(methodInfo1 + v11 + 4) = ali::readUint32((ali *)(zumaData90f0 + 4), v17);
     methodInfo2 = zumaInfo1->methodInfo + v11;
     *(_DWORD *)(methodInfo2 + 8) = ali::readUint32((ali *)(zumaData90f0 + 8), v19);
     v20 = (ali *)(zumaData90f0 + 0xC);
     zumaData90f0 += 0x10;
     methodInfo3 = zumaInfo1->methodInfo + v11;
     v11 += 0x14;
     result = ali::readUint32(v20, v22) + *(_DWORD *)(zumaInfo1->zumaDataHeader + v25 + 0x20);
     *(_DWORD *)(methodInfo3 + 0xC) = result;
     ++v24;
   }
   v26 += zumaHeader1->field_14;
   ++v23;
 }
 return result;
}


native doFixS分析

通过二分法查询了之前排序的类信息的偏移位置


JNIEnv *__fastcall Java_com_ali_mobisecenhance_Fix_doFixS(JNIEnv *env, int a2, int *cls, ali *classHash)
{
 ali *classHash1; // r6
 JNIEnv *env1; // r7
 int v6; // r2
 int classIndex; // r5
 int v9; // r2
 int v10; // [sp+8h] [bp-28h]
 int *cls1; // [sp+Ch] [bp-24h]
 unsigned int v12; // [sp+10h] [bp-20h]

 classHash1 = classHash;
 v10 = a2;
 env1 = env;
 cls1 = cls;
 v12 = 0;
 classIndex = ali::getClazzInfoRefByClzHash(classHash, (int)&v12, cls);// 在dump的classinfo中查找类信息
 if ( classIndex == -1 )
   return (JNIEnv *)logout(
                      (const char *)&unk_28914,
                      699,
                      5,
                      "RecordLog",
                      "can not find clazz_hash %X",
                      classHash1,
                      v10,
                      cls1);
 if ( !ali::ZumaInfo::get_dex_file_adress(ali::g_zuma_infos, v12, v6, (int)&ali::g_zuma_infos) )
   ali::get_all_dex_header_address_dalvik(*(ali **)(ali::g_app_infos + 96), v12, v9);
 return fix_class(env1, v10, (int)cls1, classIndex);
}


fix_class方法


通过类偏移地址找到类信息,里面存储了需要修复的方法数量和方法偏移地址等


JNIEnv *__fastcall fix_class(JNIEnv *env, int a2, int cls, int classIndex)
{
 _jmethodID *cls1; // ST24_4
 JNIEnv *env1; // ST1C_4
 unsigned __int8 *v6; // ST20_4
 FixFunInfo *fixFunInfo; // r3
 int classHash1; // ST2C_4
 int v9; // ST30_4
 int fixNativeCount1; // ST38_4
 int methodOffset1; // ST3C_4
 int v12; // r5
 int dexAddr; // r0
 int v15; // [sp+40h] [bp-18h]

 cls1 = (_jmethodID *)cls;
 env1 = env;
 v6 = (unsigned __int8 *)a2;
 fixFunInfo = (FixFunInfo *)(ali::g_zuma_infos->zumaClass + 0x14 * classIndex);
 classHash1 = fixFunInfo->classHash;
 v9 = fixFunInfo->field_4;
 fixNativeCount1 = fixFunInfo->fixNativeCount; // 需要修复的native数量
 methodOffset1 = fixFunInfo->methodOffset;
 v12 = fixFunInfo->field_8;                    // 0
 dexAddr = ali::ZumaInfo::get_dex_file_adress(ali::g_zuma_infos, fixFunInfo->field_8, (int)&v15, (int)fixFunInfo);
 return ali::start_fix_this_class(env1, v6, cls1, dexAddr, classHash1, v9, v12, fixNativeCount1, methodOffset1);
}


start_fix_this_class方法


在dex中获取到类方法的地址,然后通过动态获取到类方法来修复


JNIEnv *__fastcall ali::start_fix_this_class(JNIEnv *result, unsigned __int8 *a2, _jmethodID *cls, int dexAddr, int a5, int a6, int a7, unsigned int nativeCount, int methodOffset)
{
 int dexAddr1; // r4
 unsigned int i; // r3
 int methodIdIndex; // r7
 unsigned __int16 *dexMethodId; // r3
 unsigned __int16 protoIdIndex; // r6
 char *methodName; // r7
 char *methodSign; // r6
 unsigned int v16; // [sp+14h] [bp-3Ch]
 int string_ids_addr; // [sp+18h] [bp-38h]
 int methodAddr; // [sp+1Ch] [bp-34h]
 int className; // [sp+20h] [bp-30h]
 int type_ids_addr; // [sp+24h] [bp-2Ch]
 int method_ids_addr; // [sp+28h] [bp-28h]
 char *env; // [sp+2Ch] [bp-24h]
 _jmethodID *cls1; // [sp+30h] [bp-20h]
 int proto_ids_addr; // [sp+34h] [bp-1Ch]

 dexAddr1 = dexAddr;
 env = (char *)result;
 string_ids_addr = dexAddr + *(_DWORD *)(dexAddr + 0x3C);
 cls1 = cls;
 type_ids_addr = dexAddr + *(_DWORD *)(dexAddr + 0x44);
 method_ids_addr = dexAddr1 + *(_DWORD *)(dexAddr1 + 0x5C);
 proto_ids_addr = dexAddr + *(_DWORD *)(dexAddr + 0x4C);
 for ( i = 0; ; i = v16 + 1 )
 {
   v16 = i;
   if ( i >= nativeCount )                     // 被native的方法数量
     break;
   methodAddr = 0x14 * ali::readUint32((ali *)(methodOffset + 4 * i), a2);// methodOffset=2e
                                               // 0000A230=0x081c*0x14  1C 08 00 00 1D 08 00 00  B9 D7 9C DA 00 00 00 00
   methodIdIndex = *(_DWORD *)(ali::g_zuma_infos->methodInfo + methodAddr + 4);// 0x4846
   dexMethodId = (unsigned __int16 *)(method_ids_addr + 8 * methodIdIndex);// dex中某个地址
   protoIdIndex = dexMethodId[1];
   className = ali::get_class_name(dexAddr1, string_ids_addr, type_ids_addr, *dexMethodId);// typeIdIndex
   methodName = (char *)ali::get_method_name(dexAddr1, string_ids_addr, method_ids_addr, methodIdIndex);
   methodSign = ali::get_method_sig(dexAddr1, string_ids_addr, type_ids_addr, proto_ids_addr, protoIdIndex);
   if ( ali::g_device_infos->systemModeBoolean )
     ali::fix_method_in_art(
       env,
       cls1,
       (_jmethodID *)className,
       methodName,
       methodSign,
       *(_jmethodID **)(ali::g_zuma_infos->methodInfo + methodAddr + 8),
       (_jmethodID *)dexAddr1);
   else
     ali::fix_method_in_dalvik(
       env,
       cls1,
       (_jmethodID *)className,
       methodName,
       methodSign,
       (_jmethodID *)(dexAddr1 + *(_DWORD *)(ali::g_zuma_infos->methodInfo + methodAddr + 8)),
       (_jmethodID *)dexAddr1);
   j_free(className);
   j_free(methodName);
   result = (JNIEnv *)j_free(methodSign);
 }
 return result;
}


int __fastcall ali::fix_dalvik_method_struct(ali *this, _JNIEnv *a2, int a3, unsigned int a4)
{
 int v4; // r5
 int v5; // r4
 unsigned __int8 *v6; // r1
 unsigned __int8 *v7; // r1
 int codeOff; // r3
 unsigned __int8 *v9; // r1
 unsigned int v10; // r1
 int result; // r0
 unsigned __int8 *v12; // r1
 unsigned int v13; // r1

 v4 = a3;
 v5 = (int)a2;
 ali::getRegistersSize((ali *)a3, (unsigned __int8 *)a2);
 ali::getOutsSize((ali *)v4, v6);
 codeOff = v4 + 0x10;
 if ( ali::g_device_infos->isYunOs )
 {
   *(_DWORD *)(v5 + 0x18) = codeOff;
   *(_WORD *)(v5 + 0x20) = ali::getRegistersSize((ali *)v4, v7);
   *(_WORD *)(v5 + 0x22) = ali::getOutsSize((ali *)v4, v9);
   result = ali::getAccessFlags((ali *)*(unsigned __int16 *)(v5 + 6), v10);
   *(_WORD *)(v5 + 6) = result;
 }
 else
 {
   *(_DWORD *)(v5 + 0x20) = codeOff;
   *(_WORD *)(v5 + 0xA) = ali::getRegistersSize((ali *)v4, v7);
   *(_WORD *)(v5 + 0xC) = ali::getOutsSize((ali *)v4, v12);
   result = ali::getAccessFlags(*(ali **)(v5 + 4), v13);
   *(_DWORD *)(v5 + 4) = result;
 }
 return result;
}


至此壳的流程基本走完了

分析完可知

header




修复



因为通过上面分析,我们能找到native方法对应的codeoff,所以可以动态写脚本来修复


但是会有一个问题,codeoff可能会超出原来大小,这样dex整个偏移都要变,修复太麻烦,不现实


参考文章 https://bbs.pediy.com/thread-220717.htm


通过修改baksmali源码来修复codeoff


说一下修复思路,源码我就不放出来了


1.通过上面源码分析,还原出gen_dex_info_list、gen_clazz_info_list、gen_method_info_list的代码


2.通过还原出的类,主动去加载所有需要修复的类


3.还原出修复类方法代码start_fix_this_class,由此可以得到codeoff


4.因为codeoff在dex文件中,所以直接在电脑64位系统加载到内存会有问题,我直接把类、方法、签名、codeoff保存到文件中


5.baksmali中去加载保存的文件信息,存到集合中


6.当baksmali反编译时候修复accessflag和codeoff

我分析的样本是之前的,修复脚本最新免费版一样适用







本文由看雪论坛 Roselia  原创

转载请注明来自看雪社区



往期热门阅读:



扫描二维码关注我们,更多干货等你来拿!


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存