android脱壳第二发:grpc-dumpdex加修复

上一篇我写的dex脱壳,写到银行类型的app的dex修复问题,因为dex中被抽取出来的函数的code_item_off 的偏移所在的内存,不在dex文件范围内,所以需要进行一定的修复,然后就停止了。本来不打算接着搞得,但是写了个框架总得有点真正实用的东西。

内存中所有dex遍历

我们所要做的是脱壳,即找到保护的dex,有些dex直接在当前classloader中,有些是自定义classloader然后加载的dex,所以如何找到所有的classloader那,java代码可是没有提供过这种功能。但是frida提供了这种功能,通过符号导出调用虚拟机底部函数对所有类进行遍历(这个不多写了,以前写过)

jobjectArray getClassLoaders(JNIEnv *env, jint targetSdkVersion) {

|-------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | JavaVM ``*``javaVM; env``-``>GetJavaVM(&javaVM); JavaVMExt ``*``javaVMExt ``= (JavaVMExt ``*``) javaVM; void ``*``runtime ``= javaVMExt``-``>runtime; LOGV(``"runtime ptr: %p, vmExtPtr: %p"``, runtime, javaVMExt); LOGV(``"std::unique_ptr<PartialRuntime13> size: %d"``, sizeof (std::unique_ptr<PartialRuntime13>)); LOGV(``"get_heap_to_jvm_offset size: %d"``, get_heap_to_jvm_offset()); const ``int MAX = 5000``; int offsetOfVmExt ``= findOffset(runtime, ``0``, ``MAX``, (void``*``) javaVMExt); LOGV(``"offsetOfVmExt: %d"``, offsetOfVmExt); int head_offset ``= offsetOfVmExt``-``get_heap_to_jvm_offset()``+``sizeof (void``*``); LOGV(``"head_offset: %d"``, head_offset); void ``* heap ``= (char``*``)runtime ``+ head_offset; AndroidRunAPI``* androidRunApi ``= AndroidRunAPI::getInstance(); LOGV(``"1"``); androidRunApi``-``>partialRuntime ``= static_cast<PartialRuntime ``*``>(heap); getAndroidSystemFunction(); LOGV(``"1"``); LookupClassesVisitor visitor(env, javaVMExt); LOGV(``"1 %p"``,androidRunApi``-``>VisitClassLoaders); androidRunApi``-``>VisitClassLoaders(androidRunApi``-``>partialRuntime``-``>class_linker_,&visitor); LOGV(``"1"``); std::vector<jobject> vectorObject ``= visitor.getVecObj(); jclass ClassLoader_cls ``= env``-``>FindClass(``"java/lang/ClassLoader"``); LOGV(``"2"``); for (auto it ``= vectorObject.begin(); it !``= vectorObject.end(); ``/``* no increment here ``*``/``) { ``jboolean re ``= env``-``>IsInstanceOf(``*``it,ClassLoader_cls); ``if``(!re){ ``it ``= vectorObject.erase(it); ``} ``else``{ ``+``+``it; ``} } jobjectArray objectArray ``= env``-``>NewObjectArray(vectorObject.size(), ClassLoader_cls, NULL); for``(``int i``=``0``;i<vectorObject.size();i``+``+``){ ``env``-``>SetObjectArrayElement(objectArray, i, vectorObject[i]); } return objectArray; |

}

我们能遍历系统中所有的类,找到所有类加载,然后通过类加载器找到dex文件(有些cdex文件是系统文件)

用smali开源项目修dex code_item_off错误的文件

越来越懒了,不想多bb了,本来还想多写点扫盲和基础知识点的,懒得写了,直接上才艺。

就上个图片这里,dex文件的code_item 是超过了文件大小的,对于这种是没有办法修复的

花了半个月将grpc项目修了一下

连接和使用方式跟以前一样,但是具体的代码在test中

● dumpDexFixCodeItem

从内存中dump dex的codeitem形成修复文件,传入baksmali中作为修复参数

● dumpDexToPC 直接dumpdex 到本地目录

直接将dex dump到电脑上体验一站式dexdump

● dumpDexToAndroidLocal

dumpdex到android上,因为太大的apk中,dex文件过大内存直接爆了比如银行。

● baksmali

调用的smali,传入dex和需要修的codeitem可以将dex反编译成smali,然后将codeitem 也反编译进去

● smali

将 baksmali 编译出来的 smali工程编译为dex

使用顺序

● 使用dumpDexToPC 和 dumpDexToAndroidLocal 向dump dex文件

● 使用dumpDexFixCodeItem dump dex文件的code_item 到修复文件中

● 使用baksmali 传入dex文件和 code_item 修复文件反编译为smali工程

● 使用smali 将smali 工程反编译为dex

效果图

这个上次的文章中某银行dex最终的修复结果

使用中存在的问题

● dump出来的dex文件格式有问题:可能是cdex文件,也有可能是dex文件格式已经被破坏,如果是dex文件格式被破坏,可以通过自己编写更早时期的dex加载时dump来找到dex文件

● dumpDexToPC 导致程序崩溃了,这是因为文件太大内存爆满了,用dumpDexToAndroidLocal 手动去下载吧。

● 修复失败,修完了以后函数仍然找不到,我目前是用的是类加载,如果抽取函数是通过类加载还原的,这种方式是可以dump出code_item的,如果函数是通过必须要执行函数实体一次才能还原的话,这个可能需要你想办法让函数执行,并且确保被抽取的函数已经还原了,没有再次加密回去。

● baksmail 反编译中会剥离调试信息,参数名。smali回编译经过修改会忽略某些函数没有执行实体的错误。

废话

相比fart还是差了半截,活太多了只能先到这,不过比fart优雅多了,毕竟优雅永不过时

future

如果你想接着研究,但是又不知道该怎么继续研究下去,不知道我这个方向是不是死胡同,那我给点建议。

● 修复,如果逆向继续研究修复,用smali编译来编译去优雅程度还是有所欠缺的,而且我写的不完善要一个类一个类的还原,这方面我建议去看看dexmaker这类动态生成dex的源码,在内存中动态生成dex进行修复,或者android源码dex优化部分(我在调试dump debug模式的dex的时候发现dex和apk安装中的dex是不太一样的,查了一下说是优化了)

● dump dex,我目前采用的是程序运行中间dump,这个时候dex容易被破坏,可以hook开始的位置dumpdex

● dump code item ,这个是个坑,如果是函数运行一次还原还好一点,但是我不太确定是否有非常恶心的那些,比如不断覆盖重复运行,或者运行完再次加密,只要他能牺牲效率什么都做得出来,自己保重。

相关推荐
ac-er88882 小时前
Yii框架中的队列:如何实现异步操作
android·开发语言·php
流氓也是种气质 _Cookie4 小时前
uniapp 在线更新应用
android·uniapp
zhangphil6 小时前
Android ValueAnimator ImageView animate() rotation,Kotlin
android·kotlin
徊忆羽菲6 小时前
CentOS7使用源码安装PHP8教程整理
android
编程、小哥哥7 小时前
python操作mysql
android·python
Couvrir洪荒猛兽8 小时前
Android实训十 数据存储和访问
android
五味香10 小时前
Java学习,List 元素替换
android·java·开发语言·python·学习·golang·kotlin
十二测试录11 小时前
【自动化测试】—— Appium使用保姆教程
android·经验分享·测试工具·程序人生·adb·appium·自动化
Couvrir洪荒猛兽12 小时前
Android实训九 数据存储和访问
android
aloneboyooo13 小时前
Android Studio安装配置
android·ide·android studio