本文博客連接:http://blog.csdn.net/QQ1084283172/article/details/79378374java
在進行Android逆向分析的時候,常常須要進行動態調試棧回溯,查看Java函數的調用流程,Android的smali動態調試又不是很方便,所以使用Android的Java Hook的方法,打印Java函數調用堆棧信息輔助靜態分析。android
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); }*/