创建具有捆绑资源的Javavm

Create JavaVM with bundled resources

本文关键字:资源 Javavm 创建      更新时间:2023-10-16

我必须编辑原始帖子,因为它具有误导性。我有一个使用JNI创建Javavm的应用程序。它用QT5框架编写的C 。如果我在应用程序的.exe文件旁边提供.class和.jar文件,则我没有问题创建JVM并从Java应用程序调用函数。现在,由于Java应用程序可以分解我公司的标准,因此我不允许我将此应用程序分发给本地用户,因为它确实包含了他们无法访问的关键密码。像这样的安全学院,我得到的答复是,如果我将Java源捆绑在.EXE文件中,他们对应用程序感到满意。QT资源文件对于我定义为以下内容的这项工作将很棒:

<RCC>
    <qresource prefix="/javaApplication">
        <file>resources/bytecodes/helloworld/HelloWorld.class</file>
        <file>resources/bytecodes/helloworld/HelloWorld.jar</file>
    </qresource>
</RCC>

,因此我能够使用以下路径访问文件:

:/javaApplication/resources/bytecodes/helloworld/HelloWorld.class
:/javaApplication/resources/bytecodes/helloworld/HelloWorld.jar

良好而光滑,但是这些路径似乎与Javavmargs不起作用:

// Does work but violates security policies:
options[1].optionString = "-Djava.class.path=C:/Users/johorvat/Documents/NetBeansProjects/HelloWorld/build/classes/helloworld/HelloWorld.class;C:/Users/johorvat/Documents/NetBeansProjects/HelloWorld/dist/HelloWorld.jar";
// Does not work, sadly I try to achieve something like this:
options[1].optionString = "-Djava.class.path=:/javaApplication/resources/bytecodes/helloworld/HelloWorld.class;:/javaApplication/resources/bytecodes/helloworld/HelloWorld.jar";

如何实现第二个变体启动和运行?

您的问题与QT无关,可以简单地改写为:

是否可以将类或JAR文件的内容传递给JVM,而无需在磁盘上明确保存它们?

我问了这个问题。答案是:这是可能的,但并非首先不加载一些代码。因此,实际上,您可以通过首先启动自己的加载程序,然后传递数据,例如通过本地插座或Localhost网络连接。您的数据也可以来自本机方法,您当然可以使用QT编写JNI DLL。

QT资源系统除了您的应用程序外,其他任何内容都是看不见的。您调用JVM或任何其他可执行文件的参数是QT特定资源路径的可执行文件没有任何意义的。JVM对这些文件一无所知,并且永远不会知道。除非您在Java中重新进来QT资源系统,否则您即使如此,您也需要那些初始的类文件。

QT资源只是Zlib压缩的二进制斑点,可以从编译可执行的可执行文件中提取。他们不是"编辑"从任何意义上讲。实际上,它们通过利用链接器和编译器来串联到可执行文件,但这只是实施细节。

我公司的标准不允许我将此应用程序分发给本地用户,因为它确实包含了他们无法访问的关键密码

所有内容都可以分解,因此无论您的密码是否在显式Java类文件中,还是在QRC obfuscated类文件中都没关系。可能的结果是相同的。

为了使反向工程的生活更艰难,您所能做的就是:

  1. 保护与SSL的连接。

  2. 验证服务器的签名,以防止中间人攻击。

  3. 将应用程序可执行文件中的炒私有客户端键捆绑。使用它代替密码。服务器可以先验了解允许的客户端密钥。

  4. 与您喜欢的SSL库静态链接。

如果您的方案允许,则可以使用密码保护客户端密钥,并要求用户每次打算连接到服务器时输入它。这可以保护泄漏的可执行文件允许服务器闯入而无需具有密码。

就是这样。

如果JNI_CreateJavaVM成功,那只是第一步。您已经创建了Java环境,但是现在您需要告诉它该怎么做。

您的下一步将是这样的:

1)加载您要使用的课程(例如Helloworld)

2)实例化您的课程

3)在您的班级上调用一种方法

 //step 1
 jclass HelloWorldClass = env->FindClass( "path/to/package/HellowWorld" ); 
 jobject helloWorldInst = NULL;
 if( HelloWorldClass != NULL )
 {
     //step 2 - use javah to determine your constructor/method signatures
     jmethodID helloWorldConstructorSignature = env->GetMethodID(env, HelloWorldClass, "<init>", "()V");
     helloWorldInst = env->NewObject(env, HelloWorldClass, helloWorldConstructorSignature);
 }
 //step 3 - Load your method's signature
 if( helloWorldInst != NULL )
 {
     jmethodID myMethodSignature = env->GetMethodID(env, HelloWorldClass, "myMethod", "()I" );
     int result = env->CallIntMethod( helloWorldInst, myMethodSignature );
 }