参考资料:

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个技术点

  1. application 的转移。
  2. dex 文件加载。
  3. 定位被抽取目标字节码并还原。

三个重要函数

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壳的结构,

  1. 壳程序
  2. 加壳工具
  3. 加壳对象

加壳工具 ,将对象进行执行抽取,修改相关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

针对内存加载的猜测

添加dex文件的加载列表和cookie , 然后劫持dex文件的内存数据实现,内存加载。

pareto

未来什么方向不管,先做自己喜欢做的事情。

0 条评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注