源码分析 脱壳神器ZjDroid工作原理
0. 神器ZjDroid
Xposed框架的另外一个功能就是实现应用的简单脱壳,其实说是Xposed的作用其实也不是,主要是模块编写的好就可以了,主要是利用Xposed的牛逼Hook技术实现的,下面就先来介绍一下这个脱壳模块工具ZjDroid的原理,因为他是开源的,所以咋们直接分析源码即可,源码的下载地址:https://github.com/halfkiss/ZjDroid 不过可惜的时候他只公开了Java层的代码,而native层的代码并没有公开,但是分析源码之后会发现最重要的功能就在native层,不过也没关系,等分析到那里的时候我在给大家讲解底层的大致实现方案即可。
1. 源码分析ZjDroid原理(
下面就来详细的分析一下ZjDroid工具的源码吧,他是一个Eclipse工程导入很简单,基于之前的Xposed模块编写的经验,我们知道找到入口代码也很简单,在assets目录下有一个xposed_init文件中就记录了模块的入口类:
然后我们直接进入到这个类查看即可:
看到了,遵循统一规则,实现了IXposedHookLoadPackage接口,实现handleLoadPackage回调方法即可,下面继续分析入口方法ModuleContext的initModuleContext
发现这开始拦截Application的onCreate方法了,而这个方法一般是每个应用程序的启动方法,在这里做拦截操作也是合情合理的,在看看拦截之后做了什么,也就是ApplicationOnCreateHook类的实现:
一个是进程id:
这个作用主要是为了过滤其他应用,只处理本应用的逻辑,因为这个广播发送之后所有的应用都能接收到,但是我们脱壳有时候肯定只是针对于某一个应用,那么只需要在这个应用的广播接收中做处理即可。
一个是命令字符串:这个是为了发送广播可以支持多种功能,后面分析也可以看到的确有很多功能的。
然后这里得到命令之后就开始构造一个命令执行器类,这里用到了设计模式中的命令模式。下面继续看看有哪几种命令执行器类:
在这个方法中就开始分析了这里支持的哪几种命令类,下面来一一分析一下:
第一个命令:dump_dexinfo
获取应用运行时内存中dex的信息:DumpDexInfoCommandHandler
进入方法在详细查看一下:
看到了,这里的实现逻辑还是比较简单的,全部通过反射机制获取每个应用的dex文件对应的DexFile类型对象,这里的工作和我们之前介绍了Android中插件化开发已经很熟悉了,通过应用的默认类加载PathClassLoader类得到DexPathList类,然后在得到具体的DexFile对象即可。这里要说的就是这个dex文件对应的cookie值,这个值非常重要,是后续命令操作的基本信息,他代表的含义就是底层中每个应用的dex文件对应的唯一id值,系统会维护一个map结构来保存这些数据的,系统然后通过这个cookie值来找到对应的dex文件信息的。
命令用法:am broadcast -a com.zjdroid.invoke –ei target [pid] –es cmd '{"action":"dump_dexinfo"}'
这里使用的是命令方式发送一个广播,通过–ei携带目标进程id是一个int类型,通过–es携带命令字符串
第二个命令:dump_dexfile
这个命令也是后续脱壳的重要命令,就是dump出应用内存中的dex文件:DumpDexFileCommandHandler
这里可以看到dump出应用的内存数据,首先得需要传入源应用的dex数据也就是apk文件,这个一般都是存放在/data/app/xxx.apk目录下的,然后就是这里自己构建了一个dump之后的dex文件路径,通过源码查看是在/data/data/xxx/files/dexdump.odex中。接下来继续查看dump的核心代码:

命令用法:am broadcast -a com.zjdroid.invoke –ei target [pid] –es cmd '{"action":"dump_dexfile","dexpath":"*****"}'
注意这里的dexpath参数是代表需要脱壳的dex文件,也就是应用程序文件。
第三个命令:backsmali
这个命令其实是和上面的命令差不多功能,只是这里的命令多了一层操作就是把dex文件转化成smali文件,所以这里不再详细说明了,咋们可以先得到dex文件,然后在通过工具得到smali文件也是可以的。
命令用法:am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”backsmali”,”dexpath”:”*****”}’
注意这里的dexpath参数是代表需要脱壳的dex文件,也就是应用程序文件。而最终生成的smali文件夹是放在/data/data/xxx/smali下面的。
第四个命令:dump_mem
这个命令是用来dump出应用程序运行时内存中指定开始位置和长度的内存块数据的:DumpMemCommandHandler
可惜这个方法也是native层的,但是这个操作就比较简单了,我们知道每个应用运行时的内存地址都在 /proc/[pid]/maps 文件中:
那么查找内存地址,然后在使用memcpy进行内存数据拷贝也是非常简单的。
命令用法:am broadcast -a com.zjdroid.invoke –ei target [pid] –es cmd ‘{“action”:”dump_mem”,”start”:111,”length”:23}’
注意这里的start和length都是十进制的,而不是十六进制的数据格式。
第五个命令:dump_heap
这个命令是可以dump出虚拟机的堆内存信息的,文件可以使用java heap工具进行分析,而对于这个命令我们想一下应该也知道实现逻辑应该是也是在native层的,而且这个代码逻辑应该和上面的那个命令差不多的,但是对于这个命令我还没有想到具体的思路,悲哀呀,如果有了解的同学就告知一下哈!
命令用法:am broadcast -a com.zjdroid.invoke –ei target [pid] –es cmd ‘{“action”:”dump_heap”}’
第六个命令:dump_class
这个命令主要是用于dump出dex文件中的类信息,这个操作也是非常简单的,因为在DexFile对象中有一个隐藏的方法可以把dex文件中的所有类名获取到:getClassNameList
这里可以看到这个方法的传入参数为一个dex文件对应的cookie值。
命令用法:am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”dump_class”,”dexpath”:”*****”}’
这里的dexpath是需要得到所有类信息的dex文件路径,也就是应用的apk文件路径。
第七个命令:invoke
这个命令是用于运行时动态调用Lua脚本,本人并没有看懂这个命令的作用,该功能可以通过Lua脚本动态调用java代码。使用场景:可以动态调用解密函数,完成解密。可以动态触发特定逻辑。代码就不进行分析了,因为我觉得这个命令应该不怎么会使用
命令用法:am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”invoke”,”filepath”:”****”}’
这里的filepath是lua脚本文件的存放路径。
到这里就全部介绍完了ZjDroid的所有命令了,下面还有两个非常重要的打印日志的tag:
第一个:adb logcat -s zjdroid-shell-{package name}
这个tag可以查看上面每个命令执行的结果,便于查看命令执行的状态。
第二个:adb logcat -s zjdroid-apimonitor-{package name}
这个tag可以监听对应包名应用调用的哪些api信息,这个作用有点类似于运行时权限请求的作用。这个做起来就非常简单了,可以直接通过Xposed提供的方法进行系统的一些敏感api进行拦截然后添加监控代码即可。
三、命令总结
上面就从源码的角度完全分析完了ZjDroid工具的功能了,下面就来总结一下:
1、获取APK当前加载DEX文件信息
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”dump_dexinfo”}’
2、获取指定DEX文件包含可加载类名
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”dump_class”,”dexpath”:”*****”}’
3、根据Dalvik相关内存指针动态反编译指定DEX,并以文件形式保存
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”backsmali”,”dexpath”:”*****”}’
4、Dump指定DEX内存中的数据并保存到文件(数据为odex格式,可在pc上反编译)
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”dump_dexfile”,”dexpath”:”*****”}’
5、Dump指定内存空间区域数据到文件
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”dump_mem”,”start”:1234567,”length”:123}’
6、Dump Dalvik堆栈信息到文件,文件可以通过java heap分析工具分析处理
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”dump_heap”}’
7、运行时动态调用Lua脚本
该功能可以通过Lua脚本动态调用java代码。使用场景:可以动态调用解密函数,完成解密。可以动态触发特定逻辑。
am broadcast -a com.zjdroid.invoke –ei target pid –es cmd ‘{“action”:”invoke”,”filepath”:”****”}’
8、相关命令执行结果查看
1、命令执行结果
adb shell logcat -s zjdroid-shell-{package name}
2、敏感API调用监控输出结果
adb shell logcat -s zjdroid-apimonitor-{package name}
3、总结
好了,到这里我们就讲解完了基于Xposed框架的脱壳神器ZjDroid的实现原理以及具体用法。而这里也感受到了Xposed框架的强大之处,当然这也只是一部分,后面还可以利用这个框架编写游戏外挂等操作。
4、源码
附件列表
源码分析 脱壳神器ZjDroid工作原理的更多相关文章
- zookeeper源码分析(一) 工作原理
来自:http://www.codedump.info/?p=207 阅读zookeeper代码一段时间(注:是很长一段时间,断断续续得有半年了吧?)之后,我要开始将一些积累下来的东西写下来了,鉴于我 ...
- Spring IOC 容器源码分析 - 余下的初始化工作
1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...
- 并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理
1. AQS共享模式 前面已经说过了AQS的原理及独享模式的源码分析,今天就来学习共享模式下的AQS的几个接口的源码. 首先还是从顶级接口acquireShared()方法入手: public fin ...
- Guava 源码分析之Cache的实现原理
Guava 源码分析之Cache的实现原理 前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Goog ...
- 从SpringBoot源码分析 配置文件的加载原理和优先级
本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级 跟入源码之前,先提一个问题: SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
- ABP源码分析九:后台工作任务
文主要说明ABP中后台工作者模块(BackgroundWorker)的实现方式,和后台工作模块(BackgroundJob).ABP通过BackgroundWorkerManager来管理Backgr ...
- Spring5深度源码分析(三)之AnnotationConfigApplicationContext启动原理分析
代码地址:https://github.com/showkawa/spring-annotation/tree/master/src/main/java/com/brian AnnotationCon ...
- MyBatis源码分析(2)—— Plugin原理
@(MyBatis)[Plugin] MyBatis源码分析--Plugin原理 Plugin原理 Plugin的实现采用了Java的动态代理,应用了责任链设计模式 InterceptorChain ...
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...
随机推荐
- Azure 项目构建 – 构建和部署 .NET 应用程序
本课程主要介绍了如何在 Azure 平台上快速构建和部署基于 .NET 语言的 Web 应用, 实践讲解如何使用 Azure 门户创建 Web 应用, 部署 ASP.NET 代码, 连接 Azure ...
- codevs 1487 大批整数排序(水题日常)
时间限制: 3 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description !!!CodeVS开发者有话说: codevs自从换了评测机,新评测机的内存计算 ...
- cmake 指定输出目录
$ mkdir ~/cpp-netlib-build $ cd ~/cpp-netlib-build $ cmake -DCMAKE_BUILD_TYPE=Debug \ > -DCMAKE_C ...
- ThinkPHP5.0-多语言切换
这两天做得项目中需要多语言切换,于是乎就看了看文档,感觉有些乱,就使用了终极必杀--百度. 借鉴了网上各位大佬所集成.整理出一篇比较适合类似我这种比较菜的随笔吧. 请各位大佬轻虐.感谢. 首先,不说其 ...
- touch-action css属性 滚动和缩放手势
CSS 属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动,缩放等) 默认情况下,平移(滚动) 和 缩放手势由浏览器专门处理.该属性用于 ...
- 【贪心】bzoj1572: [Usaco2009 Open]工作安排Job
先是没怎么理解这个贪心……然后贪心又被细节弄挂…… Description Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. ...
- RN调试
https://facebook.github.io/react-native/docs/debugging.html 热加载 RN的目标是极致的开发体验,修改文件后能在1秒内看到变化,通过以下三个特 ...
- mysql 慢查询日志 mysqldumpslow 工具
文章来源:https://www.cnblogs.com/hello-tl/p/9229676.html 1.使用Mysql慢查询日志配置 查看慢查询日志是否开启 OFF关闭 ON开启 show va ...
- dbfread报错ValueError错误解决方法
问题 我在用dbfread处理.dbf数据的时候出现了报错 ValueError("could not convert string to float: b'.'",) 然后查找. ...
- 几条sql语句(exists)
通常exists后的子查询是需要和外面的表建立关联关系的,如 select count(*) from a where exists (select 'x' from b where a.id = b ...

附件列表
源码分析 脱壳神器ZjDroid工作原理的更多相关文章
- zookeeper源码分析(一) 工作原理
来自:http://www.codedump.info/?p=207 阅读zookeeper代码一段时间(注:是很长一段时间,断断续续得有半年了吧?)之后,我要开始将一些积累下来的东西写下来了,鉴于我 ...
- Spring IOC 容器源码分析 - 余下的初始化工作
1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...
- 并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理
1. AQS共享模式 前面已经说过了AQS的原理及独享模式的源码分析,今天就来学习共享模式下的AQS的几个接口的源码. 首先还是从顶级接口acquireShared()方法入手: public fin ...
- Guava 源码分析之Cache的实现原理
Guava 源码分析之Cache的实现原理 前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Goog ...
- 从SpringBoot源码分析 配置文件的加载原理和优先级
本文从SpringBoot源码分析 配置文件的加载原理和配置文件的优先级 跟入源码之前,先提一个问题: SpringBoot 既可以加载指定目录下的配置文件获取配置项,也可以通过启动参数( ...
- ABP源码分析九:后台工作任务
文主要说明ABP中后台工作者模块(BackgroundWorker)的实现方式,和后台工作模块(BackgroundJob).ABP通过BackgroundWorkerManager来管理Backgr ...
- Spring5深度源码分析(三)之AnnotationConfigApplicationContext启动原理分析
代码地址:https://github.com/showkawa/spring-annotation/tree/master/src/main/java/com/brian AnnotationCon ...
- MyBatis源码分析(2)—— Plugin原理
@(MyBatis)[Plugin] MyBatis源码分析--Plugin原理 Plugin原理 Plugin的实现采用了Java的动态代理,应用了责任链设计模式 InterceptorChain ...
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...
随机推荐
- Azure 项目构建 – 构建和部署 .NET 应用程序
本课程主要介绍了如何在 Azure 平台上快速构建和部署基于 .NET 语言的 Web 应用, 实践讲解如何使用 Azure 门户创建 Web 应用, 部署 ASP.NET 代码, 连接 Azure ...
- codevs 1487 大批整数排序(水题日常)
时间限制: 3 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description !!!CodeVS开发者有话说: codevs自从换了评测机,新评测机的内存计算 ...
- cmake 指定输出目录
$ mkdir ~/cpp-netlib-build $ cd ~/cpp-netlib-build $ cmake -DCMAKE_BUILD_TYPE=Debug \ > -DCMAKE_C ...
- ThinkPHP5.0-多语言切换
这两天做得项目中需要多语言切换,于是乎就看了看文档,感觉有些乱,就使用了终极必杀--百度. 借鉴了网上各位大佬所集成.整理出一篇比较适合类似我这种比较菜的随笔吧. 请各位大佬轻虐.感谢. 首先,不说其 ...
- touch-action css属性 滚动和缩放手势
CSS 属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动,缩放等) 默认情况下,平移(滚动) 和 缩放手势由浏览器专门处理.该属性用于 ...
- 【贪心】bzoj1572: [Usaco2009 Open]工作安排Job
先是没怎么理解这个贪心……然后贪心又被细节弄挂…… Description Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. ...
- RN调试
https://facebook.github.io/react-native/docs/debugging.html 热加载 RN的目标是极致的开发体验,修改文件后能在1秒内看到变化,通过以下三个特 ...
- mysql 慢查询日志 mysqldumpslow 工具
文章来源:https://www.cnblogs.com/hello-tl/p/9229676.html 1.使用Mysql慢查询日志配置 查看慢查询日志是否开启 OFF关闭 ON开启 show va ...
- dbfread报错ValueError错误解决方法
问题 我在用dbfread处理.dbf数据的时候出现了报错 ValueError("could not convert string to float: b'.'",) 然后查找. ...
- 几条sql语句(exists)
通常exists后的子查询是需要和外面的表建立关联关系的,如 select count(*) from a where exists (select 'x' from b where a.id = b ...