如何使用工具打印出Java运行时中调用的所有方法? [英] How to print out all methods called during runtime in Java using instrumentation?

查看:118
本文介绍了如何使用工具打印出Java运行时中调用的所有方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to print out all methods that get called during runtime. They should be printed out in the order that they're called in and if they're called multiple times, they should be printed multiple times.

这可用于反向工程-查看按下按钮或执行特定操作时要调用的功能.

This can be used for reverse engineering - seeing which functions get called when you press a button or do a specific action.

我想为此使用Java代理和工具.

I want to use Java agents and instrumentation for this.

推荐答案

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

This can be done using Java Agents and an instrumentation library.

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

Java agent - Separate code that can be made to run before the main part of the code.

仪器-在程序加载期间更改源代码.

Instrumentation - Changing the source code during the load-time of a program.

(取自 appcrawler ,并稍作修改):

(taken from appcrawler and modified slightly):

agent.jar源代码:

The agent.jar source code:

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());
  } 
}

MANIFEST.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/中).不知道第二个是否必要,但是文章说这是出于某种原因.

Take these files and package them into a jar file. Also make sure to include files from javassist.jar (downloadable from www.javassist.org) and tools.jar (found in Program Files/Java/jdk/lib/). Not sure if the second one is necessary, but the article says it is for some reason.

现在您可以将该jar文件用作Java代理.

Now you can use this jar file as a java agent.

java -javaagent:agent.jar YourJavaProgram

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

And voila. The java agent will instrument all methods and print out every method called during execution.

这篇关于如何使用工具打印出Java运行时中调用的所有方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆