写在前面
Xposed虽然有被frida替代的趋势,但是由于他们各自实现方式的差异,Xposed在hook的成功率上还有有些优势的。不过frida相对于Xposed最明显的优势个人看来在于其免重启的灵活处理模式,可以协助检测人员快速定位问题。
结合两者的以上几个优缺点以及个人的一些研究的小想法,所以就考虑做一下Xposed的免重启Hook的方案,其实之前也有肯多大佬做过类似的功能更多更强大的项目,如免重启的Xposed框架、Xserver直接就可以枚举方法动态hook,但是这种方法一是需要换框架,我懒得换了,一个是Xserver功能太多太强了不是很好操作。再加上生命在于折腾,所以怎么着也要自己来一把试试,所以就搞了一下这个小东西。
这个思路的核心在于getDeclaredMethods
和XposedBridge.hookMethod()
,通过getDeclaredMethods
遍历方法,然后用XposedBridge.hookMethod()
进行Hook和打印参数操作。在xml文件中配置需要Hook的包名、方法名。
实现比较简陋,但是可以帮助我在面对frida无法hook的时候相对快一点的去定位问题和验证目标方法是否是我想要的方法。
不过虽然不需要重启,但是还是需要彻底杀掉目标App进程才能使修改生效的。
xml文件内容如下
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id = "1">
<packagename>com.ming.xxx</packagename>
<classname>com.ming.xxx.xxx</classname>
<methodname>Encrypt</methodname>
<ishookall>false</ishookall>
</person>
</persons>
实现步骤
解析配置文件
// 定义几个字段用来接收从xml中读取的数据
String packageName = "";
String className = "";
String methodName = "";
boolean isHookAll = false;
// 解析xml文件获取信息
try {
ArrayList<Person> persons = readxmlForSAX();
Person p = persons.get(0);
packageName = p.getPackagename();
className = p.getClassName();
methodName = p.getMethodName();
isHookAll = p.isHookAll();
Log.e("ming", "读取配置文件:\npackapackageNamegeName=" + packageName + "\nclassName=" + className + "\nmethodName=" + methodName + "\nisHookAll=" + isHookAll);
}catch (Exception e){
Log.e("ming","读取配置文件出现问题");
}
//过滤掉不符合要求的类,可以打一下日志,看看是否正常
if (lpparam.packageName.equals(packageName)) {
XposedBridge.log("Loaded app: " + lpparam.packageName);
// hookAllMethod即为具体实现hook的方法
hookAllMethod(className,methodName,isHookAll,lpparam.classLoader);
}
hookAllMethod
-
获取所需的类对象
clazz = Class.forName(className, false, classLoader);
-
遍历目标类的方法
// 遍历方法 for (final Method method: clazz.getDeclaredMethods()) { // 处理逻辑 }
-
Hook目标方法
如果xml中配置isHookAll为true,则会hook目标类中的所有方法
// Hook所有方法 if(isHookAll){ XposedBridge.log("进入" + className + "\\" + hookMethod + "分支"); XposedBridge.hookMethod(method, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { int a = method.getParameterTypes().length; if (a > 0) { for (int i = 0; i < a; i++) { XposedBridge.log("自动Hook " + methodName + ",参数 [" + i + "] = " + param.args[i]); } } else { XposedBridge.log("自动Hook无参数"); } XposedBridge.log("自动Hook " + methodName + ",返回值" + param.getResult().toString()); } }); }
后期思路
目前xml方式配置有些缺陷,也没有实现hook多种方法和类的机制,后续准备看看把配置文件改成json并且把hook目标做成列表,以便实现同时Hook多个方法还有增加一下修改参数和返回值的功能。emmmm 有时间再搞吧😜