如何使用检测打印 Java 运行时调用的所有方法?

2023-11-30

我想打印出在运行时调用的所有方法。它们应该按照调用的顺序打印出来,如果多次调用它们,则应该打印多次。

这可用于逆向工程 - 查看当您按下按钮或执行特定操作时调用哪些函数。

我想为此使用 Java 代理和仪器。


这可以使用 Java 代理和检测库来完成。

Java 代理 - 可以在代码主要部分之前运行的单独代码。

检测 - 在程序加载期间更改源代码。

使其工作的代码

(取自应用程序爬虫并稍作修改):

agent.jar源代码:

SimpleTransformer.java:

package test;

import java.security.*;
import java.lang.instrument.*;
import java.util.*;
import javassist.*;
 
public class SimpleTransformer implements ClassFileTransformer {
 
  public SimpleTransformer() {
    super();
  }
 
  public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
    return transformClass(redefiningClass,bytes);
  }
 
  private byte[] transformClass(Class classToTransform, byte[] b) {
    ClassPool pool = ClassPool.getDefault();
    CtClass cl = null;
    try {
      cl = pool.makeClass(new java.io.ByteArrayInputStream(b));
      CtBehavior[] methods = cl.getDeclaredBehaviors();
      for (int i = 0; i < methods.length; i++) {
        if (methods[i].isEmpty() == false) {
          changeMethod(methods[i]);
        }
      }
      b = cl.toBytecode();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    catch (Throwable t) {
      t.printStackTrace();
    }
    finally {
      if (cl != null) {
        cl.detach();
      }
    }
    return b;
  }
 
  private void changeMethod(CtBehavior method) throws NotFoundException, CannotCompileException {
    /*if (method.getName().equals("doIt")) {
      method.insertBefore("System.out.println(\"started method at \" + new java.util.Date());");
      method.insertAfter("System.out.println(\"ended method at \" + new java.util.Date());");
    }*/
    

  
          //MY CODE
      //!Modifier.isAbstract(method.getModifiers()) -- abstract methods can't be modified. If you get exceptions, then add this to the if statement.
      //native methods can't be modified.
      if (!Modifier.isNative(method.getModifiers())) {
          String insertString = "System.out.println(\"started method " + method.getName() + "\");";
          method.insertBefore(insertString);
      }
  }

SimpleMain.java:

package test;

import java.lang.instrument.Instrumentation;

public class SimpleMain {
  public static void premain(String agentArguments, Instrumentation instrumentation) {  
    instrumentation.addTransformer(new SimpleTransformer());
  } 
}

清单.mf:

Manifest-Version: 1.0
Boot-Class-Path: javassist.jar
Premain-Class: test.SimpleMain

获取这些文件并将它们打包成 jar 文件。还要确保包含 javassist.jar 中的文件(可从www.javassist.org)和tools.jar(位于Program Files/Java/jdk/lib/)。不确定第二个是否有必要,但文章说这是出于某种原因。

现在您可以使用这个 jar 文件作为 java 代理。

java -javaagent:agent.jar YourJavaProgram

瞧。 java代理将检测所有方法并打印出执行期间调用的每个方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用检测打印 Java 运行时调用的所有方法? 的相关文章

随机推荐

  • android - 如何使按钮闪烁?

    有没有什么方法 在代码中 使按钮持续闪烁 然后在按下时停止闪烁 有几种 具体取决于您所指的闪烁类型 例如 您可以使用 alpha 动画并在按钮第一次出现时启动它 当用户单击按钮时 在您的OnClickListener做就是了clearAni
  • 将围绕 sockaddr_storage 和 sockaddr_in 进行转换,打破严格的别名

    继我之前的question 我真的很好奇这段代码 case AF INET struct sockaddr in tmp reinterpret cast
  • 将原始 HTTP 请求转换为 HTTPWebRequest 对象

    在 NET 中 是否可以将原始 HTTP 请求转换为 HTTPWebRequest 对象 我确信 NET 内部正在这样做 知道 NET 的哪一部分实际上在处理这个问题吗 我可以调用它吗 或者是否有任何允许原始 HTTP 连接的外部库 我不相
  • dart 中的转义“正则表达式”

    我正在尝试捕获 dart 正则表达式中的符号 我的正则表达式如下所示 RegExp containsSymbolRegExp RegExp r lt gt 但是 我还需要让它捕获符号 但我不能把 放在那里 因为它会弄乱字符串 有什么想法如何
  • 如何比较数组中的日期以找到最早的日期?

    我有一个名为 dateArray 的变量 其中包含日期 例如 09 09 2009 16 07 2010 29 01 2001 我想用 for 循环找到最早的一个 所以结果是 29 01 2001 or dateArray 2 语言是jav
  • 选择窗口无法选择子窗口

    在我的 Java 代码中 单击 编辑描述 链接后 将打开一个窗口 即 Java 脚本窗口 此处的图像第一个给出带有属性的锚标记 第二个打开窗口 Image 1 Image 2 Window image Along with Page Sou
  • 在Python中将字符串二维列表转换回二维列表[重复]

    这个问题在这里已经有答案了 我刚刚开始玩Python 我知道我们可以使用 str 将任何列表转换为字符串 喜欢 gt gt gt l 1 1 2 2 3 3 gt gt gt l 1 1 2 2 3 3 gt gt gt type l
  • 太多的回溯:为什么这里有“重做”?

    我正在 Prolog 中做一个非常简单的练习 但跟踪中有些东西我不明白 该程序是一个 大于 gt 对表示为后继的整数 greater than succ 0 greater than succ A succ B greater than A
  • 如何清除p:dataTable中的所有输入字段?

    我将 JSF 2 0 与 PrimeFaces 一起使用 我有一个
  • CSS 位置 - 顶部 100% 不等于底部 0

    我在分配时注意到了这一点fixed定位到 css3 动画的元素 即top 100 没有得到相同的效果bottom 0 它定位文档外部的元素 而bottom 0 仍然显示整个元素 JSFiddle演示 css位置有相反的吗top 0 这会自动
  • Yocto 中支持 PHP 的 Apache2

    我正在使用 Yocto 创建一个包含 apache2 的构建 但我很难添加 php 支持 我之前运行过它 阅读 去年 但从那时起 meta openembedded 中的meta webserver 层发生了变化 来自元网络服务器中的自述文
  • 将外部 javascript 导入到 google apps 脚本 [重复]

    这个问题在这里已经有答案了 我正在尝试从 Google 电子表格 Google 文档 使用 Trello 但不确定如何导入 引用 链接使用其库所需的 javascript 文件 我唯一的其他选择是直接使用他们的 REST API 很好 但我
  • 如何在Tensorflow中将字符串张量转换为Python字符串?

    以下代码是批量数据提供程序 mat文件 但运行时出现以下问题 TypeError expected str bytes or os PathLike object not FIFOQueue 代码是 import numpy as np i
  • 强制绑定DataGridView生成列和行

    我以编程方式创建一个 DataGridView 对象 然后使用网格的 DataSource 属性将其绑定到 DataTable 创建网格后 我将其添加到 WinForms 的控件集合中 即 Form1 Controls Add grid 我
  • 银行式导航限制

    某些网络应用程序 尤其是银行网站 会阻止您使用浏览器的导航按钮 在新选项卡中打开链接甚至刷新页面 通常他们会警告您不要这样做 甚至终止会话 迫使您再次登录 他们是否遵循特定的架构模式来实现这一目标 他们的目标是什么 这如何提高安全性 他们可
  • 桌面 SWING 应用程序上的 jpa

    我正在使用 SWING 开发一个单用户桌面应用程序 我对这种使用 java sql api 的应用程序有一点经验 并发现它一点也不舒服 在我的新应用程序中 我第一次尝试使用 JPA 我阅读了很多教程 这些教程使我几乎了解了我需要的所有内容
  • 无法启用spring框架的日志记录

    我想在Spring框架和Spring Security中配置日志记录 然后按照这个http docs spring io spring docs 3 2 x spring framework reference html overview
  • 自动布局以编程方式修改约束乘数

    如何以编程方式修改约束乘数 我设置了以下内容 self view addConstraint NSLayoutConstraint constraintWithItem button attribute NSLayoutAttributeW
  • 如何使用VC++更改桌面背景

    我目前正在尝试使用 SystemParametersInfo 更改桌面背景 当我输入我的内容时 vs 不会给我任何错误 但是当我运行程序时 我收到带有黄色三角形的警告 它说 KernelBase dll 抛出了某种异常 然后它说某些 PDB
  • 如何使用检测打印 Java 运行时调用的所有方法?

    我想打印出在运行时调用的所有方法 它们应该按照调用的顺序打印出来 如果多次调用它们 则应该打印多次 这可用于逆向工程 查看当您按下按钮或执行特定操作时调用哪些函数 我想为此使用 Java 代理和仪器 这可以使用 Java 代理和检测库来完成