urmom damn the jvm

urmom 想要玩一下jvm

federa linux install jvm

bash 复制代码
sudo dnf install # openjdk 24 , gcc as well

创建method_trace_agent.c, urmom ai do it for me

c 复制代码
#include <jni.h>
#include <jvmti.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static jvmtiEnv *jvmti = NULL;

// 处理类签名(Lxxx/xxx; -> xxx/xxx)
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);
}

// Agent初始化(适配JDK 24)
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
    // 获取JVM TI环境(使用JDK 24支持的最新版本)
    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;
    }

    // JDK 24中,方法信息访问能力通过can_access_method_data统一声明
    jvmtiCapabilities capabilities;
    memset(&capabilities, 0, sizeof(capabilities));
    capabilities.can_generate_method_entry_events = 1; // 允许生成方法进入事件
    #if 0 // not working on jdk24
    //capabilities.can_access_method_data = 1;           // 允许访问方法数据(替代旧版本的细粒度成员)
    #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

java 复制代码
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

bash 复制代码
set -xe

export JAVA_INCLUDE_DIR=/etc/alternatives/java_sdk_24

gcc -fPIC -shared -I${JAVA_INCLUDE_DIR}/include -I${JAVA_INCLUDE_DIR}/include/linux \
    method_trace_agent.c -o libmethod_trace_agent.so

java -agentpath:./libmethod_trace_agent.so Test

运行build-jvm.sh, 输出

bash 复制代码
[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

  • urmom for your mom
相关推荐
在下雨5994 小时前
优秀开源内容转自公众号后端开发成长指南
jvm
你我约定有三7 小时前
面试tips--JVM(4)--Minor GC & Major GC & Full GC
jvm·面试·职场和发展
Li_yizYa7 小时前
JVM:内存区域划分、类加载的过程、垃圾回收机制
java·jvm
A尘埃7 小时前
企业级架构师综合能力项目案例二(项目性能优化方案JVM+数据库+缓存+代码JUC+消息中间件架构+服务熔断降级)
jvm·数据库·性能优化·架构师
ByteBlossom7 小时前
JVM核心机制:类加载与内存结构详解
jvm
善我7 小时前
JVM中产生OOM(内存溢出)的8种典型情况及解决方案
jvm
程序员江鸟7 小时前
Java面试实战系列【JVM篇】- JVM内存结构与运行时数据区详解(共享区域)
java·jvm·面试
ybq195133454318 小时前
RabbitMinQ(模拟实现消息队列项目)02
jvm
ChillJavaGuy1 天前
Java中的四大引用类型强引用、软引用、弱引用、虚引用
java·开发语言·jvm·四大引用类型
C++chaofan2 天前
Spring Task快速上手
java·jvm·数据库·spring boot·后端·spring·mybatis