利用Xposed Hook打印Java函数调用堆栈信息的几种方法

Posted Fly20141201

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用Xposed Hook打印Java函数调用堆栈信息的几种方法相关的知识,希望对你有一定的参考价值。

本文博客链接:http://blog.csdn.net/QQ1084283172/article/details/79378374

在进行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);
*/

以上是关于利用Xposed Hook打印Java函数调用堆栈信息的几种方法的主要内容,如果未能解决你的问题,请参考以下文章

xposed可以hook所有的java函数吗?

Android笔记-Xposed的使用(Hook登录函数获取用户名密码)

Xposed怎样hook 静态变量的调用

Xposed hook函数内有匿名内部类该怎么写

Android插件化原理解析——Hook机制之动态代理

Android插件化原理解析——Hook机制之动态代理