JDK.attach 包解析
–> go to 总目录
JDK.attach 包解析
- 一、描述
- 二、实现原理
- 三、代码分析
- 3.1 代码结构
- 3.2 模型类
- AttachPermisson
- VirtualMachineDescriptor
- AttachProvider
- 2.3 核心类VirtualMacine
- loadAgent() 方法
- loadAgentPath()
- attach()方法
- detach()
- 监控JVM
和JVM通信,发送指令请求
一、描述
从JDK6
开始引入,除了Solaris平台的Sun JVM支持远程的Attach,在其他平台都只允许Attach到本地的JVM上。
用Java语言编写的工具使用此API附加到目标虚拟机(VM),并将其tool agent 加载到目标VM中。
什么是attach机制?
说简单点就是jvm提供一种jvm进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作,比如说我们为了让另外一个jvm进程把线程dump出来,那么我们跑了一个jstack的进程,然后传了个pid的参数,告诉它要哪个进程进行线程dump,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如要执行什么操作,传了什么参数等
涉及进程间通信。启动Attach Listener
进程和VM进程通信。交换数据的方式使用的是SOCKET
。
约束
除了 Attach API
规定的API
功能。还依赖针对JVM
的具体实现,如果jvm
嗯实现不支持,api也没有用。
功能
- 内存dump
- 线程dump
- 类信息统计(比如加载的类及大小以及实例个数等)
- 动态加载agent
- 动态设置vm flag(但是并不是所有的flag都可以设置的,因为有些flag是在jvm启动过程中使用的,是一次性的)
- 打印vm flag
- 获取系统属性等
二、实现原理
能够说明ATTCH的作用,也提供更高阶,更细致的分析。
概括性文档
详细流程分析
说简单点就是jvm
提供一种jvm进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作,比如说我们为了让另外一个jvm
进程把线程dump
出来,那么我们跑了一个jstack
的进程,然后传了个pid
的参数,告诉它要哪个进程进行线程dump
,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如要执行什么操作,传了什么参数等
三、代码分析
3.1 代码结构
VirtualMachine
是核心,通过操作它,来进行attach
等AttachPermission
来负责权限控制功能VirtualMachineDescriptor
vm的模型,一个数据对象,包含pid或者vmname信息AttachProvider
各个JVM平台,自己负责对接实现。利用SPI
给VirtualMachine
的接口提供实现,截图中给出了OPENJDK14
中默认对Hotspot
的实现
3.2 模型类
AttachPermisson
用来做权限控制
权限目标名称 | 权限允许什么 | 允许此权限的风险 |
---|---|---|
attachVirtualMachine | 能够附加到另一个Java虚拟机并将代理加载到该VM。 | 这使攻击者可以控制目标VM,这可能会导致目标VM行为异常。 |
createAttachProvider | 能够创建AttachProvider实例。 | 这使攻击者可以创建AttachProvider,该AttachProvider可以潜在地用于附加到其他Java虚拟机。 |
程序员通常不会直接创建AttachPermission
对象。而是由安全策略代码基于读取安全策略文件来创建它们。
jvm
在启动时可以设置一些权限,比如为了安全考虑禁止attach
的行为。这个类就是在attach
时被调用来检测是否能够attach
。
VirtualMachineDescriptor
JVM信息的Bean。jvm有很多种,用来保存具体jvm的信息。
VirtualMachineDescriptor
是用于描述Java虚拟机的容器类。它封装了标识目标虚拟机的标识符,以及AttachProvider
在尝试附加到虚拟机时应使用的对它的引用。该标识符取决于实现,但是通常是每个Java虚拟机都在其自己的操作系统进程中运行的进程标识符(或pid
)环境。
VirtualMachineDescriptor
也有一个displayName
。显示名称通常是工具可能显示给用户的人类可读字符串。例如,显示系统上运行的Java虚拟机列表的工具可能会使用显示名称而不是标识符。阿VirtualMachineDescriptor可以在没有被创建的显示名称。在这种情况下,标识符用作显示名称。
VirtualMachineDescriptor
实例通常是通过调用该VirtualMachine.list()
方法来创建的。这将返回描述符的完整列表,以描述所有已安装的Java
虚拟机attach providers
。
AttachProvider
用来attach到jvm的接口。真正被使用的是各个厂家提供的jvm实现,是该类的子类。
2.3 核心类VirtualMacine
有两个功能
- loadagent
加载JPLTS agent
,这个agent
会加载agent.jar
包 并执行agentMain
或者premain
方法 - attach(attach)
依附到目标jvm - detach 离开
示例
在此示例中,我们附加到由进程标识符标识的Java虚拟机2177。然后,使用提供的参数在目标进程中启动JMX管理代理。最后,客户端从目标VM分离。
VirtualMachine可安全地供多个并发线程使用。
一个Jvm的实现
loadAgent() 方法
加载制作好的agent.jar
包,并执行premain domain
方法。
加载 JPLTS agent
,这个agent
会加载agent.jar
包 并执行 agentMain
或者premain
方法
源码就不贴了,这里整个类的执行过程。可以总结为和jvm建立连接后,向jvm
发送命令,传输agent.jar
的path
参数,并触发其中的premain
或者domain
方法
loadAgentPath()
用来加载 native
方法库,即用他语言写的库。可以看出 load cmd
会有字段来标识是不是本地方法
attach()方法
这个方法的实现最终是在
provider
中实现,最终的结果是返回一个VirtualMachine
对象。可以和jvm
通信,让jvm
执行指令。
流程
- 检查权限
- 测试是否可以attach
- 成功attach
- 以上检查都没问题,返回
new VirtualMachineImpl(this, vmid)
;
detach()
hotspot的实现比较直接,直接将fd文件设置为null
监控JVM
如果对JMXBean不陌生的就可以知道,这些bean是用来获取JVM运行信息:堆内存,线程状态,gc次数等。VirtualMacine提供这样的函数,向jvm发送指令,暴露端口。通过这个端口就可以获取JVM运行信息。
startManagementAgent(Properties agentProperties)
startLocalManagementAgent()
仅暴露本地端口,最终是从本地fd读取jvm信息。
JDK.attach 包解析相关推荐
- 关于vivo 8.0和miui新系统android studio调试出现“包解析错误”的bug的解决办法
最近在工作中遇到了调试的时候将app安装到vivo 手机上,出现了包解析错误的问题.一般来说这种问题只会出现在手机版本 小于 app所要求的最低版本的手机上.但是此vivo手机的版本是8.0,很显然不 ...
- SSL加密包解析的几个概念梳理
1.DPI技术初识 DPI(Deep PacketInspection)深度包检测技术是在传统IP数据包检测技术(OSI L2-L4之间包含的数据包元素的检测分析)之上增加了对应用层数据的应用协议识别 ...
- JDK源码解析 迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的。
JDK源码解析 迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的. 看完这段代码是不是很熟悉,与我们上面代码基本类似.单列集合都使用到了迭代器,我们以Arr ...
- JDK源码解析 Comparator 中的策略模式
JDK源码解析 Comparator 中的策略模式.在Arrays类中有一个 sort() 方法,如下: public class Arrays{public static <T> voi ...
- JDK源码解析 Runable是一个典型命令模式,Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法
JDK源码解析 Runnable是一个典型命令模式, Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法 /命令接口(抽象命令角色) public interfa ...
- JDK源码解析 InputStream类就使用了模板方法模式
JDK源码解析 InputStream类就使用了模板方法模式. 在InputStream类中定义了多个 read() 方法,如下: public abstract class InputStream ...
- JDK源码解析 Integer类使用了享元模式
JDK源码解析 Integer类使用了享元模式. 我们先看下面的例子: public class Demo {public static void main(String[] args) {Integ ...
- JDK源码解析 —— IO流中的包装类使用到了装饰者模式
JDK源码解析 IO流中的包装类使用到了装饰者模式. BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter ...
- 使用Golang flag包解析字符串
本篇文章主要介绍如何使用flag包解析字符串,没有介绍flag包的详细使用,需要学习flag包如何使用的同学可以参考如下这篇文章: Go语言中使用flag包对命令行进行参数解析的方法 https:// ...
- 蓝牙4.0BLE抓包(二) – 广播包解析
转自: http://www.cnblogs.com/aikm/p/5022502.html 版权声明:本文为博主原创文章,转载请注明作者和出处. 作者:强光手电[艾克姆科技-无线事业部] 在使 ...
最新文章
- 人体肠道细菌与自身细胞的比例究竟是多少?
- Mysql5.7的gtid主从半同步复制和组复制
- 【pmcaff】产品经理每日十问,问问自己,你做到了嘛
- .NET Core ConfigureServices
- 产品原型制作_早期制作原型如何帮助您设计出色的数字产品
- 接到老大的任务,要求开发内部进销存系统
- 5. Adapter Pattern(适配器模式)
- 计算机专业必备基础知识500题,计算机基础知识500题
- 关于来料检验中多退货的问题
- TMS320DM642调试出现#10247-D creating output section .capChaACrSpace without a SECTIONS 解决办法...
- 聊聊GIS中的坐标系|再版 详细定义、计算及高程系统
- 最全空降Golang资料补给包(满血战斗),包含文章,书籍,作者论文,理论分析,开源框架,云原生,大佬视频,大厂实战分享ppt
- CSDN:2021博客之星年度总评选大赛投票
- mongodb 存储过程 遍历表数据_使用MongoDB存储数据
- 英语如此简单(转贴)
- R语言建立神经网络过程
- Android通知Notification使用全解析,看这篇就够了
- latex表格内上下边距调整
- SpringBoot网页预览或下载pdf、图片
- 好记性不如烂笔头--校园网下Parsec远程控制软件的使用