为了hook动态加载的class,我使用了hook ClassLoader.loadClass(String)的方法,此方法在原生Xposed API上生效,但在Yuki上会有app卡死或代码执行中断的问题。
以下是原生Xposed API正常使用的代码:
public class ZuoyebangHook implements IXposedHookLoadPackage {
public String LOG_TAG = "ZuoyebangHook: ";
@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
XposedBridge.log("Loaded app: " + lpparam.packageName);
if (lpparam.packageName.equals("com.baidu.homework")){
XposedBridge.log(LOG_TAG + "作业帮已启动");
findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (param.hasThrowable()) return;
super.afterHookedMethod(param);
XposedBridge.log(LOG_TAG + "已加载类:" + param.args[0]);
hook(lpparam, (String)param.args[0]);
}
});
}
}
public void hook(XC_LoadPackage.LoadPackageParam lpparam, String className) {
switch (className){
case "com.baidu.homework.activity.search.whole.PicManySearchActivity":
XposedBridge.log(LOG_TAG + "已加载" + className + ",并捕捉");
findAndHookMethod(
"com.baidu.homework.activity.search.whole.PicManySearchActivity",
lpparam.classLoader,
"onCreate",
Bundle.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
XposedBridge.log(LOG_TAG + "PicManySearchActivity.onCreate已调用");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
}
}
以下是使用Yuki不能正常工作的代码:
@InjectYukiHookWithXposed
class HookEntry : IYukiHookXposedInit {
override fun onInit() {
YukiHookAPI.configs {
debugTag = "HomeworkKiller"
isDebug = true
isAllowPrintingLogs = true
isEnableModulePrefsCache = true
isEnableModuleAppResourcesCache = true
isEnableHookModuleStatus = true
isEnableDataChannel = true
isEnableMemberCache = true
}
}
override fun onHook(){
YukiHookAPI.encase {
loadApp( APP_NAME ){
ClassLoader::class.java.hook {
injectMember {
method {
name = "loadClass"
}
afterHook {
val className = args[0] as String
loggerI(msg = "result:${hook_classes.contains(className)}")
loggerI(msg = "现在要加载hooker")
loadHooker(MethodHooks(className))
}
}
}
"com.baidu.homework.activity.search.whole.PicManySearchActivity".hook {
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
beforeHook {
loggerI(msg = "Has hooked method:PicManySearchActivity.onCreate")
}
}
}
}
}
}
}
val hook_classes = listOf(
"com.baidu.homework.activity.search.whole.PicManySearchActivity",
)
class MethodHooks(className : String) : MyBaseHooker(className){
override fun onHook() {
loadApp(APP_NAME){
loggerI(msg = "loaded class:${className}")
}
}
}
abstract class MyBaseHooker(class_name : String) : YukiBaseHooker() {
var className : String = "";
init {
className = class_name
}
abstract override fun onHook()
}
bug fixed