本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80954759

在进行Android程序的逆向分析的时候,经常需要Android程序的静态分析和动态调试的结合,尤其是对一些加固后的Android类方法被调用的确认,需要Hook java类方法打印java类方法的调用堆栈。有幸在网上看到了这篇文章《XPosed暴力列举Package下所有的方法调用》,按照作者的思路和代码进行了验证和尝试,发现效果并不明显而且不好用,对多dex的Android应用支持不好,因此在此基础上调整了一下思路,简单的写了份xposed Hook代码,如下:
package com.xposed.enumeratorClassHook;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; // 自定义的回调函数接口
public class Module implements IXposedHookLoadPackage { static String strClassName = ""; @Override
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { // 被Hook操作的目标Android应用的包名,进行Hook操作的过滤
String strPackageName = "com.guji.loveparty";
if (lpparam.packageName.equals(strPackageName)) { XposedBridge.log("Loaded App:" + lpparam.packageName); // // 枚举指定Android应用的所有类方法并对指定的类方法进行java Hook操作
// PackageHooker packageHooker = new PackageHooker(lpparam);
// // 获取指定类的方法、属性变量、内部类等的信息
// ClassLoader classLoader = lpparam.classLoader;
// Class<?> dumpClass = XposedHelpers.findClass("com.tencent.bugly.lejiagu.crashreport.BuglyLog", classLoader);
// packageHooker.dumpClass(dumpClass); // // 被Hook操作的目标类的名称
// String strNomalCln = "";
// // 被Hook操作的目标类的方法的名称
// String strNomalMdn = "";
// // 在Android应用默认的classes.dex文件中的类方法的Hook操作
// XposedHelpers.findAndHookMethod(
// // 被Hook操作的目标类
// strNomalCln,
// lpparam.classLoader,
// // 被Hook操作的目标类方法
// strNomalMdn,
// // 被Hook操作的目标类方法的第1个参数的类型
// String.class,
// // 被Hook操作的目标类方法的第2个参数的类型
// String.class,
// new XC_MethodHook() {
// // 在被Hook操作的类方法执行之前执行代码
// @Override
// protected void beforeHookedMethod(MethodHookParam param)
// throws Throwable {
//
// // 打印被Hook操作的目标类方法的第1个参数值
// XposedBridge.log("beforeHookedMethod 第1个参数:" + param.args[0]);
// // 打印被Hook操作的目标类方法的第2个参数值
// XposedBridge.log("beforeHookedMethod 第2个参数:" + param.args[1]);
//
// // 打印被Hook操作的目标类方法的函数返回值ֵ
// XposedBridge.log("beforeHookedMethod result:" + param.getResult());
// }
//
// // 在被Hook操作的类方法执行之后执行代码
// @Override
// protected void afterHookedMethod(MethodHookParam param)
// throws Throwable {
//
// // 打印被Hook操作的目标类方法的第1个参数值
// XposedBridge.log("afterHookedMethod userName:" + param.args[0]);
// // 打印被Hook操作的目标类方法的第2个参数值
// XposedBridge.log("afterHookedMethod sn:" + param.args[1]);
//
// // 修改被Hook操作的目标类方法的函数返回值
// param.setResult(true);
//
// // 打印被Hook操作的目标类方法的函数返回值ֵ
// XposedBridge.log("afterHookedMethod 函数返回值:" + param.getResult());
// }
// }); // 不在Android应用默认的classes.dex文件中的类方法的Hook操作,例如:
// 1.MultiDex情况下的,多dex文件中的类方法的Hook操作,例如:classes1.dex中的类方法
// 2.主dex加载的jar(包含dex)情况下的,类方法的的Hook操作 // Hook类方法ClassLoader#loadClass(String)
findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() { // 在类方法loadClass执行之后执行的代码
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable { // 参数的检查
if (param.hasThrowable()) {
return;
} // 获取指定名称的类加载之后的Class<?>
Class<?> clazz = (Class<?>) param.getResult();
// 获取加载的指定类的名称
String strClazz = clazz.getName();
XposedBridge.log("LoadClass : "+strClazz); // // 被Hook操作的目标类名称
// String strClazzName = "";
// // 被Hook操作的类方法的名称
// String strMethodName = ""; // 所有的类都是通过loadClass方法加载的
// 过滤掉Android系统的类以及一些常见的java类库
if (!strClazz.startsWith("android.")
&& !strClazz.startsWith(".system")
&& !strClazz.startsWith("java.")
&& !strClazz.startsWith("org.")
&& !strClazz.contains("umeng.")
&& !strClazz.contains("com.google")
&& !strClazz.contains(".alipay")
&& !strClazz.contains(".netease")
&& !strClazz.contains(".alibaba")
&& !strClazz.contains(".pgyersdk")
&& !strClazz.contains(".daohen")
&& !strClazz.contains(".bugly")
&& !strClazz.contains("mini")
&& !strClazz.contains("xposed")) {
// 或者只Hook加密算法类、网络数据传输类、按钮事件类等协议分析的重要类 // 同步处理一下
synchronized (this.getClass()) { // 获取被Hook的目标类的名称
strClassName = strClazz;
//XposedBridge.log("HookedClass : "+strClazz);
// 获取到指定名称类声明的所有方法的信息
Method[] m = clazz.getDeclaredMethods();
// 打印获取到的所有的类方法的信息
for (int i = 0; i < m.length; i++) { //XposedBridge.log("HOOKED CLASS-METHOD: "+strClazz+"-"+m[i].toString());
if (!Modifier.isAbstract(m[i].getModifiers()) // 过滤掉指定名称类中声明的抽象方法
&& !Modifier.isNative(m[i].getModifiers()) // 过滤掉指定名称类中声明的Native方法
&& !Modifier.isInterface(m[i].getModifiers()) // 过滤掉指定名称类中声明的接口方法
) { // 对指定名称类中声明的非抽象方法进行java Hook处理
XposedBridge.hookMethod(m[i], new XC_MethodHook() { // 被java Hook的类方法执行完毕之后,打印log日志
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable { // 打印被java Hook的类方法的名称和参数类型等信息
XposedBridge.log("HOOKED METHOD: "+strClassName+"-"+param.method.toString());
}
});
}
}
} // // 所有的类都是通过loadClass方法加载的
// // 所以这里通过判断全限定类名,查找到被Hook操作的目标类
// if (strClazz.contains(strClazzName)) {
//
// // Hook目标类方法
// findAndHookMethod(clazz,
// // 被Hook操作的类方法的名称
// strMethodName,
// // 被Hook操作的类方法的参数类型
// //paramTypes, // 根据实际情况进行修改
// new XC_MethodHook() {
// @Override
// protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//
// // ......
//
// // 打印被Hook操作的目标类方法的第1个参数值
// XposedBridge.log("beforeHookedMethod 第1个参数:" + param.args[0]);
// // 打印被Hook操作的目标类方法的第2个参数值
// XposedBridge.log("beforeHookedMethod 第2个参数:" + param.args[1]);
//
// // ......
// }
//
// @Override
// protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//
// // ......
//
// // 打印被Hook操作的目标类方法的函数返回值ֵ
// XposedBridge.log("afterHookedMethod 函数返回值:" + param.getResult());
//
// // ......
// }
// });
// }
// ...... }
}
});
} } // 获取指定名称的类声明的类成员变量、类方法、内部类的信息
public void dumpClass(Class<?> actions) { XposedBridge.log("Dump class " + actions.getName());
XposedBridge.log("Methods"); // 获取到指定名称类声明的所有方法的信息
Method[] m = actions.getDeclaredMethods();
// 打印获取到的所有的类方法的信息
for (int i = 0; i < m.length; i++) { XposedBridge.log(m[i].toString());
} XposedBridge.log("Fields");
// 获取到指定名称类声明的所有变量的信息
Field[] f = actions.getDeclaredFields();
// 打印获取到的所有变量的信息
for (int j = 0; j < f.length; j++) { XposedBridge.log(f[j].toString());
} XposedBridge.log("Classes");
// 获取到指定名称类中声明的所有内部类的信息
Class<?>[] c = actions.getDeclaredClasses();
// 打印获取到的所有内部类的信息
for (int k = 0; k < c.length; k++) { XposedBridge.log(c[k].toString());
}
}
} /**
* 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...)
*/
/* 目标java方法的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...) */
/* 目标java方法的Hook
public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback);
}*/ /**
* Loads the class with the specified name. Invoking this method is
* equivalent to calling {@code loadClass(className, false)}.
* <p>
* <strong>Note:</strong> In the Android reference implementation, the
* second parameter of {@link #loadClass(String, boolean)} is ignored
* anyway.
* </p>
*
* @return the {@code Class} object.
* @param className
* the name of the class to look for.
* @throws ClassNotFoundException
* if the class can not be found.
*/
//public Class<?> loadClass(String className) throws ClassNotFoundException {
// return loadClass(className, false);
// }
Xposed Hook处理Android应用打印Log日志的结果截图:

Xposed框架Hook Android应用的所有类方法打印Log日志的更多相关文章

  1. Android开发华为手机无法看log日志解决方法

    Android开发华为手机无法看log日志解决方法 上班的时候,由于开发工具由Eclipse改成Android Studio后,原本的华为手机突然无法查看崩溃日志了,大家都知道,若是无法查看日志要它毛 ...

  2. Xposed 框架 hook 简介 原理 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. android 华为、魅族手机无法打印 Log 日志的问题

    最近使用魅族真机测试 App 时,发现 LogCat 不显示项目工程中通过Log.d()和Log.v()打印的 debug 和 verbose 级别的日志,甚是奇怪,通过 debug 模式断点调试也没 ...

  4. android手机调试时不能打印Logcat日志信息

    方法: 1.在拨号界面输入:*#*#2846579#*#*  进入测试菜单界面 2.Project Menu–后台设置–LOG设置 3.LOG开关–LOG打开   LOG级别设置–VERBOSE 4. ...

  5. [转]Android中Xposed框架篇—利用Xposed框架实现拦截系统方法

    一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...

  6. [转载] Android中Xposed框架篇---利用Xposed框架实现拦截系统方法

    本文转载自: http://www.wjdiankong.cn/android%E4%B8%ADxposed%E6%A1%86%E6%9E%B6%E7%AF%87-%E5%88%A9%E7%94%A8 ...

  7. android黑科技系列——Xposed框架实现拦截系统方法详解

    一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...

  8. Xposed框架之函数Hook学习

    作者:Fly2015 Xposed是Android下Java层的开源Hook框架类似的有cydiasubstrate框架而且据说cydiasubstrate框架能实现Android的Java层和Nat ...

  9. Android Xposed框架出现java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation问题

    第一次玩Xposed框架,按照多个demo的格式写了一个demo发现死活不进入 public abstract void handleLoadPackage(LoadPackageParam lppa ...

随机推荐

  1. Ubuntu 18.04下Intel SGX应用程序程序开发——获得OCALL调用的返回值

    本文中,我们介绍在Enclave函数中调用不可信OCALL函数,并获得OCALL函数的返回值. 1. 复制SampleEnclave示例并建立自己的OcallRetSum项目 SampleEnclav ...

  2. 追溯 MySQL Statement Cancellation Timer

    原文 1. 背景 在 jstack 的内容中可以看到以下的 MySQL Statement Cancellation Timer 守护线程, 在业务高峰期的时候会出现大量的这类守护线程, 由此追溯该线 ...

  3. canal mysql select权限粒度

    今天产品问了一个问题,问懵了 产品:canal在开通mysql权限时需要哪些权限 我:SELECT, REPLICATION SLAVE, REPLICATION CLIENT 产品:那SELECT权 ...

  4. C#类中的成员

    @ 目录 字段 属性 方法 构造函数 类和对象的简单解释 创建类和对象 类中成员的归属问题 字段 字段的声明与声明变量类似,可以添加访问修饰符,通常情况下字段设置为私有的,然后定义属性对字段的读写进行 ...

  5. 【python+selenium的web自动化】- Selenium WebDriver原理及安装

    简单介绍 selenium ​ selenium是一个用于测试web网页的自动化测试工具,它直接运行在浏览器中,模拟用户的操作.

  6. php伪协议分析与CTF例题讲解

                本文大量转载于:https://blog.csdn.net/qq_41289254/article/details/81388343 (感谢博主) 一,php://  访问输入 ...

  7. pandas函数的使用

    一.Pandas的数据结构 1.Series Series是一种类似与一维数组的对象,由下面两个部分组成: values:一组数据(ndarray类型) index:相关的数据索引标签 1)Serie ...

  8. window 10 下 --excel | power query 通过 ODBC链接 mysql 数据库

    excel链接到mysql的方法有几种,今天主要介绍如何通过ODBC链接 odbc是 "开放数据库连接",你可以通过下载插件使得自己的excel可以连接到不同的数据库. 关于版本的 ...

  9. 【Azure API 管理】APIM CORS策略设置后,跨域请求成功和失败的Header对比实验

    在文章"从微信小程序访问APIM出现200空响应的问题中发现CORS的属性[terminate-unmatched-request]功能"中分析了CORS返回空200的问题后,进一 ...

  10. XUPT-D

    /*     泰泰学长又来玩数字了,泰泰学长想让你帮他求1-n的和,但是这次的求和可不是简单的1+2+...+n. 这次的求和是这样的,如果加到一个数字是2的指数倍,那就不加,反而减掉这个数.    ...