JAVA Instrumentation初步接触

写在前面:
今天测试部发包给了一个新的jar,说是要重新使用新的部署方式进行Springboot项目的部署,命令如下:

$ java -javaagent:sjt_agent.jar -jar ***.jar

反编译后看了下jar里面的内容,是利用Java se5之后提供的java Instrumentation实现的一个加密套件,防止jar被反编译造成代码泄露等
确实内网项目安全最重要,jar里面的东西如果被泄露,确实有不小的危险因素,于是初步的了解了一下Instrumentation

什么是 JAVA Instrumentation

java Instrumentation指的是可以用独立于应用程序之外的代理(agent)程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态,替换和修改类定义等。 Java SE5中使用JVM TI替代了JVM PI和JVM DI。提供一套代理机制,支持独立于JVM应用程序之外的程序以代理的方式连接和访问JVM。java.lang.instrument是在JVM TI的基础上提供的Java版本的实现。 Instrumentation提供的主要功能是修改jvm中类的行为。 Java SE6中由两种应用Instrumentation的方式,premain(命令行)和agentmain(运行时)

premain方式

在Java SE5时代,Instrument只提供了premain一种方式,即在真正的应用程序(包含main方法的程序)main方法启动前启动一个代理程序。例如使用如下命令:

java -javaagent:agent_jar_path[=options] java_app_name
可以在启动名为java_app_name的应用之前启动一个agent_jar_path指定位置的agent jar。 实现这样一个agent jar包,必须满足两个条件:

  • 在这个jar包的manifest文件中包含Premain-Class属性,并且改属性的值为代理类全路径名。
  • 代理类必须提供一个public static void premain(String args, Instrumentation inst)或 public static void premain(String args) 方法。

当在命令行启动该代理jar时,VM会根据manifest中指定的代理类,使用于main类相同的系统类加载器(即ClassLoader.getSystemClassLoader()获得的加载器)加载代理类。
在执行main方法前执行premain()方法,如果premain(String args, Instrumentation inst)和premain(String args)同时存在时,优先使用前者。
其中方法参数args即命令中的options,类型为String(注意不是String[]),因此如果需要多个参数,需要在方法中自己处理(比如用";"分割多个参数之类);
inst是运行时由VM自动传入的Instrumentation实例,可以用于获取VM信息

初步思考

看了下面的文章后,发现还有挺多高深的知识啊(agentmain、attach、btrace...) 感叹自己这个JAVA开发工程师API初级调用工程师路还很长啊~~~

参考文章

加密套件: https://h.virbox.com/vbp/
术语&实例 https://blog.csdn.net/productshop/article/details/50623626

下一篇