Я не могу прикрепить через оракул формы GUI объект с помощью DLL-инъекции и JNI

В рамках одного из моих проектов мне нужно прочитать графический объект VTextField с запущенным приложением оракуловых форм и установить в нем новое значение, я могу добавить свою DLL в приложение и могу прикрепить через текущий поток, приведенный ниже, мой код для этого

JNIEnv* env;
JavaVM *jvm = NULL;
jsize jvm_count = 0;
jint res = 0;
#ifdef __STATIC_LIB_JVM
res = JNI_GetCreatedJavaVMs(&jvm, 1, &jvm_count);
#else
{
HINSTANCE hLibJVM;
typedef jint(JNICALL GetCreatedJavaVMs_t)(JavaVM**, jsize, jsize*);
GetCreatedJavaVMs_t *MyGetCreatedJavaVMs;
hLibJVM = LoadLibrary(L"jvm.dll");
MyGetCreatedJavaVMs = (GetCreatedJavaVMs_t*)GetProcAddress(hLibJVM,  "JNI_GetCreatedJavaVMs");
res = MyGetCreatedJavaVMs(&jvm, 1, &jvm_count);
}
#endif
if (res == 0)
{
if (jvm_count == 0)
{
jvm = NULL;
}
}
else jvm = NULL;
bool mustDetach = false;
//jint retval = jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
jint retval = jvm->GetEnv((void**)&env, JNI_VERSION_1_6);

if (retval == JNI_EDETACHED)
{
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6;
args.name = NULL;
args.group = NULL;
retval = jvm->AttachCurrentThread((void**)&env, &args);
mustDetach = true; // to clean up afterwards
}
else{
fprintf(JNIStatus, "JNI is not processing\n"); // should never happen
}
if (retval != JNI_OK){
fprintf(JNIStatus, "JNI is not ok\n"); // should never happen
}
else{
fprintf(JNIStatus, "JNI is  ok\n"); // should never happen
}
if (retval>=0)
fprintf(JNIStatus, "Attachcurrentthread was successfull\n");

здесь я получаю вывод, так как присоединить текущий поток был успешным, но после этого, когда я пытаюсь найти класс, используя приведенный ниже код, система не может найти класс для этого

char* strin;
strin = "abcdef";
jstring str = env->NewStringUTF(strin);
jfieldID fid;
jclass clazz = env->FindClass("oracle/forms/ui/VTextField");
if (clazz == NULL) {
fprintf(JNIStatus, "Can't find class %s", clazz);
}

Даже я думал об этом из-за локальной ссылки, но я пытался сделать объект jclass также глобальной ссылкой, но не повезло 🙁

/* Create a global reference */
jclass clazzLUSCore = (_jclass*)env->NewGlobalRef(clazz);

/* The local reference is no longer useful */
env->DeleteLocalRef(clazz);

/* Is the global reference created successfully? */
if (clazzLUSCore == NULL) {
fprintf(JNIStatus, "Error - clazzLUSCore is still null when it is suppose to be global\n");
}

Я новичок в C ++, пожалуйста, помогите мне в этом, я не могу найти работающий класс приложения, мне нужно достичь этого без доступа к коду сервера.

Согласно комментарию @michael, я пытался добавить это, но я думаю, что это исключение. поэтому не может получить имя класса

   JavaVM* gJvm = nullptr;
static jobject gClassLoader;
static jmethodID gFindClassMethod;

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *pjvm, void *reserved) {
gJvm = pjvm;  // cache the JavaVM pointer
auto env = getEnv();
//replace with one of your classes in the line below
auto randomClass = env->FindClass("oracle/forms/ui/VTextField");
jclass classClass = env->GetObjectClass(randomClass);
auto classLoaderClass = env->FindClass("java/lang/ClassLoader");
auto getClassLoaderMethod = env->GetMethodID(classClass, "getClassLoader",
"()Ljava/lang/ClassLoader;");
gClassLoader = env->CallObjectMethod(randomClass, getClassLoaderMethod);
gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass",
"(Ljava/lang/String;)Ljava/lang/Class;");

return JNI_VERSION_1_6;
}

jclass findClass(const char* name) {
return static_cast<jclass>(getEnv()->CallObjectMethod(gClassLoader, gFindClassMethod, getEnv()->NewStringUTF(name)));

}

JNIEnv* getEnv() {
JNIEnv *env;
int status = gJvm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (status < 0) {
status = gJvm->AttachCurrentThread((void**)&env, NULL);
if (status < 0) {
return nullptr;
}
}
return env;

}

1

Решение

Вы должны получить правильный загрузчик классов.

  1. Используйте Win32 FindWindow API, чтобы получить HWND для главного окна приложения. Вы можете использовать инструмент Spy ++, чтобы получить точные свойства этого окна.
  2. Динамически загружать jawt.dll, используя Win32 LoadLibrary API. Эта DLL обычно находится в родительском каталоге каталога, содержащего jvm.dll, Пример:
C:\Program Files (x86)\Java\jre1.8.0_73\bin\jawt.dll
C:\Program Files (x86)\Java\jre1.8.0_73\bin\client\jvm.dll

У вас есть много способов получить LoadLibrary призыв к успеху:

  • просто используйте "jawt.dll"
  • получить путь уже загружен jvm.dll, с помощью GetModuleFileName и построить новый путь с ним.
  • получить путь к текущему исполняемому файлу (должен быть java.exe) передача дескриптора модуля NULL GetModuleFileName, Вы должны получить bin дорожка.

После того, как вы успешно загрузили jawt.dllиспользовать GetProcAdress чтобы получить _JAWT_GetAWT@8 функция, и вызовите это. Exemple:

// error checking committed (for clarity...)
typedef jboolean (JNICALL * PGETAWT)(JNIEnv* env, JAWT* awt);
PGETAWT pGetAWT = (PGETAWT)GetProcAddress( hModJAWT, "_JAWT_GetAWT@8" );
JAWT jawt;
jawt.version = JAWT_VERSION_1_4;
pGetAWT( env, &jawt );

Теперь вы можете назвать замечательный GetComponent API:

jobject jObjMainWindow = jawt->GetComponent( env, (void*)hWndOfTheMainOracleWindow );

Затем используйте JNI для получения jclass этого главного окна, а затем вызвать getClassLoader метод класса Class.

С тот Class Loader, FindClass должно работать намного лучше.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]