参考资料:
https://bbs.pediy.com/thread-261939.htm#msg_header_h1_3 各代壳实现的介绍
https://bbs.pediy.com/thread-260251.htm 早期代码抽取壳入门, 了解指令抽取壳的大概流程。
https://bbs.pediy.com/thread-271362.htm 乐固分析
总结3个技术点
- application 的转移。
- dex 文件加载。
- 定位被抽取目标字节码并还原。
三个重要函数
sub_C9E0 ,通过oat文件获取到加固对象的dex数据。
sub_6DC0 , 还原原始的指令。
sub_5800 , application的替换。
函数分析
sub_C9E0
- info+149:当前系统 SDK 版本
- info+151:系统虚拟机,值为1时是 Dalvik 虚拟机,值为2时是 Art 虚拟机
- info+129:变量 WrapperProxyApplication.baseContext,壳 apk 的 context
- info+130:变量 WrapperProxyApplication.baseContext.mPackageInfo
- info+131:变量 WrapperProxyApplication.baseContext.mPackageInfo.mActivityThread 当前 Activity 线程
- info+132: 获取了某个类的的mBoundApplication字段的providers字段,并重新设置了字段。
- info+133:类 com/wrapper/proxyapplication/WrapperProxyApplication
- info+166:MethodID,com/wrapper/proxyapplication/WrapperProxyApplication->init()
- info+134:类 dalvik/system/DexFile
- info+135:变量 WrapperProxyApplication.shellApp,壳的 Application
- info+138:变量 壳的ClassLoader
- info+150:机器架构 值为1时是 arm 架构,值为3时是 x86 架构。
- info+145: /data/data/com.tencent.qqpimsecure.sc/files/prodexdir/o0oooOO0ooOo.dat文件隐射起始地址
- info+147: 文件大小?????
- info+152: 保存加固App的Dex文件数量
很好奇,作者说这个info+161 保存Dalvik_dalvik_system_DexFile_openDexFile_bytearray ,dlsym 获取的dvm_dalvik_system_DexFile 的符号地址。
模拟器中没有拿到libdvm.so , 有缘再看
sub_B110
- sub_B800 获取到oat文件名称
- sub_8D10 从内存中获取到oat文件的起始地址和终止地址
- sub_AD10 获取到Dex的内存地址
返回壳Dex文件在内存中的地址。
sub_B960
- 解压被抽取的dex文件
sub_58000
- 反调试、证书校验
- 加载dex,并还原指令
- 4f80,对fstat 、mmap 和munmap 进行hook。???为什么要hook他呢 哦哦 似乎要做内存加载dex的操作。
- 6DC0 抽取指令还原。
Application 替换
嗯 ,跟了简单的流程,还是有些疑问。android壳的结构,
- 壳程序
- 加壳工具
- 加壳对象
加壳工具 ,将对象进行执行抽取,修改相关application的入口为壳程序;壳程序启动时将对象的指令进行还原后,完成相关application的替换将程序流还给加壳对象。
疑问1;从文章的说明来说,被抽取的对象从oat文件中提取,能不能改为从dex文件中或APK文件中提取?猜测可以
惊叹1:application的替换仅需要做相关字段的替换就行了???那这几个的字段是什么意义??我要是自己实践下应该也是可以的。
通过调试再跟踪一遍呗,整体跟踪到了,细节还没有get到。
JNI_OnLoad {
注册两个native函数
sub_C9E0 初始化需要使用的变量,壳的context 、application、classLoader、获取oat地址、提取被抽取的dex地址
sub_9E40 获取API level
sub_98E0 获取/data/data/..../files 目录
创建/data/data/.../files/prodexdir 目录
sub_1C540 反调试,先跳过反调试的内容
sub_4A10 证书校验,也先跳过
sub_5800 作者说重要的操作{
sub_8860 悄咪咪的又注册了一个native函数defineClassNative(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Object;)Ljava/lang/Class;sub_8600
sub_4F80 重要操作,{
做了got表hook来完成内存加载dex文件?内存加载又为什么需要hook这三个函数(fstat , mmap ,unmap)?
反射调用java层,com.wrapper.proxyapplication.MultiDex的installdex方法。
}
sub_6DC0 被抽取指令还原。
application应用替换。
}
}
调试用命令
adb shell am start -D com.tencent.qqpimsecure.sc/.MainView adb shell "ps | grep tencent | awk '{print $2}'" # 获取目标进程 jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700 breakpoint set --func-regex do_dlopen p/x *(char **)($esp+4) b *0xbc258720 j *0xBC258CD1
0 条评论