碎碎念

xplosed开发是我闲的没事干学习的,总的来说开发难度并不难,反而是kt语言自己很久没用了,写的很生疏。

这并不是xplosed模块入门,而是Yuki Hook框架开发入门,把遇见的坑写成文章。

开始入门开发吧

框架选择

入门:

Yukihook 框架:一个简单的hook列子

为了使用他的特色功能,需要用到几个ui库,来更直观的表示。

对话框UI库

混淆类查找库

宿主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 日
如果觉得我的文章对你有用,请随意赞赏