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

在进行Android程序的逆向分析的时候,经常需要Android程序的静态分析和动态调试的结合,尤其是对一些加固后的Android类方法被调用的确认,需要Hook java类方法打印java类方法的调用堆栈。有幸在网上看到了这篇文章《XPosed暴力列举Package下所有的方法调用》,按照作者的思路和代码进行了验证和尝试,发现效果并不明显而且不好用,对多dex的Android应用支持不好,因此在此基础上调整了一下思路,简单的写了份xposed Hook代码,如下:
  1. package com.xposed.enumeratorClassHook;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import java.lang.reflect.Modifier;
  5. import de.robv.android.xposed.IXposedHookLoadPackage;
  6. import de.robv.android.xposed.XC_MethodHook;
  7. import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
  8. import de.robv.android.xposed.XposedBridge;
  9. import de.robv.android.xposed.XposedHelpers;
  10. import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
  11. import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
  12. // 自定义的回调函数接口
  13. public class Module implements IXposedHookLoadPackage {
  14. static String strClassName = "";
  15. @Override
  16. public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
  17. // 被Hook操作的目标Android应用的包名,进行Hook操作的过滤
  18. String strPackageName = "com.guji.loveparty";
  19. if (lpparam.packageName.equals(strPackageName)) {
  20. XposedBridge.log("Loaded App:" + lpparam.packageName);
  21. // // 枚举指定Android应用的所有类方法并对指定的类方法进行java Hook操作
  22. // PackageHooker packageHooker = new PackageHooker(lpparam);
  23. // // 获取指定类的方法、属性变量、内部类等的信息
  24. // ClassLoader classLoader = lpparam.classLoader;
  25. // Class<?> dumpClass = XposedHelpers.findClass("com.tencent.bugly.lejiagu.crashreport.BuglyLog", classLoader);
  26. // packageHooker.dumpClass(dumpClass);
  27. // // 被Hook操作的目标类的名称
  28. // String strNomalCln = "";
  29. // // 被Hook操作的目标类的方法的名称
  30. // String strNomalMdn = "";
  31. // // 在Android应用默认的classes.dex文件中的类方法的Hook操作
  32. // XposedHelpers.findAndHookMethod(
  33. // // 被Hook操作的目标类
  34. // strNomalCln,
  35. // lpparam.classLoader,
  36. // // 被Hook操作的目标类方法
  37. // strNomalMdn,
  38. // // 被Hook操作的目标类方法的第1个参数的类型
  39. // String.class,
  40. // // 被Hook操作的目标类方法的第2个参数的类型
  41. // String.class,
  42. // new XC_MethodHook() {
  43. // // 在被Hook操作的类方法执行之前执行代码
  44. // @Override
  45. // protected void beforeHookedMethod(MethodHookParam param)
  46. // throws Throwable {
  47. //
  48. // // 打印被Hook操作的目标类方法的第1个参数值
  49. // XposedBridge.log("beforeHookedMethod 第1个参数:" + param.args[0]);
  50. // // 打印被Hook操作的目标类方法的第2个参数值
  51. // XposedBridge.log("beforeHookedMethod 第2个参数:" + param.args[1]);
  52. //
  53. // // 打印被Hook操作的目标类方法的函数返回值ֵ
  54. // XposedBridge.log("beforeHookedMethod result:" + param.getResult());
  55. // }
  56. //
  57. // // 在被Hook操作的类方法执行之后执行代码
  58. // @Override
  59. // protected void afterHookedMethod(MethodHookParam param)
  60. // throws Throwable {
  61. //
  62. // // 打印被Hook操作的目标类方法的第1个参数值
  63. // XposedBridge.log("afterHookedMethod userName:" + param.args[0]);
  64. // // 打印被Hook操作的目标类方法的第2个参数值
  65. // XposedBridge.log("afterHookedMethod sn:" + param.args[1]);
  66. //
  67. // // 修改被Hook操作的目标类方法的函数返回值
  68. // param.setResult(true);
  69. //
  70. // // 打印被Hook操作的目标类方法的函数返回值ֵ
  71. // XposedBridge.log("afterHookedMethod 函数返回值:" + param.getResult());
  72. // }
  73. // });
  74. // 不在Android应用默认的classes.dex文件中的类方法的Hook操作,例如:
  75. // 1.MultiDex情况下的,多dex文件中的类方法的Hook操作,例如:classes1.dex中的类方法
  76. // 2.主dex加载的jar(包含dex)情况下的,类方法的的Hook操作
  77. // Hook类方法ClassLoader#loadClass(String)
  78. findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {
  79. // 在类方法loadClass执行之后执行的代码
  80. @Override
  81. protected void afterHookedMethod(MethodHookParam param) throws Throwable {
  82. // 参数的检查
  83. if (param.hasThrowable()) {
  84. return;
  85. }
  86. // 获取指定名称的类加载之后的Class<?>
  87. Class<?> clazz = (Class<?>) param.getResult();
  88. // 获取加载的指定类的名称
  89. String strClazz = clazz.getName();
  90. XposedBridge.log("LoadClass : "+strClazz);
  91. // // 被Hook操作的目标类名称
  92. // String strClazzName = "";
  93. // // 被Hook操作的类方法的名称
  94. // String strMethodName = "";
  95. // 所有的类都是通过loadClass方法加载的
  96. // 过滤掉Android系统的类以及一些常见的java类库
  97. if (!strClazz.startsWith("android.")
  98. && !strClazz.startsWith(".system")
  99. && !strClazz.startsWith("java.")
  100. && !strClazz.startsWith("org.")
  101. && !strClazz.contains("umeng.")
  102. && !strClazz.contains("com.google")
  103. && !strClazz.contains(".alipay")
  104. && !strClazz.contains(".netease")
  105. && !strClazz.contains(".alibaba")
  106. && !strClazz.contains(".pgyersdk")
  107. && !strClazz.contains(".daohen")
  108. && !strClazz.contains(".bugly")
  109. && !strClazz.contains("mini")
  110. && !strClazz.contains("xposed")) {
  111. // 或者只Hook加密算法类、网络数据传输类、按钮事件类等协议分析的重要类
  112. // 同步处理一下
  113. synchronized (this.getClass()) {
  114. // 获取被Hook的目标类的名称
  115. strClassName = strClazz;
  116. //XposedBridge.log("HookedClass : "+strClazz);
  117. // 获取到指定名称类声明的所有方法的信息
  118. Method[] m = clazz.getDeclaredMethods();
  119. // 打印获取到的所有的类方法的信息
  120. for (int i = 0; i < m.length; i++) {
  121. //XposedBridge.log("HOOKED CLASS-METHOD: "+strClazz+"-"+m[i].toString());
  122. if (!Modifier.isAbstract(m[i].getModifiers()) // 过滤掉指定名称类中声明的抽象方法
  123. && !Modifier.isNative(m[i].getModifiers()) // 过滤掉指定名称类中声明的Native方法
  124. && !Modifier.isInterface(m[i].getModifiers()) // 过滤掉指定名称类中声明的接口方法
  125. ) {
  126. // 对指定名称类中声明的非抽象方法进行java Hook处理
  127. XposedBridge.hookMethod(m[i], new XC_MethodHook() {
  128. // 被java Hook的类方法执行完毕之后,打印log日志
  129. @Override
  130. protected void afterHookedMethod(MethodHookParam param) throws Throwable {
  131. // 打印被java Hook的类方法的名称和参数类型等信息
  132. XposedBridge.log("HOOKED METHOD: "+strClassName+"-"+param.method.toString());
  133. }
  134. });
  135. }
  136. }
  137. }
  138. // // 所有的类都是通过loadClass方法加载的
  139. // // 所以这里通过判断全限定类名,查找到被Hook操作的目标类
  140. // if (strClazz.contains(strClazzName)) {
  141. //
  142. // // Hook目标类方法
  143. // findAndHookMethod(clazz,
  144. // // 被Hook操作的类方法的名称
  145. // strMethodName,
  146. // // 被Hook操作的类方法的参数类型
  147. // //paramTypes, // 根据实际情况进行修改
  148. // new XC_MethodHook() {
  149. // @Override
  150. // protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  151. //
  152. // // ......
  153. //
  154. // // 打印被Hook操作的目标类方法的第1个参数值
  155. // XposedBridge.log("beforeHookedMethod 第1个参数:" + param.args[0]);
  156. // // 打印被Hook操作的目标类方法的第2个参数值
  157. // XposedBridge.log("beforeHookedMethod 第2个参数:" + param.args[1]);
  158. //
  159. // // ......
  160. // }
  161. //
  162. // @Override
  163. // protected void afterHookedMethod(MethodHookParam param) throws Throwable {
  164. //
  165. // // ......
  166. //
  167. // // 打印被Hook操作的目标类方法的函数返回值ֵ
  168. // XposedBridge.log("afterHookedMethod 函数返回值:" + param.getResult());
  169. //
  170. // // ......
  171. // }
  172. // });
  173. // }
  174. // ......
  175. }
  176. }
  177. });
  178. }
  179. }
  180. // 获取指定名称的类声明的类成员变量、类方法、内部类的信息
  181. public void dumpClass(Class<?> actions) {
  182. XposedBridge.log("Dump class " + actions.getName());
  183. XposedBridge.log("Methods");
  184. // 获取到指定名称类声明的所有方法的信息
  185. Method[] m = actions.getDeclaredMethods();
  186. // 打印获取到的所有的类方法的信息
  187. for (int i = 0; i < m.length; i++) {
  188. XposedBridge.log(m[i].toString());
  189. }
  190. XposedBridge.log("Fields");
  191. // 获取到指定名称类声明的所有变量的信息
  192. Field[] f = actions.getDeclaredFields();
  193. // 打印获取到的所有变量的信息
  194. for (int j = 0; j < f.length; j++) {
  195. XposedBridge.log(f[j].toString());
  196. }
  197. XposedBridge.log("Classes");
  198. // 获取到指定名称类中声明的所有内部类的信息
  199. Class<?>[] c = actions.getDeclaredClasses();
  200. // 打印获取到的所有内部类的信息
  201. for (int k = 0; k < c.length; k++) {
  202. XposedBridge.log(c[k].toString());
  203. }
  204. }
  205. }
  206. /**
  207. * Look up a method and place a hook on it. The last argument must be the callback for the hook.
  208. * @see #findMethodExact(Class, String, Object...)
  209. */
  210. /* 目标java方法的Hook
  211. public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {
  212. if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length-1] instanceof XC_MethodHook))
  213. throw new IllegalArgumentException("no callback defined");
  214. XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];
  215. Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));
  216. return XposedBridge.hookMethod(m, callback);
  217. }*/
  218. /** @see #findAndHookMethod(Class, String, Object...) */
  219. /* 目标java方法的Hook
  220. public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
  221. return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback);
  222. }*/
  223. /**
  224. * Loads the class with the specified name. Invoking this method is
  225. * equivalent to calling {@code loadClass(className, false)}.
  226. * <p>
  227. * <strong>Note:</strong> In the Android reference implementation, the
  228. * second parameter of {@link #loadClass(String, boolean)} is ignored
  229. * anyway.
  230. * </p>
  231. *
  232. * @return the {@code Class} object.
  233. * @param className
  234. * the name of the class to look for.
  235. * @throws ClassNotFoundException
  236. * if the class can not be found.
  237. */
  238. //public Class<?> loadClass(String className) throws ClassNotFoundException {
  239. // return loadClass(className, false);
  240. // }
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. HDu1087 Super Jumping! Jumping! Jumping!

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1087 分析:简单dp:dp[i] = max (dp[i], dp[j] + a[i]) 1 #inc ...

  2. 小程序基于Token登录 示意图

  3. 什么原因才是阻碍Linux桌面发展的罪魁祸首

    我大概2000年上大学在宿舍开始玩Linux,到现在20年了!也算是最早一批痴迷于Linux桌面用户啦!记得当时的毕业设计BBS论坛开发就是在Mandrake Linux(后改名Mandriva,一种 ...

  4. idea添加本地文件约束(DTD)

    当我们做 xml 文件配置的时候,需要对其进行约束的配置 例如: hibernate 如果我们在联网的情况下是可以不添加配置文件约束的,红框内的 URL 会自动帮我们从网络上加载约束文件,但是没有网络 ...

  5. wireshark如何抓取分析https的加密报文

    [问题概述] https流量基于ssl/tls加密,无法直接对报文进行分析. [解决方案] 方案1 -- 利用"中间人攻击"的代理方式抓包分析.整个方案过程比较简单,这里不赘述,大 ...

  6. java基础详解-集合

    一.集合组成 java集合主要由Map和Collection组成,Collection主要类图如下(图片来源于网络,懒得画图): 从上图中能很明显的看出来Collection下主要是Set.List和 ...

  7. 冒泡排序算法的实现(Java)

    什么是冒泡排序 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法.它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小.首字母从Z到A)错误就把他们交换 ...

  8. 【JVM进阶之路】一:Java虚拟机概览

    1.Java简史 Java语言是一门通用的.面向对象的.支持并发的程序语言.全球从事Java相关开发的人员已经数以百万计. 从1995年"Java"正式出现以来,Java已经经历了 ...

  9. ASP.NET Core分布式日志系统ELK实战演练

    一.ELK简介  ELK是Elasticsearch.Logstash和Kibana首字母的缩写.这三者均是开源软件,这三套开源工具组合起来形成了一套强大的集中式日志管理平台. •  Elastics ...

  10. java例题_11 求不重复数

    1 /*11 [程序 11 求不重复数字] 2 题目:有 1.2.3.4 这四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 3 程序分析:可填在百位.十位.个位的数字都是 1.2.3. ...