《Arthas系列三》Arthas的程序入口java agent,Java程序的后门

Posted 香菜聊游戏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Arthas系列三》Arthas的程序入口java agent,Java程序的后门相关的知识,希望对你有一定的参考价值。

agent 是什么?

Java Agent 是 Java 虚拟机提供的一整套后门,通过这套后门可以对虚拟机方方面面进行监控与分析,甚至干预虚拟机的运行。直白点理解你可以控制你的程序,想做什么东西都可以。

agent 怎么用?

启动java agent 有两种方式:

一种是在程序启动的时候,启动agent,我们的本地调试就是通过这种方式。

一种是在程序启动之后,正常运行的时候,在自己想控制的时候attach上去,远程调试就是通过这种方式。 Attach 机制的核心组件是 Attach Listener,顾名思义,Attach Listener 是 JVM 内部的一个线程,这个线程的主要工作是监听和接收客户端进程通过 Attach 提供的通信机制发起的命令,你调试的时候看到过这个线程吗? 现在知道是怎么使用了吧。

可以看到调试的核心技术就是这个了,打开了大门,至于其他都是业务层面了。

agent 的技术

实现premain方法,在JVM启动前加载

实现agentmain方法,在JVM启动后attach加载

说太多也没啥用,直接来个例子吧。

创建2个maven项目, 一个是agent项目,一个是test项目

agent代码

我们看下源码,先看agent,因为这个需要注意的比较少

package com.pdool;

import java.lang.instrument.Instrumentation;

/**
 * Hello world!
 */
public class App 
    // 随程序启动的时候调用
    public static void premain(String agentArgs, Instrumentation instrumentation) 
        sayHello(agentArgs, instrumentation, "premain");
    

    //  attach的是调用
    public static void agentmain(String agentArgs, Instrumentation instrumentation) 
        sayHello(agentArgs, instrumentation, "agentMain");
    
    public static void sayHello(String agentArgs, Instrumentation instrumentation, String methodName) 
        System.out.println("from -----------" + methodName);
    

接着在pom.xml中增加一些打包的参数

<plugin>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.0.2</version>
  <configuration>
    <archive>
      <!--自动添加META-INF/MANIFEST.MF -->
      <manifest>
        <addClasspath>true</addClasspath>
      </manifest>
      <manifestEntries>
      <!-- 这两个记得填写全路径 -->
        <Premain-Class>com.pdool.App</Premain-Class>
        <Agent-Class>com.pdool.App</Agent-Class>
        <Can-Redefine-Classes>true</Can-Redefine-Classes>
        <Can-Retransform-Classes>true</Can-Retransform-Classes>
      </manifestEntries>
    </archive>
  </configuration>
</plugin>

这个打包的插件会自动创建MANIFEST.MF,并且修改,可以在打包完成后,看下是不是如自己的设置的 ,可以使用压缩软件打开哦,然后使用记事本查看

打包直接用maven的生命周期,package 命令就行,打包的路径就是target下面

接下来看下测试的代码

就是一个每隔2s运行一次的长须

package com.pdool;

/**
 * Hello world!
 *
 */
public class TestDemo

    public static void main(String[] args) throws InterruptedException 
        int index =0;
        System.out.println("----  start ----");
        while (true) 
            Thread.sleep(2000);
            System.out.println("Hello World!  " + index++);
        
    

接下来先验证pre-main

运行上面的testDemo 修改运行参数,添加vm参数

记得把上面的路径改为你本地的路径 运行之后就可以看到

恭喜你,你的agent已经生效了

接下来验证agent-main

先把我们的TestDemo运行起来,然后使用jps 查看我们的pid

这里可以看到我们的pid 是9520,留着备用

启动agent代码

package com.pdool;

import com.sun.tools.attach.VirtualMachine;

import java.util.Scanner;

public class AttachTest 
    public static void main(String[] args) throws Exception 
        Scanner scanner = new Scanner(System.in);
        int pid = scanner.nextInt();
        VirtualMachine virtualMachine = VirtualMachine.attach(String.valueOf(pid));
        virtualMachine.loadAgent("E:\\github\\JavaAgentDemo\\target\\JavaAgentDemo-1.0-SNAPSHOT.jar");
        Thread.sleep(10000L);
        virtualMachine.detach();
    

如果你想运行上面的代码,会发现无法导包,是因为pom中需要配置tools.jar

<dependency>
  <groupId>jdk.tools</groupId>
  <artifactId>jdk.tools</artifactId>
  <version>1.8.0</version>
  <scope>system</scope>
  <systemPath>C:/Program Files/Java/jdk1.8.0_121/lib/tools.jar</systemPath>
</dependency>

这里面有几点需要注意: 1、包的id 是jdk.tools

2、本地路径要换成你机器的路径,同时不能使用\\ 要用linux的/

3、scope 是是system

接下来启动AttackTest,然后输入上面的pid,转到TestDemo 就可以看到输出。 你就可以启动你的agent,这也是Arthas的使用方式。

Arthas 对agent 的使用

Arthas的使用基本上是上面的第二种,因为一般生产环境没有人会在服务启动的时候直接把Arthas启动起来,就像没有人会随身携带一个医生是一样的。 Arthas的使用将上面的直接合并了,在启动之后会列出所有的皮豆,然后直接选择,attach上去

总结

java agent 在平常的开发中使用不多,但是功能很强大

以上是关于《Arthas系列三》Arthas的程序入口java agent,Java程序的后门的主要内容,如果未能解决你的问题,请参考以下文章

JVM实战系列「监控调优体系」实战开发arthas-spring-boot-starter监控你的微服务是否健康!

JVM实战系列「监控调优体系」实战开发arthas-spring-boot-starter监控你的微服务是否健康

《Arthas系列一》搭建调试环境,千里之行始于足下

《Arthas系列一》搭建调试环境,千里之行始于足下

Java程序员线上排查问题神器-Arthas

JVM实战系列「监控调优体系」针对于Alibaba-Arthas的安装入门及基础使用开发实战指南