urmom 想要玩一下jvm
federa linux install jvm
sudo dnf install
创建method_trace_agent.c, urmom ai do it for me
# include <jni.h>
# include <jvmti.h>
# include <stdio.h>
# include <string.h>
# include <stdlib.h> static jvmtiEnv * jvmti = NULL ;
static char * process_class_signature ( const char * signature) { if ( signature == NULL || * signature != 'L' ) { return strdup ( signature ? signature : "" ) ; } size_t len = strlen ( signature) ; char * processed = ( char * ) malloc ( len - 1 ) ; if ( processed) { strncpy ( processed, signature + 1 , len - 2 ) ; processed[ len - 2 ] = '\0' ; } return processed;
}
void JNICALL MethodEntryCallback ( jvmtiEnv * jvmti, JNIEnv * env, jthread thread, jmethodID method
) { jclass declaring_class; jvmtiError err = ( * jvmti) -> GetMethodDeclaringClass ( jvmti, method, & declaring_class) ; if ( err != JVMTI_ERROR_NONE) { fprintf ( stderr , "GetMethodDeclaringClass failed: %d\n" , err) ; return ; } char * class_signature, * class_generic; err = ( * jvmti) -> GetClassSignature ( jvmti, declaring_class, & class_signature, & class_generic) ; if ( err != JVMTI_ERROR_NONE) { fprintf ( stderr , "GetClassSignature failed: %d\n" , err) ; return ; } char * class_name = process_class_signature ( class_signature) ; char * method_name, * method_signature, * method_generic; err = ( * jvmti) -> GetMethodName ( jvmti, method, & method_name, & method_signature, & method_generic) ; if ( err != JVMTI_ERROR_NONE) { fprintf ( stderr , "GetMethodName failed: %d\n" , err) ; free ( class_name) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) class_signature) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) class_generic) ; return ; } printf ( "[JVM HACK] 调用方法: %s.%s%s\n" , class_name, method_name, method_signature) ; free ( class_name) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) class_signature) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) class_generic) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) method_name) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) method_signature) ; ( * jvmti) -> Deallocate ( jvmti, ( unsigned char * ) method_generic) ;
}
JNIEXPORT jint JNICALL Agent_OnLoad ( JavaVM * vm, char * options, void * reserved) { jint ret = ( * vm) -> GetEnv ( vm, ( void * * ) & jvmti, JVMTI_VERSION_1_2) ; if ( ret != JNI_OK || jvmti == NULL ) { fprintf ( stderr , "获取JVM TI环境失败,错误码: %d\n" , ret) ; return ret; } jvmtiCapabilities capabilities; memset ( & capabilities, 0 , sizeof ( capabilities) ) ; capabilities. can_generate_method_entry_events = 1 ; # if 0 # endif jvmtiError err = ( * jvmti) -> AddCapabilities ( jvmti, & capabilities) ; if ( err != JVMTI_ERROR_NONE) { fprintf ( stderr , "添加JVM TI功能失败,错误码: %d\n" , err) ; return err; } jvmtiEventCallbacks callbacks; memset ( & callbacks, 0 , sizeof ( callbacks) ) ; callbacks. MethodEntry = & MethodEntryCallback; err = ( * jvmti) -> SetEventCallbacks ( jvmti, & callbacks, sizeof ( callbacks) ) ; if ( err != JVMTI_ERROR_NONE) { fprintf ( stderr , "设置事件回调失败,错误码: %d\n" , err) ; return err; } err = ( * jvmti) -> SetEventNotificationMode ( jvmti, JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, NULL ) ; if ( err != JVMTI_ERROR_NONE) { fprintf ( stderr , "启用事件通知失败,错误码: %d\n" , err) ; return err; } printf ( "[JVM HACK] 代理加载成功,开始监控方法调用...\n" ) ; return JNI_OK;
}
创建Test.java, jaba jaba boba tea
public class Test { public static void main ( String [ ] args) { System . out. println ( "开始测试..." ) ; foo ( ) ; bar ( 123 ) ; } public static void foo ( ) { System . out. println ( "执行foo()" ) ; } public static void bar ( int x) { System . out. println ( "执行bar(" + x + ")" ) ; }
}
创建build-jvm.sh
set -xeexport JAVA_INCLUDE_DIR = /etc/alternatives/java_sdk_24gcc -fPIC -shared -I${JAVA_INCLUDE_DIR} /include -I${JAVA_INCLUDE_DIR} /include/linux \ method_trace_agent.c -o libmethod_trace_agent.sojava -agentpath:./libmethod_trace_agent.so Test
运行build-jvm.sh, 输出
[ JVM HACK] 代理加载成功,开始监控方法调用.. .
[ JVM HACK] 调用方法: java/lang/Thread.< init> ( Ljava/lang/ThreadGroup; Ljava/lang/String; ) V
[ JVM HACK] 调用方法: java/lang/Thread.checkName( Ljava/lang/String; ) Ljava/lang/String;
[ JVM HACK] 调用方法: java/lang/Thread.< init> ( Ljava/lang/ThreadGroup; Ljava/lang/String; ILjava/lang/Runnable; J) V
[ JVM HACK] 调用方法: java/lang/Object.< init> ( ) V
[ JVM HACK] 调用方法: java/lang/Object.< init> ( ) V
[ JVM HACK] 调用方法: java/lang/Thread.getPriority( ) I
[ JVM HACK] 调用方法: java/lang/Thread.isVirtual( ) Z
[ JVM HACK] 调用方法: java/lang/ThreadGroup.getMaxPriority( ) I
[ JVM HACK] 调用方法: java/lang/Math.min( II) I
.. .很多输出
ok, shutdown Windows and sleep for a while, next time damn the world