JNI成功附加到程序但无法获取字段?

时间:2016-05-31 09:24:28

标签: java c++ dll java-native-interface low-level

计算器!

我设法将我的dll注入游戏我的游戏(用java制作),我确实附加到主线程,所以我可以获得课程和字段。

总代码:



#include <Windows.h>
#include <jni.h>
#include <iostream>
#include <string>
#include "MCClass.h"
/*
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD     fdwReason,
_In_ LPVOID    lpvReserved
);
*/

typedef jint (*hJNI_GetCreatedJavaVMs )( JavaVM** vmBuf , jsize bufLen , jsize* nVMs );

hJNI_GetCreatedJavaVMs oJNI_GetCreatedJavaVMs;

HMODULE jvmHandle;
FARPROC func_JNI_GetCreatedJavaVMs;
JavaVM *jvm;
JNIEnv *jenv;
jclass Minecraft;
jclass FMLH;
jclass FMLHI;
jclass launchWrapper;
MCClass* mc = new MCClass ( );

using namespace std;

void GetAllMinecraft ( )
{
    
    jfieldID f = jenv->GetFieldID ( Minecraft , "serverName" , "Ljava/lang/String;" );
        if ( f != NULL )
        {
        jstring str = (jstring)jenv->GetObjectField ( Minecraft , f );

        mc->serverName = (char*)jenv->GetStringUTFChars( str , 0 );
        cout << mc->serverName << endl;
    }
    else
    {
        MessageBox ( NULL , "serverName is null", "ERROR" , MB_OK );
    }
    
    
}
/*
void start ( )
{
    MessageBox ( NULL , "Initialization has completed." , "Works" , MB_OK );

    FMLH =  jenv->FindClass ( "net/minecraftforge/fml/relauncher/FMLLaunchHandler" );

    if ( FMLH != nullptr )
    {
        MessageBox ( NULL , "FMLLaunchHandler found successfully" , "OK" , MB_OK );
        jfieldID f = jenv->GetStaticFieldID ( (jclass) FMLH , "INSTANCE" , "Lnet/minecraftforge/fml/relauncher/FMLLaunchHandler;" );
        MessageBox ( NULL , "FMLH passed" , "OK" , MB_OK );
        if ( f == nullptr )
        {
            MessageBox ( NULL , "FMLLaunchHandler fieldID couldn't be found successfully" , "OK" , MB_OK );
        }
        else
        {
            MessageBox ( NULL , "FMLLaunchHandler fieldID found successfully" , "OK" , MB_OK );
            FMLHI = jenv->GetStaticObjectField ( (jclass) FMLH , f );
            MessageBox ( NULL , "FMLHI passed" , "OK" , MB_OK );
            if ( FMLHI == nullptr )
            {
                MessageBox ( NULL , "FMLLaunchHandler instance couldn't be found successfully" , "OK" , MB_OK );
            }
            else
            {
                MessageBox ( NULL , "FMLHI is not nullptr" , "OK" , MB_OK );
                jfieldID f1 = jenv->GetFieldID ( ( jclass ) FMLHI , "classLoader" , "Lnet/minecraft/launchwrapper/LaunchClassLoader;" ); //HERE
                MessageBox ( NULL , "f1 passed" , "OK" , MB_OK );
                if ( f1 == nullptr )
                {
                    MessageBox ( NULL , "classLoader fieldID couldn't be found successfully" , "OK" , MB_OK );
                }
                else
                {
                    MessageBox ( NULL , "classLoader fieldID found successfully" , "OK" , MB_OK );
                    launchWrapper = jenv->GetObjectField ( ( jclass ) FMLHI , f1 );
                    MessageBox ( NULL , "launchWrapper passed" , "OK" , MB_OK );
                    if ( launchWrapper == nullptr )
                    {
                        MessageBox ( NULL , "classLoader class couldn't be found successfully" , "OK" , MB_OK );
                    }
                    else
                    {
                        MessageBox ( NULL , "classLoader class found successfully" , "OK" , MB_OK );
                        jmethodID mmid = jenv->GetMethodID ( ( jclass ) launchWrapper , "findClass" , "(Ljava/lang/String;)Ljava/lang/Class;" );
                        MessageBox ( NULL , "findClass passed" , "OK" , MB_OK );

                        if ( mmid != NULL )
                        {
                            Minecraft = ( jclass ) jenv->CallNonvirtualObjectMethod ( launchWrapper , ( jclass ) launchWrapper , mmid , "net.minecraft.client.Minecraft" );
                            MessageBox ( NULL , "Minecraft class found successfully" , "OK" , MB_OK );
                            //   GetAllMinecraft ( );
                        }
                        else
                        {
                            MessageBox ( NULL , "findClass method ID couldn't be found successfully" , "OK" , MB_OK );
                        }
                    }
                }
            }
        }
    }
    else
    {
        MessageBox ( NULL , "FMLLaunchHandler couldn't be found successfully" , "OK" , MB_OK );
    }


}
*/

const char* GetObjName ( jobject cls )
{


    
    jclass clsClazz = jenv->GetObjectClass ( cls );

    
    jmethodID methodId = jenv->GetMethodID ( clsClazz , "getName" , "()Ljava/lang/String;" );
    jstring className = ( jstring ) jenv->CallObjectMethod ( cls , methodId );

    return jenv->GetStringUTFChars ( className , NULL );

   
    jenv->DeleteLocalRef ( clsClazz );
}
void start ( )
{
    jclass preMC = jenv->FindClass ( "net/minecraftforge/fml/relauncher/FMLLaunchHandler" );

    if ( preMC != NULL )
    {

		/*Section intercept custom findClassStart*/
		jfieldID iID = jenv->GetStaticFieldID ( preMC , "INSTANCE" , "Lnet/minecraftforge/fml/relauncher/FMLLaunchHandler;" );
		cout << "IID: " << iID << endl;
		jobject instance = jenv->GetStaticObjectField ( preMC , iID );
		cout << "INSTANCE: " << instance << endl;
		jfieldID lID = jenv->GetFieldID ( preMC , "classLoader" , "Lnet/minecraft/launchwrapper/LaunchClassLoader;" );
		cout << "LID: " << lID << endl;
		jobject classLoader = jenv->GetObjectField ( instance , lID );
		cout << "classLoader: " << classLoader << endl;
		jmethodID fid = jenv->GetMethodID ( jenv->GetObjectClass(classLoader) , "findClass" , "(Ljava/lang/String;)Ljava/lang/Class;" );
		cout << "FID: " << fid << endl;
		jobject a = jenv->CallNonvirtualObjectMethod ( classLoader , jenv->GetObjectClass(classLoader), fid , "net/minecraft/client/Minecraft" );
		preMC = ( jclass ) a;
		cout << "preMC: " << preMC << endl;
		/*Section intercept custom findClassEND*/

		/*Section getDisplayWidthStart*/
        jfieldID mid = jenv->GetStaticFieldID ( jenv->GetObjectClass(preMC) , "theMinecraft" , "Lnet/minecraft/client/Minecraft;" );
        cout << "MID: " << mid << endl;
        jobject MC = jenv->GetStaticObjectField ( jenv->GetObjectClass(preMC) , mid );
		cout << "MC: " << MC << endl;
		jfieldID mid2 = jenv->GetFieldID ( jenv->GetObjectClass(MC) , "displayWidth" , "I" );
		cout << "MID2: " << mid2 << endl;
		int displayWidth = jenv->GetIntField ( MC , mid2 );
		cout << "DisplayWidth: " << displayWidth << endl;
		/*Section getDisplayWidthEND*/
    }
    

}
void init ( )
{
    jvmHandle = GetModuleHandleA ( "jvm.dll" );
    func_JNI_GetCreatedJavaVMs = GetProcAddress ( jvmHandle , "JNI_GetCreatedJavaVMs" );
    oJNI_GetCreatedJavaVMs = ( hJNI_GetCreatedJavaVMs ) func_JNI_GetCreatedJavaVMs;
    jint returnOF = oJNI_GetCreatedJavaVMs ( &jvm , 1 , NULL );
    
    jint returnOf1 = jvm->AttachCurrentThread ( ( void ** ) &jenv , NULL );

    if ( jenv != nullptr )
    {
        start ( );
    }


    if ( jenv->ExceptionCheck ( ) )
    {
        jenv->ExceptionDescribe ( );
    }

    jvm->DetachCurrentThread ( );


}




BOOL WINAPI DllMain ( HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpvReserved )
{
    switch ( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            init ( );
       //case DLL_PROCESS_DETACH:
       //case DLL_THREAD_ATTACH:
       //case DLL_THREAD_DETACH:
    }
}   
&#13;
&#13;
&#13;

注意:此游戏使用自定义类启动器,+我在其上使用forge api。

我查看了cout调试,看起来像cout停在:

cout << "FID: " << fid << endl;

之后不再打电话给cout。然后游戏停止响应。 感谢您阅读,希望我的描述性足够。

编辑:整个代码停止游戏我的飞机在一段时间后响应或立即随机发出随机。

我现在使用带极端注射器的标准注射。

这是我从调试中得到的一些信息:

&#13;
&#13;
IID: 0000000024D1FE80
INSTANCE: 00000000191813F8
LID: 0000000000000032
classLoader: 0000000019181400
FID: 0000000016176C90
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000002d7688e, pid=6048, tid=0x0000000000001648
#
# JRE version: Java(TM) SE Runtime Environment (8.0_92-b14) (build 1.8.0_92-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.92-b14 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# J 3576 C2 net.minecraft.launchwrapper.LaunchClassLoader.findClass(Ljava/lang/String;)Ljava/lang/Class; (695 bytes) @ 0x0000000002d7688e [0x0000000002d76820+0x6e]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\Balen\Desktop\ForgeMod\eclipse\hs_err_pid6048.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
AL lib: (EE) alc_cleanup: 1 device not closed
:runClient FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':runClient'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_92\bin\java.exe'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 8 mins 50.128 secs
&#13;
&#13;
&#13;

编辑:这是为了更好地解释一切:

在游戏中的所有内容初始化后,我将这个dll注入游戏中。

游戏使用自定义类加载器(LaunchClassLoader)我尝试检索它的实例,为此我得到FMLLaunchHandler我得到一个FMLLaunchHandler实例然后从该实例我得到classLoader并从该实例我使用classLoaders findClass来获得课程。

有人告诉我,我需要获取类的初始化版本才能使用非静态方法或获取非静态字段。

我现在使用一种名为极端进样器的进样器,并使用标准进样,即loadlibrary。

我也没有创建自己的虚拟机,我附加到正在运行的minecraft vm并通过dll和init函数获取env来处理附加。

感谢阅读,祝你有个美好的一天。

0 个答案:

没有答案