java - 使用 sa-jli 将 ClassDump 禁用到正在运行的 JVM 进程

标签 java jvm

我试图通过设置 -XX:+DisableAttachMechanism 来保护正在运行的 JVM 中的类。

但是,我发现该进程阻止了 jconsole 等工具的附加,但我仍然可以使用以下命令转储该 JVM 中所有已加载的类:

java -Dsun.jvm.hotspot.tools.jcore.PackageNameFilter.pkgList=com.xxxx -classpath ".:./bin:$JAVA_HOME/lib/sa-jdi.jar" sun.jvm.hotspot.tools.jcore.ClassDump 1234

有没有办法通过在运行的 JVM 中设置一些选项来阻止这种行为?或者有什么可以解决的?

谢谢。

最佳答案

一般来说,这是不可能的。

Serviceability Agent (sa-jdi) 不需要目标进程的合作。它只是使用 ptrace 停止目标 JVM系统调用,并在 JVM 甚至不知道的情况下读取进程的内存。

但是,您可以通过覆盖可服务性代理使用的变量来增加调试难度。特别是,如果重置gHotSpotVMStructs全局变量,SA将无法重建内部VM结构,因此基于SA的工具将停止工作。

为此,编译以下 novmstructs.c 程序:

extern void *gHotSpotVMStructs;

int Agent_OnLoad(void *vm, char *options, void *reserved) {
    gHotSpotVMStructs = 0;
    return 0;
}

如何编译:

gcc -fPIC -nostdlib -shared -olibnostructs.so -O2 nostructs.c

然后运行您的 Java 应用程序,并将生成的库作为代理附加:

java -agentpath:/path/to/libnostructs.so ...

下次有人尝试调用 ClassDump 或其他基于 SA 的实用程序时,将发生异常:

Attaching to process ID 574, please wait...
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.tools.jstack.JStack.runJStackTool(JStack.java:140)
        at sun.tools.jstack.JStack.main(JStack.java:106)
Caused by: java.lang.RuntimeException: gHotSpotVMStructs was not initialized properly in the remote process; can not continue
        at sun.jvm.hotspot.HotSpotTypeDataBase.readVMStructs(HotSpotTypeDataBase.java:418)
        at sun.jvm.hotspot.HotSpotTypeDataBase.<init>(HotSpotTypeDataBase.java:91)
        at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:395)
        at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:305)
        at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
        at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
        at sun.jvm.hotspot.tools.JStack.main(JStack.java:92)
        ... 6 more

关于java - 使用 sa-jli 将 ClassDump 禁用到正在运行的 JVM 进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48056863/

相关文章:

java - 将对象从文件加载到 arrayList

java - 针对现有注入(inject)器测试注入(inject)类的方法

java - ChangeListener 作为私有(private)类

java - 如何即时更改更改类行为?

java - SocketInitiator getSession 提供的 session 顺序与配置文件中的顺序不同

java - 如何从 Hibernate 获取更多调试消息?

java - 如何确保我使用的是 "server"JVM?

lambda - Kotlin:为什么函数不能存储在变量中?

java - 从java中找到java.exe位置

java - Java中唯一标识文件