diff --git a/GUI/misc.cpp b/GUI/misc.cpp index d8deeef..12f58ac 100644 --- a/GUI/misc.cpp +++ b/GUI/misc.cpp @@ -58,10 +58,13 @@ namespace return {}; } RCode.remove(0, 1); - QRegExp stringGap("^\\-?[\\dA-F]+"); - if (stringGap.indexIn(RCode) == -1) return {}; - hp.offset = stringGap.cap(0).toInt(nullptr, 16); - RCode.remove(0, stringGap.cap(0).length()); + QRegExp stringGap("^\\*(\\-?[\\dA-F]+)"); + if (stringGap.indexIn(RCode) != -1) + { + hp.index = stringGap.cap(1).toInt(nullptr, 16); + RCode.remove(0, stringGap.cap(0).length()); + hp.type |= DATA_INDIRECT; + } if (RCode.at(0).unicode() != L'@') return {}; RCode.remove(0, 1); QRegExp address("[\\dA-F]+$"); diff --git a/include/types.h b/include/types.h index 115314e..0755013 100644 --- a/include/types.h +++ b/include/types.h @@ -12,7 +12,7 @@ struct HookParam typedef bool(*hook_fun_t)(DWORD esp, HookParam *hp); // jichi 10/24/2014: Add generic hook function, return false if stop execution. unsigned __int64 address; // absolute or relative address - short offset, // offset of the data in the memory + int offset, // offset of the data in the memory index, // deref_offset1 split, // offset of the split character split_index; // deref_offset2 diff --git a/vnrhook/hijack/texthook.cc b/vnrhook/hijack/texthook.cc index 4cde801..405572d 100644 --- a/vnrhook/hijack/texthook.cc +++ b/vnrhook/hijack/texthook.cc @@ -264,7 +264,13 @@ bool TextHook::UnsafeInsertHookCode() } BYTE* original; - if (MH_CreateHook((void*)hp.address, (void*)trampoline, (void**)&original) != MH_OK) return false; + if (int err = MH_CreateHook((void*)hp.address, (void*)trampoline, (void**)&original)) + if (err == MH_ERROR_ALREADY_CREATED) RemoveHook(hp.address); + else + { + ConsoleOutput(("NextHooker: UnsafeInsertHookCode: FAILED: error " + std::to_string(err)).c_str()); + return false; + } void* thisPtr = (void*)this; void* funcPtr = (void*)((BYTE*)ProcessHook - (BYTE*)(trampoline + 19)); @@ -290,15 +296,26 @@ bool TextHook::UnsafeInsertHookCode() } #endif // _WIN32 -DWORD WINAPI ReaderThread(LPVOID threadParam) +DWORD WINAPI ReaderThread(LPVOID hookPtr) { - TextHook* hook = (TextHook*)threadParam; + TextHook* hook = (TextHook*)hookPtr; BYTE buffer[PIPE_BUFFER_SIZE] = {}; unsigned int changeCount = 0; int dataLen = 0; - const char* currentAddress = (char*)hook->hp.address; + const void* currentAddress = (void*)hook->hp.address; while (true) { + if (!IthGetMemoryRange((void*)hook->hp.address, nullptr, nullptr)) + { + ConsoleOutput("NextHooker: can't read desired address"); + break; + } + if (hook->hp.type & DATA_INDIRECT) currentAddress = *((char**)hook->hp.address + hook->hp.index); + if (!IthGetMemoryRange(currentAddress, nullptr, nullptr)) + { + ConsoleOutput("NextHooker: can't read desired address"); + break; + } Sleep(500); if (memcmp(buffer + sizeof(ThreadParam), currentAddress, dataLen + 1) == 0) { @@ -308,20 +325,20 @@ DWORD WINAPI ReaderThread(LPVOID threadParam) if (++changeCount > 10) { ConsoleOutput("NextHooker: memory constantly changing, useless to read"); - ConsoleOutput("NextHooker: remove read code"); break; } if (hook->hp.type & USING_UNICODE) dataLen = wcslen((const wchar_t*)currentAddress) * 2; else - dataLen = strlen(currentAddress); + dataLen = strlen((const char*)currentAddress); *(ThreadParam*)buffer = { GetCurrentProcessId(), hook->hp.address, 0, 0 }; memcpy(buffer + sizeof(ThreadParam), currentAddress, dataLen + 1); DWORD unused; WriteFile(::hookPipe, buffer, dataLen + sizeof(ThreadParam), &unused, nullptr); } + ConsoleOutput("NextHooker: remove read code"); hook->ClearHook(); return 0; } @@ -329,11 +346,6 @@ DWORD WINAPI ReaderThread(LPVOID threadParam) bool TextHook::InsertReadCode() { RemoveHook(hp.address); // Artikash 8/25/2018: clear existing - if (!IthGetMemoryRange((LPCVOID)hp.address, 0, 0)) - { - ConsoleOutput("NextHooker:InsertReadCode failed: cannot access read address"); - return false; - } hp.readerHandle = CreateThread(nullptr, 0, ReaderThread, this, 0, nullptr); return true; }