本文博客地址: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. .net 开源模板引擎jntemplate 实战演习:基础篇之入门

    一.简介 模板引擎是Web开发中非常重要的一环,它负责将页面上的动态内容呈现出最终的结果展现给前端用户,在asp.net mvc中,我们最熟悉的就是Razor了,作为官方的视图引擎(视图引擎不等同于模 ...

  2. [Elementary Mechanics-01]Two masses and a spring

    [Elementary Mechanics Using Python-01] Question 5.28 Two masses and a spring. Two particles of m = 0 ...

  3. Java 集合框架 04

    集合框架·Map 和 Collections集合工具类 Map集合的概述和特点 * A:Map接口概述 * 查看API可知: * 将键映射到值的对象 * 一个映射不能包含重复的键 * 每个键最多只能映 ...

  4. 测试平台系列(3) 给Hello World添加日志

    给Hello World添加日志 回顾 通过上篇内容,我们已经使用「Flask」完成了我们的第一个接口.我们可以看到,使用「Flask」来编写接口是十分简单的.那么接下来,我们丰富一下上面的例子. 需 ...

  5. div+伪元素实现太极图

    需求:使用div和伪元素实现阴阳太极图 图例: 代码: <html> <head> <title>太极图</title> <style type= ...

  6. Python基础(1)——变量和数据类型[xiaoshun]

    目录 一.变量 1.概述 Variables are used to store information to be referenced(引用)and manipulated(操作) in a co ...

  7. 仿MSDN的帮助系统

    作为软件开发人员,软件做好后,接下来就是编写文档.我自己也是做软件的,经常有用户询问软件的安装与使用, 我一直很喜欢微软的MSDN帮助系统,简介.大气,使用方便. 网上也找了很久,感觉一直没有合适的, ...

  8. 使用 Velero 跨云平台迁移集群资源到 TKE

    概述 Velero 是一个非常强大的开源工具,可以安全地备份和还原,执行灾难恢复以及迁移Kubernetes群集资源和持久卷,可以在 TKE 平台上使用 Velero 备份.还原和迁移集群资源,关于如 ...

  9. MongoDB 那些事(一文以蔽之)

    前言 身边一直都有小伙伴在问:MongoDB到底是什么?它有到底什么特性?有什么与众不同?在什么情况下使用MongoDB最合适?以什么样的姿势是最好的?难道就一定要用吗?....说实话,这些问题都问到 ...

  10. 清明|TcaplusDB持续为您保驾护航

    清明将至,又到一年休闲踏青,祭拜祖先的时机. 清明假期期间,TcaplusDB不停歇,我们将一如既往地守护您的数据,继续做您最坚实的后盾.  在未来,TcaplusDB还将以国产键值型数据库领航者的身 ...