同步操作将从 裤头将军/xposedhooktool 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
Android 破解的hook工具,集成一些帮助破解的常用功能,如自动网络抓包、网络堆栈爆破、文件日志、webview调试环境
入口在 com.virjar.xposedhooktool.hotload.XposedInit,但是该入口代码非常不建议修改
在xposed原生的回调钩子函数注册流程中,需要在合适的实际寻找到Class对象(或者classloader+className)。然后使用xposedApi注入钩子函数,这个合适时机非常难以把握。 对于一个没有加壳的,单dex apk来说,一般可以直接使用宿主apk的classloader来加载钩子函数。 但是对于有壳的apk,或者运行时构建的classloader来说,我们并不容易寻找到一个合适的方式定位到classloader(这包括如何找到他,以及如何尽可能早的找到他),如果无法找到class,那么肯定无法注册钩子函数。如果找到的时机过晚,那么可能注册钩子函数的时候,需要观察的逻辑已经发生了。
我提供了一个方案,可能在Class被加载到虚拟机的时候,马上触发我们的回调函数,可以在第一时间感知一个class的定义。使用api也很简单
//test to use class load monitor
ClassLoadMonitor.addClassLoadMonitor("com.huicent.ui.FlightQueryActivity", new ClassLoadMonitor.OnClassLoader() {
@Override
public void onClassLoad(Class clazz) {
Log.i("weijia", "load class: " + clazz.getName());
}
});
只需要传递一个代表class全称限定的className,即可实现对class初始化的拦截,无需关心这个class是何时何地被定义。
我们在分析网络请求的时候,有自顶向下和自底向上两种分析路径。但是自底向上分析经常由于异步任务的原因导致堆栈断层。因为堆栈dump是基于线程的。很多业务都是在ui线程触发事件,准备数据,加解密。然后异步发送网络请求,当我们关心网络请求的时候,常常在网络出口(socket)dump线程堆栈,进而分析业务逻辑调用链。这个时候异步掐断了堆栈,所以我提供了线程堆栈跟踪功能,任何时候,只要你通过我提供的api输出堆栈。我将会输出从主线程到网络线程之间的线程跳跃堆栈。
=============>
com.virjar.xposedhooktool.tool.okhttp.ThreadPoolHook.stackTraceChain:31
com.virjar.xposedhooktool.tool.log.LogUtil.getTrack:167
com.virjar.xposedhooktool.tool.log.LogUtil.outTrack:162
com.virjar.xposedhooktool.tool.socket.NetDataPrinter$5.beforeHookedMethod:359
de.robv.android.xposed.XposedBridge.handleHookedMethod:340
com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream:-1
org.apache.http.impl.io.SocketInputBuffer.<init>:75
org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer:88
org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer:175
org.apache.http.impl.SocketHttpClientConnection.bind:111
org.apache.http.impl.conn.DefaultClientConnection.openCompleted:134
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection:177
org.apache.http.impl.conn.AbstractPoolEntry.open:169
org.apache.http.impl.conn.AbstractPooledConnAdapter.open:124
org.apache.http.impl.client.DefaultRequestDirector.execute:370
org.apache.http.impl.client.AbstractHttpClient.execute:560
org.apache.http.impl.client.AbstractHttpClient.execute:492
org.apache.http.impl.client.AbstractHttpClient.execute:470
com.hkairlines.apps.BaseActivity.e:2148
com.hkairlines.apps.BaseActivity.a:163
com.hkairlines.apps.BaseActivity$46.run:2128
com.virjar.xposedhooktool.tool.okhttp.ThreadPoolHook$RunnableMonitor.run:129
java.lang.Thread.run:818
cause parent submit task stack entry
com.virjar.xposedhooktool.tool.okhttp.ThreadPoolHook$2.beforeHookedMethod:77
de.robv.android.xposed.XposedBridge.handleHookedMethod:340
java.lang.Thread.create:-1
java.lang.Thread.<init>:215
com.hkairlines.apps.BaseActivity.d:2125
com.hkairlines.apps.BaseActivity.onStart:281
android.app.Instrumentation.callActivityOnStart:1238
android.app.Activity.performStart:6374
android.app.ActivityThread.performLaunchActivity:2446
android.app.ActivityThread.handleLaunchActivity:2543
android.app.ActivityThread.access$1000:156
android.app.ActivityThread$H.handleMessage:1407
android.os.Handler.dispatchMessage:102
android.os.Looper.loop:157
android.app.ActivityThread.main:5653
java.lang.reflect.Method.invoke:-2
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run:746
com.android.internal.os.ZygoteInit.main:636
de.robv.android.xposed.XposedBridge.main:107
<================
上面是某航空公司航班报价查询堆栈拦截,可以看到在,在activity启动的时候,触发航班列表查询,其代码地址是:com.hkairlines.apps.BaseActivity.d:2125
&&com.hkairlines.apps.BaseActivity.onStart:281
而且使用的是异步线程,这个时候新建了一个线程,并且在新线程中访问网络,而最终网络发出点为:com.hkairlines.apps.BaseActivity.e:2148
本工具环境绕过了xposed插件更新需要重启Android设备的限制,关于xposed热加载网上有一些方案: 如:https://github.com/githubwing/HotXposed 和 https://github.com/liuyufei/hotposed 但是我觉得这两个都有一些不方便的地方,而且还存在权限的风险(她们都借助sdcard和热发代码通信,但是宿主进程可能没有sdcard权限,这样加载热发代码会报错) 她们都需要双apk配合,用来隔离插件和基座,第二个还需要删除原插件xposed入口,使插件变成热加载插件的插件
使用我们这个热加载没有这么麻烦,hotload模块的设计和xposed本身类似。只需要在/assets/hotload_entry.txt中配置入口,即可正常实现热加载。 hotload模块实现类不再是de.robv.android.xposed.IXposedHookLoadPackage,为了避免混淆,我提供了新的入口com.virjar.xposedhooktool.hotload.XposedHotLoadCallBack,当然xposed原始代码很容易迁移。因为参数在com.virjar.xposedhooktool.hotload.SharedObject都有 com.virjar.xposedhooktool.hotload.XposedHotLoadCallBack需要实现两个函数。needHook和onXposedHotLoad,其中needHook是判断当前的apk宿主是否需要被hook,onXposedHotLoad是真正的hook业务代码
SharedObject是一个静态资源存储类,存放了几个重要的环境参数,他是环境隔离的,因为他是自定义classloader加载的,classloader不同,对应的静态对象其实是不相同的 SharedObject包含的参数如下:
public static ClassLoader masterClassLoader;//宿主进程的classloader,如果需要通过反射的方式获取宿主进程里面的class,则需要使用这个类
public static ClassLoader pluginClassLoader;//插件本身的classloader,他可以访问xposed框架的类,以及插件代码的类,一般作用不大。因为插件代码就是他加载的,我们可以通过任何插件代码的class对象获取到这个classloader
public static Context context;//宿主的上下文,可以通过他访问宿主的资源数据等,
public static String pluginApkLocation;//插件代码本身的安装路径,如果需要访问插件自己的资源,可以通过这个路径找到自己(回答我是谁的问题,因为插件寄生在宿主,他是以宿主的身份执行。所以对进程来说,自己不是自己)
public static XC_LoadPackage.LoadPackageParam loadPackageParam;//xposed原生的package load事件的回调参数,使用过xposed的人对这个应该不陌生
热加载代码回调时机是Application的attach的时候,他在xposed 提供的回调loadpackageParam之后,也就是说,如果你要hookpackage load和Application attach之间的流程的话,本工具是不支持的。 支持很麻烦,这样我需要去hook Android内部代码,但是内部代码容易发生api变动,适配各个版本的api的工作很不好做。不过Application attach本身也是在apk启动前面执行的,所以hook一般的apk业务流程完全没有问题
DroidSword是我在了解热加载方案的时候,发现作者的另一个项目。看了一下描述感觉满满的黑科技,但是代码是kotlin写的,没有学过kotlin所以看了看用java实现了一份,然后移植到了工具内部(想想当年写Android程序的时候,官方ide是eclipse,市面上的Android手机版本长时间2.3。真是岁月蹉跎。技术变化速度真的难让人追上,就像一个你喜欢的姑娘,眼看着离你越来越远---越来越远-----!) 原作者项目地址:https://github.com/githubwing/DroidSword
不需要做任何配置,DroidSword插件会默认在hook的apk的界面上面附加一个浮层,上面显示当前activity信息,如果点击了某些控件,还会尝试寻找这些控件的名称、回调函数。 如果觉得界面显示不好看,还可以通过日志查看。每当浮层数据刷新时,数据还会同时在日志中打印一次(打印方式是标准日志,也就是可以通过logcat过滤日志的方式查看)。
虽然我觉得不需要关闭DroidSword,但是如果真的要关闭的话,注释掉代码里面 com.virjar.xposedhooktool.hotload.HotLoadPackageEntry.entry
中开启DroidSword的逻辑即可
顺便说一句,默认组件都是可以在这里关闭的。当然我没有提供配置入口来关闭,修改框架默认策略目前都是对代码的修改
如果你在Android studio编译该项目,请关闭Android studio的Instant Run功能。xposed本身也是不支持Instant Run的
Updated to the official Xposed v85:
Fixed frequent boot freezes, especially with modules that access many files (details)
Built-in way to get a full logcat (details)
Crashes not related to Xposed/ART are no longer written to the normal Xposed logs
On encrypted devices with boot password, the password prompt is now shown quicker
Warning for developers to disable "Instant Run" in Android Studio, otherwise the module can't be loaded
6.0 only: Cherry-picked some ART commit included in CyanogenMod and other ROMs
6.0 only: Forced clearing Dalvik cache when upgrading from versions before 85 (would have been necessary for 84 and might have caused some boot loops)
所以如果你开启了Instant Run
,Xposed将不会加载插件,当然本工具也不会去加载她。关闭方案:
不支持Instant Run
的原因是,Instant Run
本身也是一个热加载框架,他将我们的apk代码当做了资源,然后使用PathClassLoader动态加载代码,实现代码的局部热替换,
开启Instant Run
后,Xposed框架和本框架所能够识别到的代码是Instant Run
框架,而非我们的插件代码本身(插件代码身份是Instant Run的资源文件),我们必须模拟一个
Android环境,启动Instant Run
框架后,由改Instant Run
框架加载插件apk代码。。。。。
关于热加载偶尔失效,这时xposed的日志如下
Loading modules from /data/app/xxxx-1/base.apk
File does not exist
这个确定是xposed的bug,但是在不使用热加载的时候,该bug几乎不会出现,具体原因我就不描述了,和插件安装,系统重启的流程有关。当遇到这个场景时,可能重启无效,解决方案是需要触发一下插件安装,再重启Android系统。
工具开始于我的个人项目,后期在我公司所用。由于公司内部使用进而慢慢完善了越来越多的功能,也导致公司版本和开源版本分叉。由于部分功能存在较大商业价值,所以目前两个分支不再合并,而是由我分别维护。 而脱壳相关代码实现,属于公司内部版本一个很重要的功能,目前支持到任何非vmp得壳的脱壳。这里我提供一个解题思路:看雪帖子-换一个帅一点儿的姿势实现DexHunter 但是抱歉源码不会同步。一部分由我工作中积累的功能点,并且不具备商业竞争问题的情况下,我会考虑迁移到开源版本
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。