Java agent agent practice

foreword

        The java agent provides a mechanism that allows developers to manipulate the virtual machine to achieve some special functions to a certain extent, so as to manage and monitor the virtual machine to a greater extent. Combined with the actual application situation, it can be found that some applications actually use this mechanism to achieve such as software cracking, anti-cracking, jvm resource monitoring, hot update, debugging, etc. For example, our commonly used development tool idea can be cracked by adding the -javaagent option to the jvm virtual machine parameter, because a jvm process is loaded when idea starts, which is also the premise of cracking.

Similarly, when running a java program in idea, you can also find the shadow of javaagent from the command line parameters of the console

yī,javaagent、agentlib、agentpath

When opening cmd.exe to view the java command help, the usage methods of these three agents are listed

1) The method used is different for the running java process and the unstarted java process

     For unstarted processes, you only need to add options such as -agentlib, -agentpath and -javaagent to modify the command line parameters.

     For the running process, you need to write an independent java process, and inject the jar package or dll dynamic link library into the running java process . This requires the tools.jar package, which is located under the jdk directory \lib. This package is very powerful, and the tools commonly used by jdk have corresponding implementations in this package, such as javac, jinfo, jar, etc.

In the above example program, all jvm processes are listed first, and a WindowsVirtualMachine class object represents a

The running java process injects the jar package file path into the corresponding jvm process through the loadAgent method. We know that the jdk tool jps can also list all java processes, and the principle is roughly the same.

The jar package passed by loadAgent needs to meet certain specifications before it can be successfully injected. A class needs to be implemented in the jar package. This class contains two methods premain and agentmain. The parameters of these two methods are consistent. When calling loadAgent or specifying the command line parameters When -javaagent, jvm will transfer control to these two methods, here,

The instrumentation parameter is the core object, and the main operations of our agent plug-in revolve around this object.

Using redefineClasses, we can redefine a class that has been loaded in jvm. The result of redefinition is that the class class can be modified at runtime, that is, we can change the execution logic of the class without restarting the java application .

However, there are certain limitations in this redefinition. The commonly used hotspot virtual machine can only modify the class method body, and some non-mainstream virtual machine implementations can add/modify/delete fields and methods.

 

The implementation of this class is located in the jdk directory \bin\instrument.dll

It can be found that the exported functions in the dll basically correspond to the method names in the instrument interface class. The InstrumentImpl implementation class is a bound native method. Checking the InstrumentImpl implementation class also verifies this point. loadClassAndCallFromPremain and loadClassAndCallAgentmain call premain respectively and agentmain entry method

Printing the call stack does the same

 

Generally, the native method we declare in the class can be bound through System.loadLibrary.

 

2) If we use -javaagent, we only need to write java code to realize it, but if we use -agentlib and -agentpath, we have a certain c/c++ programming foundation. It is obvious that the agent jar package written in java controls the granularity of the jvm

It is weaker than the agent library implemented by c/c++, and the agent library written by dll is more powerful. Of course, it needs to meet certain specifications,

Need to implement two functions Agent_OnLoad and Agent_OnUnload

We found that the instrument.dll above actually implements these two functions, so javagent actually adds a layer on top of agentlib to transfer control.

Using agentlib and agentpath, we directly manipulate the jniEnv object for some more fine-grained operations. For example, use DefineClass to directly define a memory class based on the byte array, and the ClassLoader of this memory class can be null.

An example of calling with command line parameters is as follows

It was found that the Agent was indeed called

Guess you like

Origin blog.csdn.net/weixin_38526093/article/details/128944040