首页
论坛
专栏
课程

某壳分析+修复(二)

Editor 发布于 看雪学院 2018-05-14 18:05

声明

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

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


Java层分析

快分析完才想起打算用art模式分析的,那就分析下一个壳用art模式分析把

这个是dalvik模式,nexus5 4.4.4

逻辑比较简单,主要是加载libSecShell.so,和替换原APP的Application,Helper.h的native方法是对华为手机一些设置,手里没有华为手机具体native没有分析


java层有一个DexInstall类,Native层会通过jni方法调用install(ClassLoader loader, String dex_path, String dexDir)方法

一直往下分析,此方法主要作用就是把Native层解密的dex通过反射调用makeDexElements方法把生成的Element数组加入到dexElements数组中





具体过程可以参考android源码

https://www.androidos.net.cn/android/4.4.4_r1/xref/libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java

https://www.androidos.net.cn/android/4.4.4_r1/xref/libcore/dalvik/src/main/java/dalvik/system/DexPathList.java


Native方法分析

通过查看.init_array和.finit_array段没有做具体内容,解密方法应该放在了JNI_OnLoad中,一看就是经过llvm混淆过,正常代码怎么会有这种逻辑


f5看一眼,能正常反编译,大体扫一眼逻辑还是可以接受的没那么变态,发现字符串都被加密了,部分方法也被加密了

只能动态分析了,具体就不帖代码了,最后我会把分析的so文件分享给大家


JNI_OnLoad 4.4.4 dalvik流程,这里的反调试并不影响我们分析这个,反调试具体代码我没有分析,感兴趣的可以分析一遍



Jar解密方法,有兴趣的可以还原下,那样直接把apk的jar解密直接解压就是原apk的dex文件


unsigned int __fastcall sub_25C90(unsigned int result, _BYTE *a2, int jarBuff)

{

int v3; // r1

int v4; // r3

unsigned int v5; // r3

int v6; // r6

int v7; // r5

char v8; // r2

int v9; // r4

int v10; // r3

int v11; // r7

_BYTE *v12; // r6

int v13; // r4

_BYTE *v14; // r1

int v15; // [sp+0h] [bp-138h]

unsigned int v16; // [sp+4h] [bp-134h]

_BYTE *v17; // [sp+8h] [bp-130h]

int v18; // [sp+10h] [bp-128h]

char v19[256]; // [sp+1Ch] [bp-11Ch]

v17 = a2;

v16 = result;

v15 = jarBuff;

v3 = 0;

if ( result <= 0x1FFFF )                      // result=0

{

v3 = 0x20000 - result;

if ( (signed int)(0x20000 - result) > jarBuff )

v3 = jarBuff;

v15 = jarBuff - v3;

if ( v3 > 0 )

{

v18 = dword_53C70;

v4 = 0;

do

{

v19[v4] = v4;

++v4;

}

while ( v4 != 256 );

v5 = 0;

v6 = 0;

v7 = 0;

do

{

v6 = (*(unsigned __int8 *)(v18 + v5) + (unsigned __int8)v19[v7] + v6) & 0xFF;

v8 = v19[v7];

v5 = (v5 + 1) & -((v5 + 1 <= 0xF) + ((v5 + 1) >> 31));

v19[v7] = v19[v6];

v19[v6] = v8;

++v7;

}

while ( v7 != 256 );

v9 = 0;

result = 0;

v10 = 0;

while ( v9 != v16 )

{

v10 = (v10 + 1) & 0xFF;

v11 = (unsigned __int8)v19[v10];

++v9;

result = (v11 + result) & 0xFF;

v19[v10] = v19[result];

v19[result] = v11;

}

v12 = v17;

do

{

v10 = (v10 + 1) & 0xFF;

v13 = (unsigned __int8)v19[v10];

result = (result + v13) & 0xFF;

v19[v10] = v19[result];

v19[result] = v13;

*v12++ ^= v19[(v13 + (unsigned __int8)v19[v10]) & 0xFF];

}

while ( v12 != &v17[v3] );

}

}

if ( v15 > 0 )

{

v14 = &v17[v3];

result = (unsigned int)v14;

do

*v14++ ^= 0xACu;

while ( (signed int)&v14[-result] < v15 );

}

return result;

}


脱壳dump

壳只是把原dex加密放到了secData0.jar中,所以直接拿到dex,修复AndroidManifest的application重打包完美运行

dump方法比较多,列举几个方法

1.通过还原加密算法,解密secData0.jar,直接解压解密jar就是原dex(不推荐这种方法,虽然方便,但算法更新太快)

2.壳保存在.cache的classes.dex是加密的,主要通过hook实现,打开时解密,关闭时候加密。

壳hook了open和mmap方法,这里下断得到的dex是解密的dex即原dex(调用open,mmap方法可能不只是打开dex,通过文件大小可以筛选出来)

3.在解密jar函数下断点,执行完得到解密jar,dump出解密jar,解压出dex

4.壳hook了dvmRawDexFileOpen,在这里下断点,得到的dex是解密的dex即原dex(比较推荐这种)


提醒

1.idb用的ida7.0保存的

2.给switch下断点注意,一级下的switch,如果没执行到一级的switch直接下断点可能会失败(不知道是ida问题还是?)


总结

别被JNI_OnLoad的流程给唬住,静下心来分析还是挺简单的。

感觉这种内存加载dex安全性还是挺低的,只要分析出关键代码dump出原dex那就是分分钟的事,连修复都不用。


本文由看雪论坛 Roselia  原创

转载请注明来自看雪社区



分享到:
最新评论 (0)
登录后即可评论
上一篇:NEC将打造大型犯罪侦查生物识别系统 下一篇:微软在Windows 10每次更新后都会重新安装用户不需要的软件和游戏