0x01 導讀
工作中,常常需要針對各種app進行快速代碼定位,找到代碼修改和調試各種功能,就不得不面對xposed來進行一系列快速定位關鍵代碼的問題了。那么問題來了,如何快速找到代碼呢?
這里值這針對代碼在java層的進行分析,在so中的,目前作者是無能為力的。
0x02 眾所周知
我們的一般做法就是通過界面定位到具體的Activity ,執行adb 命令 “adb shell dumpsys activity | findstr "mFocusedActivity"”
就可以快速找到我們當前需要hook頁面的Activity功能塊,然后通過,XposedHelpers的
findAndHookMethod方法來,監控方法。少量的工作沒什么,但是如果代碼量很多,很難看,就比較麻煩了。 所以這里介紹一種作者目前使用的,自仍未快速的方式。
0x03 推薦使用
1、安裝apk后,可以得到app使用的dex文件。
2、然后解包dex文件得到jar文件。
3、通過xposed讀取jar中的所有類,
4、然后hook,然后讀取所有方法hook.
5、然后通過關鍵字,匹配參數,匹配返回值,快速得到操作日志。
注意:如果是多個dex,一樣是可以的,多個jar。解壓然后覆蓋保存到一個里面,然后打包成jar就可以,jar就使用zip打包工具就可以,修改后綴就ok.,
dex文件一般都可以通過apk解壓得到,然后用apktool工具得到jar文件,針對某些apk無法apktool解包的可以添加-r等操作,不處理資源文件就OK.
懶加載plugin如何操作呢? 找到不類呢?有一種情況,某些dex是專門存放插件,插件是進入到某些頁面才會進行加載的,通過懶hook,進入某某頁面,然后再進行hook操作,或者hook文件操作即可。
部分參考代碼:

public static void hook_byJar(final XC_LoadPackage.LoadPackageParam loadPackageParam, String jarFile) throws Exception { try { //通過將給定路徑名字符串轉換為抽象路徑名來創建一個新File實例 File f = new File(jarFile); URL url1 = f.toURI().toURL(); URLClassLoader myClassLoader = new URLClassLoader(new URL[]{url1}, Thread.currentThread().getContextClassLoader()); //通過jarFile和JarEntry得到所有的類 JarFile jar = new JarFile(jarFile); //返回zip文件條目的枚舉 Enumeration<JarEntry> enumFiles = jar.entries(); JarEntry entry; //測試此枚舉是否包含更多的元素 while (enumFiles.hasMoreElements()) { entry = (JarEntry) enumFiles.nextElement(); if (entry.getName().indexOf("META-INF") < 0) { String classFullName = entry.getName(); if (classFullName.indexOf(".class") < 0) { classFullName = classFullName.substring(0, classFullName.length() - 1); } else { Map<String, Object> hashMap = new HashMap<String, Object>(); // 這里通過包名對部分類進行過濾,方式由於類不存在引起的錯誤。 hashMap.put("com/test/test/test/", new ArrayList<String>()); boolean isOkClass = false; for (Map.Entry<String, Object> m : hashMap.entrySet()) { String name = m.getKey(); ArrayList<String> list = (ArrayList<String>) m.getValue(); if (classFullName.startsWith(name)) { isOkClass = true; for (String str : list) { if (classFullName.startsWith(str)) { isOkClass = false; } } break; } } if (isOkClass) { //去掉后綴.class String className = classFullName.substring(0, classFullName.length() - 6).replace("/", "."); // log(classFullName); try { final Class<?> myclass = myClassLoader.loadClass(className); for (final Method method : myclass.getDeclaredMethods()) { if (!Modifier.isAbstract(method.getModifiers())) { XposedBridge.hookMethod(method, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { String before_className = myclass.getName(); String methodName = param.method.getName(); super.beforeHookedMethod(param); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { String before_className = myclass.getName(); String methodName = param.method.getName(); super.afterHookedMethod(param); } }); } } } catch (Exception e) { e.printStackTrace(); } } } } } } catch (IOException e) { e.printStackTrace(); } }
0x04 其他方式
1、針對app使用的開源庫進行了解然后方便hook注關鍵代碼,因為開源代碼都是開源的,不需要看app解包的混淆,羞澀的代碼。
2、針對app作者,寫入Log的內容進行hook,因為發布的app一般都是把其中的一個true或者false進行注釋掉了,方法調用日志本身沒有注釋掉,所以可以針對寫入的日志的地方進行處理。