利用Xposed Hook列印Java函式呼叫堆疊資訊的幾種方法
阿新 • • 發佈:2019-02-01
在進行Android逆向分析的時候,經常需要進行動態除錯棧回溯,檢視Java函式的呼叫流程,Android的smali動態除錯又不是很方便,因此使用Android的Java Hook的方法,列印Java函式呼叫堆疊資訊輔助靜態分析。
package com.xposeddemo; import java.util.Map; import android.util.Log; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; public class Module implements IXposedHookLoadPackage { @Override public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { // 判斷是否是要Hook的包名 if (lpparam.packageName.equals("com.lenovo.anyshare.gps")){ XposedBridge.log("Loaded App:" + lpparam.packageName); // 查詢要Hook的函式(需要列印堆疊呼叫的目標函式) XposedHelpers.findAndHookMethod( "com.lenovo.anyshare.frv", // 被Hook函式所在的類com.lenovo.anyshare.frv lpparam.classLoader, "a", // 被Hook函式的名稱a new XC_MethodHook(){ @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { // Hook函式之前執行的程式碼 //傳入引數1 //XposedBridge.log("beforeHookedMethod userName:" + param.args[0]); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // Hook函式之後執行的程式碼 //函式返回值 //XposedBridge.log("afterHookedMethod result:" + param.getResult()); // 函式呼叫完成之後列印堆疊呼叫的資訊 // 方法一: Log.i("Dump Stack: ", "---------------start----------------"); Throwable ex = new Throwable(); StackTraceElement[] stackElements = ex.getStackTrace(); if (stackElements != null) { for (int i = 0; i < stackElements.length; i++) { Log.i("Dump Stack"+i+": ", stackElements[i].getClassName() +"----"+stackElements[i].getFileName() +"----" + stackElements[i].getLineNumber() +"----" +stackElements[i].getMethodName()); } } Log.i("Dump Stack: ", "---------------over----------------"); // 方法二: new Exception().printStackTrace(); // 直接乾脆 // 方法三: Thread.dumpStack(); // 直接暴力 // 方法四: // 列印呼叫堆疊: http://blog.csdn.net/jk38687587/article/details/51752436 RuntimeException e = new RuntimeException("<Start dump Stack !>"); e.fillInStackTrace(); Log.i("<Dump Stack>:", "++++++++++++", e); // 方法五: // Thread類的getAllStackTraces()方法獲取虛擬機器中所有執行緒的StackTraceElement物件,可以檢視堆疊 for (Map.Entry<Thread, StackTraceElement[]> stackTrace:Thread.getAllStackTraces().entrySet()) { Thread thread = (Thread) stackTrace.getKey(); StackTraceElement[] stack = (StackTraceElement[]) stackTrace.getValue(); // 進行過濾 if (thread.equals(Thread.currentThread())) { continue; } Log.i("[Dump Stack]","**********Thread name:" + thread.getName()+"**********"); int index = 0; for (StackTraceElement stackTraceElement : stack) { Log.i("[Dump Stack]"+index+": ", stackTraceElement.getClassName() +"----"+stackTraceElement.getFileName() +"----" + stackTraceElement.getLineNumber() +"----" +stackTraceElement.getMethodName()); } // 增加序列號 index++; } Log.i("[Dump Stack]","********************* over **********************"); } }); //查詢要Hook的函式 // XposedHelpers.findAndHookMethod( // "com.lenovo.anyshare.frw", // 被Hook函式所在的類com.lenovo.anyshare.frv // lpparam.classLoader, // "b", // 被Hook函式的名稱b // int.class, // new XC_MethodHook(){ // @Override // protected void beforeHookedMethod(MethodHookParam param) // throws Throwable { // // Hook函式之前執行的程式碼 // // //傳入引數1 // XposedBridge.log("beforeHookedMethod com.lenovo.anyshare.frw--b--StpSocket: " + param.args[0]); // } // // @Override // protected void afterHookedMethod(MethodHookParam param) // throws Throwable { // // Hook函式之後執行的程式碼 // // //函式返回值 // //XposedBridge.log("afterHookedMethod result:" + param.getResult()); // // XposedBridge.log("com.lenovo.anyshare.frw--b---StpSocket---Dump Stack: "+"---------------start----------------"); // Throwable ex = new Throwable(); // StackTraceElement[] stackElements = ex.getStackTrace(); // if (stackElements != null) { // for (int i = 0; i < stackElements.length; i++) { // // XposedBridge.log("Dump Stack---StpSocket"+i+": "+stackElements[i].getClassName() // +"----"+stackElements[i].getFileName() // +"----" + stackElements[i].getLineNumber() // +"----" +stackElements[i].getMethodName()); // } // // XposedBridge.log("com.lenovo.anyshare.frw--b---StpSocket---Dump Stack: "+"---------------over----------------"); // } // } // }); // XposedHelpers.findAndHookMethod( // "com.lenovo.anyshare.frw", // 被Hook函式所在的類com.lenovo.anyshare.frv // lpparam.classLoader, // "a", // 被Hook函式的名稱a // int.class, // new XC_MethodHook(){ // @Override // protected void beforeHookedMethod(MethodHookParam param) // throws Throwable { // // Hook函式之前執行的程式碼 // // //傳入引數1 // XposedBridge.log("beforeHookedMethod com.lenovo.anyshare.frw--a--ServerSocket:" + param.args[0]); // } // // @Override // protected void afterHookedMethod(MethodHookParam param) // throws Throwable { // // Hook函式之後執行的程式碼 // // //函式返回值 // //XposedBridge.log("afterHookedMethod result:" + param.getResult()); // // XposedBridge.log("com.lenovo.anyshare.frw--a--ServerSocket--Dump Stack: "+"---------------start----------------"); // Throwable ex = new Throwable(); // StackTraceElement[] stackElements = ex.getStackTrace(); // if (stackElements != null) { // for (int i = 0; i < stackElements.length; i++) { // // XposedBridge.log("Dump Stack--ServerSocket"+i+": "+stackElements[i].getClassName() // +"----"+stackElements[i].getFileName() // +"----" + stackElements[i].getLineNumber() // +"----" +stackElements[i].getMethodName()); // } // // XposedBridge.log("com.lenovo.anyshare.frw--a--ServerSocket--Dump Stack: "+"---------------over----------------"); // } // } // }); } } } /** * Look up a method and place a hook on it. The last argument must be the callback for the hook. * @see #findMethodExact(Class, String, Object...) */ /*針對非靜態方法的Hook public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) { if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length-1] instanceof XC_MethodHook)) throw new IllegalArgumentException("no callback defined"); XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1]; Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback)); return XposedBridge.hookMethod(m, callback); }*/ /** @see #findAndHookMethod(Class, String, Object...) */ /*針對靜態方法的Hook public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) { return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback); }*/