Disable ClassDump to a running JVM process by using sa-jli

情到浓时终转凉″ 提交于 2021-02-08 06:47:52

问题


I'm trying to protect my classes in a running JVM by setting -XX:+DisableAttachMechanism.

However, I found that the process prevents tools like jconsole to attach, but still I can use following command the dump all the loaded classes in that 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

Is there any way to stop this behavior by setting some options in the running JVM? Or anything to work around?

Thanks.


回答1:


In general, this is not possible.

Serviceability Agent (sa-jdi) does not require cooperation from the target process. It just stops target JVM using ptrace syscall, and reads the memory of the process without JVM even knowing about that.

However, you can make debugging harder by overwriting the variables used by Serviceability Agent. Particularly, if you reset gHotSpotVMStructs global variable, SA will not be able to reconstruct internal VM structures, so that tools based on SA will stop working.

In order to do this, compile the following novmstructs.c program:

extern void *gHotSpotVMStructs;

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

How to compile:

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

Then run your Java application with the produced library attached as the agent:

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

The next time someone tries to invoke ClassDump or other SA-based utility, the exception will occur:

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


来源:https://stackoverflow.com/questions/48056863/disable-classdump-to-a-running-jvm-process-by-using-sa-jli

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!