ddostest123

0x01 Java Agent

JavaAgent有两种使用方式。

  1. 第一种是在 JVM启动的时候加载,通过 javaagent 启动参数,在程序main方法执行之前执行agent 中的premain 方法。

  2. 第二种方式是在 JVM启动后进行Attach,通过Attach API进行加载,在agent加载以后执行agentmain 方法。

0x02 javaagent

对于第一种方式,javaagent是java命令的其中一个参数,-javaagent用于指定一个 jar 包,可装载多个agent。

其与java.lang.instrument有关,java.lang.instrument在jre中lib里面的rt.jar包。

image-20221127010052017

对于javaagent的jar包,其需满足:

  • MANIFEST.MF文件必须指定Premain-Class。

  • Premain-Class指定的类必须实现一个公共静态premain方法。

image-20221127011151878

https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html

JVM初始化后,执行premain方法,再执行main方法。
该premain方法的定义为:

public static void premain(String agentArgs, Instrumentation inst);
public static void premain(String agentArgs);

JVM初始化后会先加载定义了Instrumentation的第一种类型方法,加载成功则忽略第二种。

如果第一种类型没定义,则加载第二种方法。

image-20221127013127872

在rt.jar包的java.lang.instrument中,Instrumentation接口定义了若干个方法:

image-20221127013442172

https://www.cnblogs.com/rickiyang/p/11368932.html

public interface Instrumentation {
    void addTransformer(ClassFileTransformer var1, boolean var2);
    void addTransformer(ClassFileTransformer var1);
    boolean removeTransformer(ClassFileTransformer var1);
    boolean isRetransformClassesSupported();
    void retransformClasses(Class<?>... var1) throws UnmodifiableClassException;
    boolean isRedefineClassesSupported();
    void redefineClasses(ClassDefinition... var1) throws ClassNotFoundException, UnmodifiableClassException;
    boolean isModifiableClass(Class<?> var1);
    Class[] getAllLoadedClasses();
    Class[] getInitiatedClasses(ClassLoader var1);
    long getObjectSize(Object var1);
    void appendToBootstrapClassLoaderSearch(JarFile var1);
    void appendToSystemClassLoaderSearch(JarFile var1);
    boolean isNativeMethodPrefixSupported();
    void setNativeMethodPrefix(ClassFileTransformer var1, String var2);
}

其中,常用的方法的作用如下:

  1. 增加Class文件的转换器,用于改变 Class 二进制流的数据,参数 canRetransform 设置是否允许重新转换。

void addTransformer(ClassFileTransformer var1, boolean var2);

  1. 增加Class文件的转换器,在类加载之前,重新定义 Class 文件,ClassDefinition 表示对一个类新的定义。

void addTransformer(ClassFileTransformer var1);

  1. 读取Class文件的转换器,读取重新定义 的Class 文件。

void redefineClasses(ClassDefinition... var1) throws ClassNotFoundException, UnmodifiableClassException;

  1. 重读取Class文件的转换器,如果在类加载之后,需要使用 retransformClasses 方法重新定义。对于已经加载过的类,可以使用retransformClasses来重新触发这个Transformer的拦截。

void retransformClasses(Class<?>... var1) throws UnmodifiableClassException;

  1. 删除Class文件的转换器,删除重新定义 的Class 文件。

boolean removeTransformer(ClassFileTransformer var1);

0x03 Before main

1、测试demo

image-20221127020223527

2、测试agent

image-20221127020350545

3、装载agent

image-20221127020638912

可以看到premain方法先main方法执行。

0x04 Replace Return

1、测试demo

image-20221127180015536

通过Javaagent,在main方法加载执行前,将num方法中的返回值修改为2。

2、测试agent

image-20221127180500558

通过premain方法,调用增加Class文件的转换器addTransformer来改变 Class 二进制流的数据。

接着继承和重写ClassFileTransformer类中的transform方法,

在定位修改的目标类和方法后,通过使用javassist来修改目标方法中的代码和返回值。

3、装载agent

image-20221127181419465

最后成功修改目标方法的代码和返回值。

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

$ hexo new "My New Post"

More info: Writing

Run server

$ hexo server

More info: Server

Generate static files

$ hexo generate

More info: Generating

Deploy to remote sites

$ hexo deploy

More info: Deployment