zoukankan      html  css  js  c++  java
  • 利用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);
    }*/

  • 相关阅读:
    MYSQL关于数据库的操作命令
    理解js中的原型和原型链
    float引起的高度塌陷问题
    使用webpack2.0 搭建前端项目
    jquery插件开发总结
    js中的OOP编程
    关于gulp的基本使用
    关于requireJs的学习总结
    vuex的学习总结
    事件中的target与currentTarget的区别
  • 原文地址:https://www.cnblogs.com/csnd/p/11800597.html
Copyright © 2011-2022 走看看