寫在前面
Xposed雖然有被frida替代的趨勢,但是由于他們各自實(shí)現(xiàn)方式的差異,Xposed在hook的成功率上還有有些優(yōu)勢的。不過frida相對于Xposed最明顯的優(yōu)勢個(gè)人看來在于其免重啟的靈活處理模式,可以協(xié)助檢測人員快速定位問題。
結(jié)合兩者的以上幾個(gè)優(yōu)缺點(diǎn)以及個(gè)人的一些研究的小想法,所以就考慮做一下Xposed的免重啟Hook的方案,其實(shí)之前也有肯多大佬做過類似的功能更多更強(qiáng)大的項(xiàng)目,如免重啟的Xposed框架、Xserver直接就可以枚舉方法動(dòng)態(tài)hook,但是這種方法一是需要換框架,我懶得換了,一個(gè)是Xserver功能太多太強(qiáng)了不是很好操作。再加上生命在于折騰,所以怎么著也要自己來一把試試,所以就搞了一下這個(gè)小東西。
這個(gè)思路的核心在于getDeclaredMethods和XposedBridge.hookMethod(),通過getDeclaredMethods遍歷方法,然后用XposedBridge.hookMethod()進(jìn)行Hook和打印參數(shù)操作。在xml文件中配置需要Hook的包名、方法名。
實(shí)現(xiàn)比較簡陋,但是可以幫助我在面對frida無法hook的時(shí)候相對快一點(diǎn)的去定位問題和驗(yàn)證目標(biāo)方法是否是我想要的方法。
不過雖然不需要重啟,但是還是需要徹底殺掉目標(biāo)App進(jìn)程才能使修改生效的。
xml文件內(nèi)容如下
<?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>
實(shí)現(xiàn)步驟
解析配置文件
// 定義幾個(gè)字段用來接收從xml中讀取的數(shù)據(jù)
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","讀取配置文件出現(xiàn)問題");
}
//過濾掉不符合要求的類,可以打一下日志,看看是否正常
if (lpparam.packageName.equals(packageName)) {
XposedBridge.log("Loaded app: " + lpparam.packageName);
// hookAllMethod即為具體實(shí)現(xiàn)hook的方法
hookAllMethod(className,methodName,isHookAll,lpparam.classLoader);
}
hookAllMethod
-
獲取所需的類對象
clazz = Class.forName(className, false, classLoader); -
遍歷目標(biāo)類的方法
// 遍歷方法 for (final Method method: clazz.getDeclaredMethods()) { // 處理邏輯 }
-
Hook目標(biāo)方法
如果xml中配置isHookAll為true,則會hook目標(biāo)類中的所有方法
// Hook所有方法 if(isHookAll){ XposedBridge.log("進(jìn)入" + 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("自動(dòng)Hook " + methodName + ",參數(shù) [" + i + "] = " + param.args[i]); } } else { XposedBridge.log("自動(dòng)Hook無參數(shù)"); } XposedBridge.log("自動(dòng)Hook " + methodName + ",返回值" + param.getResult().toString()); } }); }
后期思路
目前xml方式配置有些缺陷,也沒有實(shí)現(xiàn)hook多種方法和類的機(jī)制,后續(xù)準(zhǔn)備看看把配置文件改成json并且把hook目標(biāo)做成列表,以便實(shí)現(xiàn)同時(shí)Hook多個(gè)方法還有增加一下修改參數(shù)和返回值的功能。emmmm 有時(shí)間再搞吧??