碎碎念
xplosed开发是我闲的没事干学习的,总的来说开发难度并不难,反而是kt语言自己很久没用了,写的很生疏。
这并不是xplosed模块入门,而是Yuki Hook框架开发入门,把遇见的坑写成文章。
开始入门开发吧
框架选择
入门:
为了使用他的特色功能,需要用到几个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管理器的永久会员。
- 超级混淆8.0
- apk伪加密
- 修改apk内文件时间
- Res内容加密
- 控制流混淆(MILK)
这些能有效防止APP被破解,如果担心破解就多处理一下软件。
更上难度的so层加密才是应该做的。
可实际上并不能一键把函数打包成so,那会导致hook不起作用。
碎碎念
其实xplosed开发没什么好说的,如果是原生的开发还需要稍微处理一下,但是像Yuki这样的xplosed库就很方便了。
但是踩得坑也很多,说实话。
但是喜欢尝试新鲜事物,是这样的捏。
工具没有好坏,只有用途才有好坏之分。
写到这里,我很快啊。里面把yuki的仓库给fork了。
以前玩的Autojs也是,因为用户莫名其妙的消失了。
把我给整乐了,按键精灵那么火,你不封,autojs你直接就给整改了。
你md。