From 385af259a91d97f20fd4e49d08e4b2ae01c06ca7 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Sat, 1 Dec 2018 15:53:54 -0500 Subject: [PATCH] dont use terminatethread and other refactors --- vnrhook/engine/match.cc | 6 ++++ vnrhook/main.h | 4 +-- vnrhook/texthook.cc | 76 +++++++++++++++++------------------------ vnrhook/texthook.h | 11 +++--- 4 files changed, 44 insertions(+), 53 deletions(-) diff --git a/vnrhook/engine/match.cc b/vnrhook/engine/match.cc index 7cbf14a..5a73888 100644 --- a/vnrhook/engine/match.cc +++ b/vnrhook/engine/match.cc @@ -29,6 +29,12 @@ WCHAR *processName, // cached processPath[MAX_PATH]; // cached //LPVOID trigger_addr; +/** jichi 12/24/2014 + * @param addr function address + * @param frame real address of the function, supposed to be the same as addr + * @param stack address of current stack - 4 + * @return If success, which is reverted +*/ trigger_fun_t trigger_fun_; } // namespace Engine diff --git a/vnrhook/main.h b/vnrhook/main.h index c71dd9c..99253e3 100644 --- a/vnrhook/main.h +++ b/vnrhook/main.h @@ -8,10 +8,10 @@ #include "types.h" void TextOutput(ThreadParam tp, BYTE* text, int len); -void ConsoleOutput(LPCSTR text); +void ConsoleOutput(LPCSTR text, ...); void NotifyHookRemove(uint64_t addr); void NewHook(HookParam hp, LPCSTR name, DWORD flag = HOOK_ENGINE); -void RemoveHook(uint64_t addr); +void RemoveHook(uint64_t addr, int maxOffset = 9); #define ITH_RAISE (*(int*)0 = 0) // raise C000005, for debugging only #define ITH_TRY __try diff --git a/vnrhook/texthook.cc b/vnrhook/texthook.cc index dd9e4c8..0f9a63e 100644 --- a/vnrhook/texthook.cc +++ b/vnrhook/texthook.cc @@ -19,7 +19,7 @@ #include "growl.h" #include -extern std::unique_ptr sectionMutex; +extern std::unique_ptr viewMutex; // - Unnamed helpers - @@ -95,16 +95,17 @@ void SetTrigger() // - TextHook methods - -bool TextHook::InsertHook() +bool TextHook::Insert(HookParam h, DWORD set_flag) { - //ConsoleOutput("vnrcli:InsertHook: enter"); - LOCK(*sectionMutex); + LOCK(*viewMutex); + hp = h; + hp.insertion_address = hp.address; + hp.type |= set_flag; if (hp.type & USING_UTF8) hp.codepage = CP_UTF8; if (hp.type & DIRECT_READ) return InsertReadCode(); #ifndef _WIN64 else return InsertHookCode(); #endif - //ConsoleOutput("vnrcli:InsertHook: leave"); return false; } @@ -126,12 +127,6 @@ void TextHook::Send(DWORD dwDataBase) dwAddr = hp.insertion_address; dwRetn = *(DWORD*)dwDataBase; // first value on stack (if hooked start of function, this is return address) - /** jichi 12/24/2014 - * @param addr function address - * @param frame real address of the function, supposed to be the same as addr - * @param stack address of current stack - 4 - * @return If success, which is reverted - */ if (trigger) trigger = Engine::InsertDynamicHook((LPVOID)dwAddr, *(DWORD *)(dwDataBase - 0x1c), *(DWORD *)(dwDataBase - 0x18)); @@ -166,7 +161,7 @@ void TextHook::Send(DWORD dwDataBase) } dwCount = GetLength(dwDataBase, dwDataIn); } - // jichi 12/25/2013: validate data size + if (dwCount == 0 || dwCount > PIPE_BUFFER_SIZE - sizeof(ThreadParam)) return; if (hp.length_offset == 1) { @@ -180,7 +175,6 @@ void TextHook::Send(DWORD dwDataBase) else ::memcpy(pbData, (void*)dwDataIn, dwCount); - // jichi 10/14/2014: Add filter function if (hp.filter_fun && !hp.filter_fun(pbData, &dwCount, &hp, 0) || dwCount <= 0) return; if (dwType & (NO_CONTEXT | FIXING_SPLIT)) @@ -219,24 +213,23 @@ insert: return false; } - +#ifndef _WIN64 *(TextHook**)(common_hook + 9) = this; *(void(TextHook::**)(DWORD))(common_hook + 14) = &TextHook::Send; *(void**)(common_hook + 24) = original; memcpy(trampoline, common_hook, sizeof(common_hook)); +#else // _WIN32 + BYTE* original; + MH_CreateHook((void*)hp.address, (void*)trampoline, (void**)&original); + memcpy(trampoline, common_hook, sizeof(common_hook)); + void* thisPtr = (void*)this; + memcpy(trampoline + 30, &thisPtr, sizeof(void*)); + auto sendPtr = (void(TextHook::*)(void*))&TextHook::Send; + memcpy(trampoline + 46, &sendPtr, sizeof(sendPtr)); + memcpy(trampoline + sizeof(common_hook) - 8, &original, sizeof(void*)); +#endif // _WIN64 - //BYTE* original; - //MH_CreateHook((void*)hp.address, (void*)trampoline, (void**)&original); - //memcpy(trampoline, common_hook, sizeof(common_hook)); - //void* thisPtr = (void*)this; - //memcpy(trampoline + 30, &thisPtr, sizeof(void*)); - //auto sendPtr = (void(TextHook::*)(void*))&TextHook::Send; - //memcpy(trampoline + 46, &sendPtr, sizeof(sendPtr)); - //memcpy(trampoline + sizeof(common_hook) - 8, &original, sizeof(void*)); - - if (MH_EnableHook((void*)hp.insertion_address) != MH_OK) return false; - - return true; + return MH_EnableHook((void*)hp.insertion_address) == MH_OK; } #endif // _WIN32 @@ -249,10 +242,9 @@ DWORD WINAPI Reader(LPVOID hookPtr) __try { const void* currentAddress = (void*)hook->hp.insertion_address; - while (true) + while (WaitForSingleObject(hook->readerEvent, 500) == WAIT_TIMEOUT) { if (hook->hp.type & DATA_INDIRECT) currentAddress = *((char**)hook->hp.insertion_address + hook->hp.index); - Sleep(500); if (memcmp(buffer, currentAddress, dataLen + 1) == 0) { changeCount = 0; @@ -261,6 +253,7 @@ DWORD WINAPI Reader(LPVOID hookPtr) if (++changeCount > 10) { ConsoleOutput(GARBAGE_MEMORY); + hook->Clear(); break; } @@ -276,27 +269,18 @@ DWORD WINAPI Reader(LPVOID hookPtr) __except (EXCEPTION_EXECUTE_HANDLER) { ConsoleOutput("Textractor: Reader ERROR (likely an incorrect R-code)"); + hook->Clear(); } - hook->ClearHook(); return 0; } bool TextHook::InsertReadCode() { - //RemoveHook(hp.address); // Artikash 8/25/2018: clear existing - readerHandle = CreateThread(nullptr, 0, Reader, this, 0, nullptr); + readerThread = CreateThread(nullptr, 0, Reader, this, 0, nullptr); + readerEvent = CreateEventW(nullptr, FALSE, FALSE, NULL); return true; } -void TextHook::InitHook(HookParam h, LPCSTR name, DWORD set_flag) -{ - LOCK(*sectionMutex); - hp = h; - hp.insertion_address = hp.address; - hp.type |= set_flag; - strcpy_s(hookName, name); -} - void TextHook::RemoveHookCode() { MH_DisableHook((void*)hp.insertion_address); @@ -305,14 +289,16 @@ void TextHook::RemoveHookCode() void TextHook::RemoveReadCode() { - TerminateThread(readerHandle, 0); - CloseHandle(readerHandle); + SetEvent(readerEvent); + if (GetThreadId(readerThread) != GetCurrentThreadId()) WaitForSingleObject(readerThread, 1000); + CloseHandle(readerEvent); + CloseHandle(readerThread); } -void TextHook::ClearHook() +void TextHook::Clear() { - LOCK(*sectionMutex); - ConsoleOutput((REMOVING_HOOK + std::string(hookName)).c_str()); + LOCK(*viewMutex); + ConsoleOutput(REMOVING_HOOK, hp.name); if (hp.type & DIRECT_READ) RemoveReadCode(); else RemoveHookCode(); NotifyHookRemove(hp.insertion_address); diff --git a/vnrhook/texthook.h b/vnrhook/texthook.h index 1201a41..ab5a14a 100644 --- a/vnrhook/texthook.h +++ b/vnrhook/texthook.h @@ -23,16 +23,15 @@ class TextHook void RemoveHookCode(); void RemoveReadCode(); + HANDLE readerThread, readerEvent; + BYTE trampoline[120]; public: HookParam hp; - char hookName[HOOK_NAME_SIZE]; - BYTE trampoline[120]; - HANDLE readerHandle; - bool InsertHook(); - void InitHook(HookParam hp, LPCSTR name, DWORD set_flag); + bool Insert(HookParam hp, DWORD set_flag); void Send(DWORD dwDataBase); - void ClearHook(); + void Clear(); + friend DWORD WINAPI Reader(LPVOID hookPtr); }; enum { MAX_HOOK = 300, HOOK_BUFFER_SIZE = MAX_HOOK * sizeof(TextHook), HOOK_SECTION_SIZE = HOOK_BUFFER_SIZE * 2 };