java api 获取jvm实例,获取当前进程中的JavaVM *的所有实例?

This is only specific to Windows.

Does JNI provide any API that returns all instance of JavaVM* of the calling process?

Consider the following scenario, a C++ dll is injected into a java.exe process. Now the question is, how can the C++ dll locate the current instance of JavaVM* within the process it's running from?

As far as I know, all JNI invocation API require a JNIEnv object which can only be acquired from JavaVM* right? http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html

The traditional way of getting JavaVM* is via JNI_OnLoad but since I'm not writing a native library to be consumed by Java, I don't think that would do the trick. http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html

解决方案

jsize nVMs;

JNI_GetCreatedJavaVMs(NULL, 0, &nVMs); // 1. just get the required array length

JavaVM** buffer = new JavaVM*[nVMs];

JNI_GetCreatedJavaVMs(buffer, nVMs, &nVMs); // 2. get the data

This code is the "safe" version that asks how big the buffer has to be and then calls a second time to get the data. However, the major Windows JVM (Hotspot) doesn't support more than one JVM per process, so it may be sufficient for you to just allocate a buffer for one element. JNI_GetCreatedJavaVMs is a part of the invocation API and therefore exported by the jvm.dll.

I'm not writing a native library to be consumed by Java

If you are creating the JVM in your library, that's all you need because you have to load the jvm.dll anyways. I can't really help you much because you're not writing how exactly your library is going to be invoked. If your library is used by another native library that either creates the JVM or is loaded from the JVM and it doesn't pass the JavaVM* to you for whatever reason, you could try something like this:

#include

#include

// ...

typedef jint (JNICALL * GetCreatedJavaVMs)(JavaVM**, jsize, jsize*);

GetCreatedJavaVMs jni_GetCreatedJavaVMs;

// ...

jni_GetCreatedJavaVMs = (GetCreatedJavaVMs)GetProcAddress(GetModuleHandle(

TEXT("jvm.dll")), "JNI_GetCreatedJavaVMs");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
众所周知,Java编译后的Jar包和Class文件,可以轻而易举的使用反编译工具(如JD-GUI)进行反编译,拿到源码。为了保护自己发布的Jar包和Class文件,采用的方式大多是混淆方式,这种方式对于Class文件的加密是不彻底的,还是能够通过分析得出核心算法。本工具是采用jvmti方式对Class文件进行加密,使用C++生成加密和解密库,先用加密库对Jar包进行加密,将加密后的Jar包及解密库文件发布出去,执行时候需要JVM引入解密库文件,解密后执行。c++的.dll文件和.so文件的破解难度是很大的,这就能有效的保护软件和代码的知识产权. 使用方法: 1.打开windows命令行(运行=>cmd=>回车),在命令行 进入 EncryptJar目录 2.执行 java -jar encrypt.jar 3.输入h,然后回车,可以看到帮助菜单 4.输入3,然后按回车键,进入加入jar文件功能 5.输入要加密的jar文件的路径 6.提示输入秘钥(key)的时候,直接回车,不要输入任何字符(否则后面classhook将不可解密加密后的jar包) 7.输入目标路径(加密后的jar文件路径,此处要注意:jar文件名要保持相同,将加密后的文件保存到不同的目录) 8.将加密后的jar包,替换原来的没有加密的jar包,与要发布的程序一起进行发布.(一般替换lib目录下对应的jar包即可) 9.加密后的jar包运行方法: windows下: 拷贝libClassHook.dll文件到程序的根目录(通常为要执行的jar程序的根目录) 使用以下命令启动程序: java -agentlib:libClassHook -jar xxxxxxxxxxx.jar 则在运行过程会自动进行解密操作(解密过程是运行过程用c++的dll进行解密的,可以有效防止破解class文件) 如果执行过程报错,可将程序根目录添加到环境变量path去 Linux下: 拷贝libClassHook.so到程序的根目录(通常为要执行的jar程序的根目录) 使用以下命令启动程序: java -agentlib:ClassHook -jar xxxxxxxxxxx.jar (这里要删除掉lib,linux系统下会自动补全) 则在运行过程会自动进行解密操作(解密过程是运行过程用c++的dll进行解密的,可以有效防止破解class文件) 如果执行过程报错,可以在程序根目录下执行以下语句:export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH 或将libClassHook.so 拷贝到/usr/lib目录去。 支持操作系统:加密请在windows64位系统并安装了64位jdk环境下进行。 需要解密运行的程序支持LINUX(64位)和windows(64位)安装了JDK1.8以上的系统。 测试程序: (t_lib目录下的jar包为经过加密的jar包) java -agentlib:libClassHook -jar test.jar

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值