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

相关推荐
锋风Fengfeng1 小时前
安卓15预置第三方apk时签名报错问题解决
android
User_undefined2 小时前
uniapp Native.js原生arr插件服务发送广播到uniapp页面中
android·javascript·uni-app
程序员厉飞雨3 小时前
Android R8 耗时优化
android·java·前端
丘狸尾4 小时前
[cisco 模拟器] ftp服务器配置
android·运维·服务器
van叶~6 小时前
探索未来编程:仓颉语言的优雅设计与无限可能
android·java·数据库·仓颉
Crossoads10 小时前
【汇编语言】端口 —— 「从端口到时间:一文了解CMOS RAM与汇编指令的交汇」
android·java·汇编·深度学习·网络协议·机器学习·汇编语言
li_liuliu11 小时前
Android4.4 在系统中添加自己的System Service
android
C4rpeDime13 小时前
自建MD5解密平台-续
android
鲤籽鲲15 小时前
C# Random 随机数 全面解析
android·java·c#
m0_5485147719 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php