Skip to content

Instantly share code, notes, and snippets.

@apangin
Created January 31, 2016 19:16
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save apangin/781683bc86ab19e92372 to your computer and use it in GitHub Desktop.
Save apangin/781683bc86ab19e92372 to your computer and use it in GitHub Desktop.
Using JVMTI to obtain bytecodes of a Java method
#include <jvmti.h>
static jvmtiEnv* jvmti;
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM* vm, void* reserved) {
(*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0);
jvmtiCapabilities capabilities = {0};
capabilities.can_get_bytecodes = 1;
capabilities.can_get_constant_pool = 1;
jvmtiError err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
return JNI_VERSION_1_4;
}
JNIEXPORT jbyteArray JNICALL
Java_Bytecodes_getBytecodes(JNIEnv* env, jclass cls, jobject method) {
jmethodID methodID = (*env)->FromReflectedMethod(env, method);
jint bytecode_size;
unsigned char* bytecodes;
if ((*jvmti)->GetBytecodes(jvmti, methodID, &bytecode_size, &bytecodes) != 0) {
return NULL;
}
jbyteArray result = (*env)->NewByteArray(env, bytecode_size);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, bytecode_size, bytecodes);
}
(*jvmti)->Deallocate(jvmti, bytecodes);
return result;
}
import java.lang.reflect.Method;
import java.util.Arrays;
public class Bytecodes {
static {
System.loadLibrary("bytecodes");
}
private static native byte[] getBytecodes(Method method);
public static void main(String[] args) throws Exception {
Method m = Object.class.getDeclaredMethod("toString");
byte[] bytecode = getBytecodes(m);
System.out.println(Arrays.toString(bytecode));
}
}
@unwit
Copy link

unwit commented Apr 30, 2022

Is it possible to get the bytecode of an entire Java class using JVMTI?

@apangin
Copy link
Author

apangin commented May 1, 2022

Yes, using RetransformClasses API.
See https://github.com/apangin/class-file-extractor (not exactly JVM TI, but idea is the same).

@SammyVimes
Copy link

SammyVimes commented Nov 25, 2022

Shouldn't it be also possible with the JvmtiClassFileReconstituter? As I understand, instrumentation's retransform method collects class' bytecode via this reconstituter (if it's not cached). Not sure if it's portable though :D
But since we are already doing something dirty, why not skip the middle man (agent)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment