利用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函数调用堆栈信息的几种方法的更多相关文章
- 打印Java异常堆栈信息
背景 在开发Java应用程序的时候,遇到程序抛异常,我们通常会把抛异常时的运行时环境保存下来(写到日志文件或者在控制台中打印出来).这样方便后续定位问题. 需要记录的运行时环境包含两部分内容:抛异常时 ...
- Slf4j打印异常的堆栈信息
一.前言 直接用logger.info("异常信息为:"+e)或者logger.info(e.getMessage())只能记录到异常的描述信息,却没有其异常具体发生在哪一行代码. ...
- java分享第十六天( java读取properties文件的几种方法&java配置文件持久化:static块的作用)
java读取properties文件的几种方法一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取Propert ...
- 这里给大家介绍一下通过 Wi-Fi 连接“慷慨捐赠”你的身份信息的七种方法.
这里给大家介绍一下通过 Wi-Fi 连接“慷慨捐赠”你的身份信息的七种方法和反制措施. 本文作者:黑子小盆友 1.利用免费热点 它们似乎无处不在,而且它们的数量会在接下来四年里增加三倍.但是它们当中很 ...
- Java中创建数组的几种方法
Java中创建数组的几种方法 public static void main(String[] args) { //创建数组的第一种方法 int[] arr=new int[6]; int intVa ...
- Java List转换为字符串的几种方法
Java List转换为字符串的几种方法 import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import ...
- java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)
转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...
- Win7系统与它的Virtualbox中安装的Ubuntu14.04共享信息的几种方法
虚拟机是每一个程序猿必备的工具.本文依据最新版VirtualBox用户手冊的提示,通过自己的亲自实践,给出了Win7系统与执行在当中的VirtualBox 5.0.2中的Ubuntu 14.04共享信 ...
- Java遍历List集合的三种方法
Java遍历List集合的三种方法 List<String> list = new ArrayList<String>(); list.add("aaa") ...
随机推荐
- 微信小程序封装请求接口
var rootDocment = 'https://123.com';//你的域名 function postData(url, data, cb) { wx.request({ url: root ...
- PAT-1132(Cut Integer )数的拆分+简单题
Cut Integer PAT-1132 #include<iostream> #include<cstring> #include<string> #includ ...
- [00]数字图像处理-matlab速成
原本听的是mooc武汉大学的数字图像处理课程,但是无奈老师读ppt的能力太强,不太适应,后面的课程对于实验方面的要求甚低,无奈之下到处找课程,终于找到了一个适合自己的教程<王伟强-数字图像处理& ...
- python flask框架详解
Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务.本文参考自Flask官方文档, 英文不好的同学也可以参考中文文档 1.安装flask pi ...
- AbstractQueuedSynchronizer之AQS
一.可重入锁 可参考:可重入锁和递归锁 1,定义 指的是同一线程外层函数获得锁后,再进入该线程的内层方法会自动获取锁(前提:锁对象是同一个对象). Java中的ReentranLock(显示锁)和Sy ...
- 使用dcmtk库读取.dcm文件并获取信息+使用OpenCV显示图像
借助VS2013和OpenCV的绘图功能,在工程DICOMReader.sln中实现了对单张.dcm图像的读取与显示,以下是详细步骤. 前期准备工作 编译器:VS2013 库:dcmtk-3.6.0( ...
- 【新阁教育】台达DVP-ES3 ModbusTCP通信案例
本文主要针对台达DVP-ES3系列PLC,实现上位机与PLC之间的ModbusTCP通信. 一.硬件说明 DVP-ES3 系列为高阶应用可编程控制器, CPU 内置4 组高速计数器输入.4组轴输出(脉 ...
- 你说,怎么把Bean塞到Spring容器?
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 小傅哥,你是怎么学习的? 有很多初学编程或者码了几年CRUD砖的小伙伴问我,该怎么学 ...
- Java例题_27 100以内的素数
1 /*27 [程序 27 求素数] 2 题目:求 100 之内的素数 3 */ 4 5 /*分析 6 * 素数:是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数. 7 * 同第二题: ...
- [Azure Devops] 使用 Azure Pipelines 实现 CI
1. 什么是 Azure Pipelines Azure Pipelines 会自动构建和测试代码项目,以将其提供给其他人.它适用于任何语言或项目类型.Azure Pipelines 结合了持续集成 ...