bytecodejava-bytecode-asmbytecode-manipulation

Detect modified bytecode at runtime


There are a number of tools(e.g. JavaAssist, ASM) to re-generate bytecodes at runtime for various purposes. One case is Application permformance Management(APM), which provides agents to rewrite existing bytecodes during application startup.

For example, an original class A has a method: void sayHello(String name){}, and a new method can be generated by these agents in a such way:

 void NewA:sayHello(String name){
     Long start = System.currentMillseconds()
     A::sayHello(name)
     Long elpased = System.currentMillseconds()-start
  }

and the JVM will interprete the class newA after classloaded instead of the original A.

So my question is: is it possible to detect these kind of modification inside of origin A at runtime so that to alert that the executed bytecodes is not the raw bytecodes we deliveried?


Solution

  • There's no official way to detect modification to a class as it is understood that a user with sufficient permission to install an agent is already on the other side of the security door.

    It's possible to prevent agents from being attached at runtime by either disabling all tools from attaching (-XX:+DisableAttachMechanism) or by just disabling dynamic agents in JDK9+ (-XX:-EnableDynamicAgentLoading).

    Neither of those prevent agents from being attached during startup of the JVM.

    There are some hacky ways to attempt to tell that a class has been modified but they aren't perfect:

    But overall, there really isn't a reliable way to do this. As @Holger said, an agent could modify any test to always return false or remove it entirely.