问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
解决Xposed hook不到加固的应用问题
移动安全
由于 Xposed 是系统级,所以 hook 的时机是很早,当 hook 加固的应用时会出现 hook 不到的情况。本文采用三种方法,从根本上解决了这一问题。
解决Xposed hook不到加固的应用问题 ---------------------- #### 应用被加固 Xposed 是 hook 不到的 测试的是一个不良 App,名字是 移动TV。 要用 Xposed hook 的类是 com.cz.babySister.activity.MainActivity。 首先用 objection search 一下这个类,看是否存在。 ```php objection -g com.cz.babySister explore android hooking search classes com.cz.babySister.activity.MainActivity ```  通过从内存里面查找,发现 com.cz.babySister.activity.MainActivity 类是的的确确存在的。 那么既然这个类存在,用 Xposed hook 应该就可以 hook 的到。 编写 Xposed hook 代码: ```java package com.bmstd.xposed1; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookTest implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (loadPackageParam.packageName.equals("com.cz.babySister")) { Class<?> aClass = XposedHelpers.findClass("com.cz.babySister.activity.MainActivity", loadPackageParam.classLoader); XposedBridge.hookAllMethods(aClass, "onCreate", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); XposedBridge.log("MainActivity onCreate called"); } }); } } } ``` 发现会一直触发 java.lang.ClassNotFoundException 类找不到的异常。  将 App 进行静态分析,拖入 GDA 中,发现这是一个加了壳的 App ,进行了腾讯加固。  所以,由于 Xposed 是系统级别 hook 框架,Xposed 注入的时机是很早的,而壳程序总是又较 App 应用程序最先执行的,所以 Xposed hook 默认使用的是壳的 ClassLoader 而不是应用本身的 ClassLoader,所以是不可能 hook 到应用内部的代码的。 这就将问题转换为,如何转换 ClassLoader。 #### 基本原理 要使用 Xposed hook 加固的应用分为三步 1. 是拿到加载应用本身 dex 的 ClassLoader 2. 是通过这个 ClassLoader 去找到被加固的类 3. 是通过这个类去 hook 需要 hook 的方法 #### 从多dex hook不到的问题角度去解决 Xposed hook 不到加固的应用 现在很多的 app 都有多个 dex 文件,因为谷歌规定单个 dex 文件中的方法不能超过 65536 个。 如果代码太多的话必须拆分 dex。如果用 Xposed 去 hook 非默认 dex 文件的类就会发生 ClassNotFoundError。 要解决这个问题,需要拿到对应 dex 文件的上下文环境。 android 在加载 dex 文件后会创建一个 Application 类,然后会调用 attach 方法,attach 方法的参数就是上下文 context。  而且 attach 方法是 final 方法,不会因为被覆盖而 hook 不到,拿到这个 context 就可以获取对应的 classloader,然后可以顺利 hook 到需要的类。 根据上面的思路,编写代码: ```java package com.bmstd.xposed1; import android.app.Application; import android.content.Context; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookTest implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (loadPackageParam.packageName.equals("com.cz.babySister")) { // 解决多dex文件hook不到问题 XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); // 获取上下文 Context context = (Context) param.args[0]; XposedBridge.log("context => " + context); // 类加载器 ClassLoader classLoader = context.getClassLoader(); XposedBridge.log("classLoader => " + classLoader); // 替换类加载器进行 hook 对应的方法 Class<?> aClass = XposedHelpers.findClass("com.cz.babySister.activity.MainActivity", classLoader); XposedBridge.hookAllMethods(aClass, "onCreate", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); XposedBridge.log("MainActivity onCreate called"); } }); } }); } } } ``` 执行代码后,可以看到首先进入了壳的 context ,然后获取到了壳的 ClassLoader。  等正式进入 App 后,android 会重新加载 App 本身 dex 文件,会创建一个 Application 类,然后会调用 attach 方法,attach 方法的参数就是上下文 context。通过这个 context 获取到的就是 App 本身的 ClassLoader 了。 在通过这个 ClassLoader 找到要 hook 的类,执行后的结果就是成功 hook 到类中的方法。  #### 从动态加载dex hook不到的问题角度去解决 Xposed hook 不到加固的应用 从上面的理论分析得知,重点问题还是在 ClassLoader 的切换。 所以直接使用 java.lang.ClassLoader.loadClass(java.lang.String) 这个方法。 这个方法的功能是:加载具有指定二进制名称的类,成功,然后一个类的对象。  根据上面的思路,编写代码: ```java package com.bmstd.xposed1; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookTest implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (loadPackageParam.packageName.equals("com.cz.babySister")) { XposedBridge.log("has hooked!"); // 解决动态加载dex文件hook不到问题 XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); // 打印当前已经加载的类 XposedBridge.log("clazz => " + param.getResult()); Class<?> clazz = (Class<?>) param.getResult(); if (clazz != null && clazz.getName().equals("com.cz.babySister.activity.MainActivity")) { XposedBridge.hookAllMethods(clazz, "onCreate", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); XposedBridge.log("MainActivity onCreate called"); } }); } } }); } } } ``` 执行代码后,首先找到了壳的类。  然后陆续找到了所有类,并成功进行预想中的 hook 。  #### 从应用加载角度解决 Xposed hook 不到加固的应用 App 是通过 Zygote 进程孵化的,通过 ActivityThread.main() 进入 App 。 performLaunchActivity() 函数用于响应 Activity 的操作。 并且 ActivityThread 类中还存在 Application 类型的 mInitialApplication。  mInitialApplication 可以获得当前的 ClassLoader。 根据上面的思路,编写代码: ```java package com.bmstd.xposed1; import android.app.Application; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class HookTest implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (loadPackageParam.packageName.equals("com.cz.babySister")) { Class ActivityThread = XposedHelpers.findClass("android.app.ActivityThread", loadPackageParam.classLoader); XposedBridge.hookAllMethods(ActivityThread, "performLaunchActivity", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Application mInitialApplication = (Application) XposedHelpers.getObjectField(param.thisObject, "mInitialApplication"); ClassLoader finalClassloader = mInitialApplication.getClassLoader(); XposedBridge.log("found classload is => " + finalClassloader.toString()); Class<?> MainActivity = XposedHelpers.findClass("com.cz.babySister.activity.MainActivity", finalClassloader); XposedBridge.hookAllMethods(MainActivity, "onCreate", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); XposedBridge.log("MainActivity onCreate called"); } }); } }); } } } ``` 再次成功完成 hook 。 
发表于 2023-05-04 09:00:02
阅读 ( 9217 )
分类:
漏洞分析
0 推荐
收藏
2 条评论
yls
2023-09-16 18:01
非常棒,但是有个娜迦的shell,用老哥的方法并不能hook到。老哥尝试过娜迦的那个Vdog的shell没。
请先
登录
后评论
yls
2023-09-16 20:55
Vdog 的shell,貌似hook 不行
请先
登录
后评论
请先
登录
后评论
bmstd
13 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!