2

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.

Yue S
  • 23
  • 3
  • Do you have a good reason to need this? If so, what is it? – Kayaman Jan 02 '18 at 07:42
  • Simply I don't want the classes to be read in any way when they are distributed and deployed to our client's server. I've already had a tool to encrypt the classes and decrypt them when loaded in jvm. I want them not be dumped. – Yue S Jan 02 '18 at 08:02
  • 1
    That's just not possible to do reliably. Tell your clients that you'll sue them if they dump the classes, that's a lot more effective and a lot cheaper. – Kayaman Jan 02 '18 at 08:31
  • Thanks, will do it – Yue S Jan 02 '18 at 09:06

2 Answers2

6

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
apangin
  • 92,924
  • 10
  • 193
  • 247
0

Old question but here we go

Field jvmField = ManagementFactory.getRuntimeMXBean().getClass().getDeclaredField("jvm");
jvmField.setAccessible(true);
VMManagement jvmInstance = (VMManagement) jvmField.get(ManagementFactory.getRuntimeMXBean());
List<String> jvmArguments = jvmInstance.getVmArguments();

jvmArguments will have all the the arguments the jvm was started with, you can check these before loading in the actual classes and if there is a flag used you don't want abort loading.

But keep in mind that this is just one of the many ways classes can be dumped from a jvm, you can attach an agent, hook ClassLoader#defineClass and many other things as long as you are in the jvm there is no way to be 100% "dump proof".

uglibubla
  • 83
  • 11