首页 > 编程语言 >使用jvmti dll |so 加密java class jar包

使用jvmti dll |so 加密java class jar包

时间:2022-10-28 14:26:07浏览次数:49  
标签:java jar jvmti len char str data class

dll代码 

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <iostream>
#include <jni_md.h>
#include <jni.h>
#include <jvmti.h>
#include <string.h>
#include <stdio.h>
#include "com_example_javajnicall_JniCall.h"



using namespace std;



void encode(char *str ,int len)
{
    unsigned int m = strlen(str);
    
    printf("wait encode len %d arg len %d\n",m ,len);


    for (int i = 0; i < len; i++) {
        str[i] = str[i] + k;
    }


    /*for (int i = 0; i < m; i++)
    {
        str[i] = str[i] + k;
    }*/
}

void decode(char *str,int len)
{
    unsigned int m = strlen(str);
    for (int i = 0; i < len; i++) {
        str[i] = str[i] - k;
    }



    /*for (int i = 0; i < m; i++)
    {
        str[i] = str[i] - k;
    }*/
}

extern"C" JNIEXPORT jbyteArray JNICALL Java_com_example_javajnicall_JniCall_encrypt(JNIEnv * env, jclass cla, jbyteArray text,jint len)
{
    printf("call it!");
    char* dst = (char*)env->GetByteArrayElements(text, 0);


    encode(dst, len);
    //env->SetByteArrayRegion(text, 0, strlen(dst), (jbyte *)dst);
    env->SetByteArrayRegion(text, 0, len, (jbyte *)dst);    
    return text;
}





void JNICALL
ClassDecryptHook(
    jvmtiEnv *jvmti_env,
    JNIEnv *jni_env,
    jclass class_being_redefined,
    jobject loader,
    const char *name,
    jobject protection_domain,
    jint class_data_len,
    const unsigned char *class_data,
    jint *new_class_data_len,
    unsigned char **new_class_data
) {
    
    
    *new_class_data_len = class_data_len;
    jvmti_env->Allocate(class_data_len, new_class_data);
    unsigned char* _data = *new_class_data;
    // com/example/javajvmtiloader/scope/Test2
    if (name && strncmp(name, "com/far/demo/Test2", 38) == 0 )
    {

        printf("find it  len:%d\n", class_data_len);
        for (int i = 0; i < class_data_len; i++){
            _data[i] = class_data[i];
        }
        decode((char*)_data, class_data_len);
        
    }else {
        for (int i = 0; i < class_data_len; i++){
            _data[i] = class_data[i];
        }
    }


}

JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
    return JNI_OK;
}
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm) {

}

JNIEXPORT jint
JNICALL Agent_OnLoad(JavaVM * vm, char * options, void * reserved) {

    jvmtiEnv *jvmti;
    jint ret = vm->GetEnv((void **)&jvmti, JVMTI_VERSION);
    if (JNI_OK != ret) {
        printf("ERROR: Unable to access JVMTI!\n");
        return ret;
    }
    jvmtiCapabilities capabilities;
    (void)memset(&capabilities, 0, sizeof(capabilities));

    capabilities.can_generate_all_class_hook_events = 1;
    capabilities.can_tag_objects = 1;
    capabilities.can_generate_object_free_events = 1;
    capabilities.can_get_source_file_name = 1;
    capabilities.can_get_line_numbers = 1;
    capabilities.can_generate_vm_object_alloc_events = 1;



    jvmtiError error = jvmti->AddCapabilities(&capabilities);
    if (JVMTI_ERROR_NONE != error) {
        printf("ERROR: Unable to AddCapabilities JVMTI!\n");
        return error;
    }

    jvmtiEventCallbacks callbacks;
    (void)memset(&callbacks, 0, sizeof(callbacks));

    callbacks.ClassFileLoadHook = &ClassDecryptHook;
    error = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
    if (JVMTI_ERROR_NONE != error) {
        printf("ERROR: Unable to SetEventCallbacks JVMTI!\n");
        return error;
    }

    error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
    if (JVMTI_ERROR_NONE != error) {
        printf("ERROR: Unable to SetEventNotificationMode JVMTI!\n");
        return error;
    }

    printf("jvmti oj8k\n");

    return JNI_OK;
}
View Code

 

com_example_javajnicall_JniCall.h

 这个头文件是用javac生成的,实际上这个DLL可以分成两个,我偷懒搞一成一个了

一个用于加密(Java Jni调用),一个用于jvm加载时解密(java agent),对于给jvm加载的dll 包含解密方法即可

坑点

springboot的jar包格式导致不触发jvmti的fIleLoad事件

springboot项目jar包结构

 

正常的Jar包结构

 

 

要想触发jvmti中的fileLoad的事件,必须是正常的jar包格式

springboot是把用户写的类单独放到boot-inf目录下,springboot自己去加载,所以触发不了fileLoad事件!

win下编译的dll 不需要dllMain函数

开始一直以为需要dllmain函数,其实不需要!

 

想单独加密一个java文件,结果有两个class?

这是因为用了内部类或者lamda方法

 

标签:java,jar,jvmti,len,char,str,data,class
From: https://www.cnblogs.com/cfas/p/16835902.html

相关文章

  • Java集合
    List和Set的区别:List:有序,按对象进入的顺序保存对象,可重复,允许多个Null元素对象,可以使用Iterator取出所有元素,再逐一遍历,还可以使用get(intindex)获取指定下标的元素......
  • Java程序员就业方向主要有哪几个?
    1、Android开发Android是全球最大的智能手机操作系统,根据StrategyAnalytics最新研究报告显示,全球智能手机出货量在2016年第三季度达到3.75亿台。Android操作系统获得了创......
  • 【JavaSE】Java常用类
    1.String的特性代表字符串,java中所有字符串字面值都作为此类的实现例实现。String是一个final类,不能被继承。String实现了Serialiable,表示字符串支持序列化,实现了Comarabl......
  • Java™ Management Extensions Technology Stack
    JavaPlatform,StandardEditionJavaManagementExtensionsGuideJava™ManagementExtensionsInstrumentationandAgentSpecification,v1.2Java™ManagementEx......
  • java commond
    #!/bin/bash#参数配置#jar包路径jarPath=/app/beifa/20221008#jar包名称jarName=htsc-svc-data-migration-10-08#log日志输出路径logPath=/app/betalpha/htsc/log......
  • java基础-->源码,反码,补码 和位运算
    原码、反码、补码原码:十进制数据的二进制表现形式,最左边的是符号位,0为正,1为负。反码:正数的反码是其本身,负数的反码是符号位保持不变,其余取反。补码:正数的补码是其本身,......
  • Kotlin Jetpack 实战|00. 写给 Java 开发者的 Kotlin 入坑指南
    简介本文主要讲解Kotlin​​基础语法​​。本文是​​《KotlinJetpack实战》​​的开篇。主要内容每个Java开发者都应该学Kotlin快速认识Kotlin基础语法扩展函数委......
  • java第二天 随机数
    Random的包先生成实例Randomrm=newRandom();newRandom().nextInt();--返回int范围内的一个随机整数newRandom().nextInt(n);--返回0~n之间的一个随机整......
  • JavaScript 箭头函数
    箭头函数的形式:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content="IE=edge"/><metana......
  • Java流程控制
    Java流程控制Scanner对象之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我提供了这样一个工具类,我们可以获取用户的输入,java.util.Scanner,我们......