### 碎碎念 xplosed开发是我闲的没事干学习的,总的来说开发难度并不难,反而是kt语言自己很久没用了,写的很生疏。 这并不是xplosed模块入门,而是Yuki Hook框架开发入门,把遇见的坑写成文章。 ### 开始入门开发吧 #### 框架选择 *入门:* [Yukihook 框架:一个简单的hook列子](https://highcapable.github.io/YukiHookAPI/zh-cn/guide/example.html#一个简单的-hook-例子) 为了使用他的特色功能,需要用到几个ui库,来更直观的表示。 [对话框UI库](https://github.com/afollestad/material-dialogs) [混淆类查找库](https://luckypray.org/DexKit/zh-cn/guide/example.html#多条件匹配类多条件用法示例) *宿主APP:* 酷安(傻逼广告),其实这个宿主APP可以忽略不计,因为我只是为了讲述疑难杂症,并没有说该如何hook。 --- #### 如何使用纯净的context ``` loadApp(name = "com.android.browser") { ActivityClass.method { name = "onCreate" param(BundleClass) returnType = UnitType }.hook { after { AlertDialog.Builder(instance()) .setTitle("Hooked") .setMessage("I am hook!") .setPositiveButton("OK", null) .show() } } } ``` 这是一个非常简单的hook,应用界面初始化后提供弹窗的情况。 但是这里需要指定一个问题,即软件继承的context问题。 Yuki可用的context,分别是appcontext,systemcontext,以及可以用他内嵌的instance方法来获取一个未被宿主污染的context。 ``` val appCompatContext = instance().applyModuleTheme(com.google.android.material.R.style.Theme_Material3_DayNight_NoActionBar) ``` 如果不适用这个appCompatContext,利用hook或者其余方式转化的context,均会导致其他用到context的ui库获取其他内容报错,因为这个context不对。 有一说一,框架封装了之后,比使用默认的xplsoed框架开发更方便,尤其是像这种未被污染的context。 --- #### 自动注入模块资源及忽略加固 ``` onAppLifecycle { attachBaseContext { baseContext, hasCalledSuper -> if (hasCalledSuper) run { appClassLoader = baseContext.classLoader // YLog.warn("HookEntry attachBaseContext success") } } onCreate { // 注入模块资源 injectModuleAppResources() registerModuleAppActivities() XSharedPreferences(BuildConfig.APPLICATION_ID) } } ``` onAppLifecycle这个是自动化注入的内容, 但是需要提醒: ``` registerModuleAppActivities() ``` 这样注入模块,如采用代理 override val proxyClassName: String get() = "" // 指定代理宿主类 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) YLog.info("HOOKActivity onCreate") } 很遗憾,这样的功能处于实验模式,而我也并未成功注入过,不过感兴趣的,可以查看xihan123/QDReadHook 这个Github仓库。 我即使自己指定了context,或者一开始就注入了,都只会跳转到宿主活动的界面,而不会将自己的解密进行覆盖。 --- #### 使用原生xplosed方法 ``` YukiXposedEvent.events { onHandleLoadPackage { } } ``` 令人高兴的是,他封装了原生的方法,里面正常写xplosed原生的hook即可。 ``` XposedHelpers.findAndHookMethod() ``` 当然可以自己在APP直接注入: ``` override fun onXposedEvent(){ onInitZygote { // it 对象即 [StartupParam] } onHandleLoadPackage { // it 对象即 [LoadPackageParam] // 用于提供原生hook的监听 } onHandleInitPackageResources { // it 对象即 [InitPackageResourcesParam] } } ``` 效果是一样的。 --- #### Xposed 模块数据存储 这个也比原生的使用方便的很多。 ``` prefs().edit { putString("test_name", "saved_value") } ``` 若果想要其他类和方法使用这个功能,将其函数内部传递即可,如: ``` native: YukiHookPrefsBridge ``` --- #### 混淆类查找 我使用的是Dexkit这个库,因为他极为方便。 当你查找到类后,可以使用很简单的方法来直接锁定hook点: ``` appClassLoader?.let { methodData.getClassInstance(it).method { } ``` 这样就不用再次进行反射开销了。 如他官方的列子: ``` val methodData = bridge.findMethod { matcher { // 一切条件都是可选的,您可以自由的组合 modifiers = Modifier.PUBLIC returnType = "boolean" paramCount = 0 usingStrings("VipCheckUtil", "userInfo:") } }.single() val method: Method = methodData.getMethodInstance(hostClassLoader) XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(true)) ``` #### 如何提高模块破解难度 说实话这个需要用工具,但是我为了偷懒就直接买了NP管理器的永久会员。 1. 超级混淆8.0 2. apk伪加密 3. 修改apk内文件时间 4. Res内容加密 5. 控制流混淆(MILK) 这些能有效防止APP被破解,如果担心破解就多处理一下软件。 更上难度的so层加密才是应该做的。 可实际上并不能一键把函数打包成so,那会导致hook不起作用。 --- ### 碎碎念 其实xplosed开发没什么好说的,如果是原生的开发还需要稍微处理一下,但是像Yuki这样的xplosed库就很方便了。 但是踩得坑也很多,说实话。 但是喜欢尝试新鲜事物,是这样的捏。 工具没有好坏,只有用途才有好坏之分。 写到这里,我很快啊。里面把yuki的仓库给fork了。 以前玩的Autojs也是,因为用户莫名其妙的消失了。 把我给整乐了,按键精灵那么火,你不封,autojs你直接就给整改了。 你md。 Loading... ### 碎碎念 xplosed开发是我闲的没事干学习的,总的来说开发难度并不难,反而是kt语言自己很久没用了,写的很生疏。 这并不是xplosed模块入门,而是Yuki Hook框架开发入门,把遇见的坑写成文章。 ### 开始入门开发吧 #### 框架选择 *入门:* [Yukihook 框架:一个简单的hook列子](https://highcapable.github.io/YukiHookAPI/zh-cn/guide/example.html#一个简单的-hook-例子) 为了使用他的特色功能,需要用到几个ui库,来更直观的表示。 [对话框UI库](https://github.com/afollestad/material-dialogs) [混淆类查找库](https://luckypray.org/DexKit/zh-cn/guide/example.html#多条件匹配类多条件用法示例) *宿主APP:* 酷安(傻逼广告),其实这个宿主APP可以忽略不计,因为我只是为了讲述疑难杂症,并没有说该如何hook。 --- #### 如何使用纯净的context ``` loadApp(name = "com.android.browser") { ActivityClass.method { name = "onCreate" param(BundleClass) returnType = UnitType }.hook { after { AlertDialog.Builder(instance()) .setTitle("Hooked") .setMessage("I am hook!") .setPositiveButton("OK", null) .show() } } } ``` 这是一个非常简单的hook,应用界面初始化后提供弹窗的情况。 但是这里需要指定一个问题,即软件继承的context问题。 Yuki可用的context,分别是appcontext,systemcontext,以及可以用他内嵌的instance方法来获取一个未被宿主污染的context。 ``` val appCompatContext = instance<Activity>().applyModuleTheme(com.google.android.material.R.style.Theme_Material3_DayNight_NoActionBar) ``` 如果不适用这个appCompatContext,利用hook或者其余方式转化的context,均会导致其他用到context的ui库获取其他内容报错,因为这个context不对。 有一说一,框架封装了之后,比使用默认的xplsoed框架开发更方便,尤其是像这种未被污染的context。 --- #### 自动注入模块资源及忽略加固 ``` onAppLifecycle { attachBaseContext { baseContext, hasCalledSuper -> if (hasCalledSuper) run { appClassLoader = baseContext.classLoader // YLog.warn("HookEntry attachBaseContext success") } } onCreate { // 注入模块资源 injectModuleAppResources() registerModuleAppActivities() XSharedPreferences(BuildConfig.APPLICATION_ID) } } ``` onAppLifecycle这个是自动化注入的内容, 但是需要提醒: ``` registerModuleAppActivities() ``` 这样注入模块,如采用代理 override val proxyClassName: String get() = "" // 指定代理宿主类 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) YLog.info("HOOKActivity onCreate") } 很遗憾,这样的功能处于实验模式,而我也并未成功注入过,不过感兴趣的,可以查看xihan123/QDReadHook 这个Github仓库。 我即使自己指定了context,或者一开始就注入了,都只会跳转到宿主活动的界面,而不会将自己的解密进行覆盖。 --- #### 使用原生xplosed方法 ``` YukiXposedEvent.events { onHandleLoadPackage { } } ``` 令人高兴的是,他封装了原生的方法,里面正常写xplosed原生的hook即可。 ``` XposedHelpers.findAndHookMethod() ``` 当然可以自己在APP直接注入: ``` override fun onXposedEvent(){ onInitZygote { // it 对象即 [StartupParam] } onHandleLoadPackage { // it 对象即 [LoadPackageParam] // 用于提供原生hook的监听 } onHandleInitPackageResources { // it 对象即 [InitPackageResourcesParam] } } ``` 效果是一样的。 --- #### Xposed 模块数据存储 这个也比原生的使用方便的很多。 ``` prefs().edit { putString("test_name", "saved_value") } ``` 若果想要其他类和方法使用这个功能,将其函数内部传递即可,如: ``` native: YukiHookPrefsBridge ``` --- #### 混淆类查找 我使用的是Dexkit这个库,因为他极为方便。 当你查找到类后,可以使用很简单的方法来直接锁定hook点: ``` appClassLoader?.let { methodData.getClassInstance(it).method { } ``` 这样就不用再次进行反射开销了。 如他官方的列子: ``` val methodData = bridge.findMethod { matcher { // 一切条件都是可选的,您可以自由的组合 modifiers = Modifier.PUBLIC returnType = "boolean" paramCount = 0 usingStrings("VipCheckUtil", "userInfo:") } }.single() val method: Method = methodData.getMethodInstance(hostClassLoader) XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(true)) ``` #### 如何提高模块破解难度 说实话这个需要用工具,但是我为了偷懒就直接买了NP管理器的永久会员。 1. 超级混淆8.0 2. apk伪加密 3. 修改apk内文件时间 4. Res内容加密 5. 控制流混淆(MILK) 这些能有效防止APP被破解,如果担心破解就多处理一下软件。 更上难度的so层加密才是应该做的。 可实际上并不能一键把函数打包成so,那会导致hook不起作用。 --- ### 碎碎念 其实xplosed开发没什么好说的,如果是原生的开发还需要稍微处理一下,但是像Yuki这样的xplosed库就很方便了。 但是踩得坑也很多,说实话。 但是喜欢尝试新鲜事物,是这样的捏。 工具没有好坏,只有用途才有好坏之分。 写到这里,我很快啊。里面把yuki的仓库给fork了。 以前玩的Autojs也是,因为用户莫名其妙的消失了。 把我给整乐了,按键精灵那么火,你不封,autojs你直接就给整改了。 你md。 最后修改:2024 年 03 月 13 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏