forked from Public-Mirror/Textractor
dont use terminatethread and other refactors
This commit is contained in:
parent
2f544afaa5
commit
385af259a9
@ -29,6 +29,12 @@ WCHAR *processName, // cached
|
|||||||
processPath[MAX_PATH]; // cached
|
processPath[MAX_PATH]; // cached
|
||||||
|
|
||||||
//LPVOID trigger_addr;
|
//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_;
|
trigger_fun_t trigger_fun_;
|
||||||
|
|
||||||
} // namespace Engine
|
} // namespace Engine
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void TextOutput(ThreadParam tp, BYTE* text, int len);
|
void TextOutput(ThreadParam tp, BYTE* text, int len);
|
||||||
void ConsoleOutput(LPCSTR text);
|
void ConsoleOutput(LPCSTR text, ...);
|
||||||
void NotifyHookRemove(uint64_t addr);
|
void NotifyHookRemove(uint64_t addr);
|
||||||
void NewHook(HookParam hp, LPCSTR name, DWORD flag = HOOK_ENGINE);
|
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_RAISE (*(int*)0 = 0) // raise C000005, for debugging only
|
||||||
#define ITH_TRY __try
|
#define ITH_TRY __try
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "growl.h"
|
#include "growl.h"
|
||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
|
|
||||||
extern std::unique_ptr<WinMutex> sectionMutex;
|
extern std::unique_ptr<WinMutex> viewMutex;
|
||||||
|
|
||||||
// - Unnamed helpers -
|
// - Unnamed helpers -
|
||||||
|
|
||||||
@ -95,16 +95,17 @@ void SetTrigger()
|
|||||||
|
|
||||||
// - TextHook methods -
|
// - TextHook methods -
|
||||||
|
|
||||||
bool TextHook::InsertHook()
|
bool TextHook::Insert(HookParam h, DWORD set_flag)
|
||||||
{
|
{
|
||||||
//ConsoleOutput("vnrcli:InsertHook: enter");
|
LOCK(*viewMutex);
|
||||||
LOCK(*sectionMutex);
|
hp = h;
|
||||||
|
hp.insertion_address = hp.address;
|
||||||
|
hp.type |= set_flag;
|
||||||
if (hp.type & USING_UTF8) hp.codepage = CP_UTF8;
|
if (hp.type & USING_UTF8) hp.codepage = CP_UTF8;
|
||||||
if (hp.type & DIRECT_READ) return InsertReadCode();
|
if (hp.type & DIRECT_READ) return InsertReadCode();
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
else return InsertHookCode();
|
else return InsertHookCode();
|
||||||
#endif
|
#endif
|
||||||
//ConsoleOutput("vnrcli:InsertHook: leave");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,12 +127,6 @@ void TextHook::Send(DWORD dwDataBase)
|
|||||||
dwAddr = hp.insertion_address;
|
dwAddr = hp.insertion_address;
|
||||||
dwRetn = *(DWORD*)dwDataBase; // first value on stack (if hooked start of function, this is return 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)
|
if (trigger)
|
||||||
trigger = Engine::InsertDynamicHook((LPVOID)dwAddr, *(DWORD *)(dwDataBase - 0x1c), *(DWORD *)(dwDataBase - 0x18));
|
trigger = Engine::InsertDynamicHook((LPVOID)dwAddr, *(DWORD *)(dwDataBase - 0x1c), *(DWORD *)(dwDataBase - 0x18));
|
||||||
|
|
||||||
@ -166,7 +161,7 @@ void TextHook::Send(DWORD dwDataBase)
|
|||||||
}
|
}
|
||||||
dwCount = GetLength(dwDataBase, dwDataIn);
|
dwCount = GetLength(dwDataBase, dwDataIn);
|
||||||
}
|
}
|
||||||
// jichi 12/25/2013: validate data size
|
|
||||||
if (dwCount == 0 || dwCount > PIPE_BUFFER_SIZE - sizeof(ThreadParam)) return;
|
if (dwCount == 0 || dwCount > PIPE_BUFFER_SIZE - sizeof(ThreadParam)) return;
|
||||||
|
|
||||||
if (hp.length_offset == 1) {
|
if (hp.length_offset == 1) {
|
||||||
@ -180,7 +175,6 @@ void TextHook::Send(DWORD dwDataBase)
|
|||||||
else
|
else
|
||||||
::memcpy(pbData, (void*)dwDataIn, dwCount);
|
::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 (hp.filter_fun && !hp.filter_fun(pbData, &dwCount, &hp, 0) || dwCount <= 0) return;
|
||||||
|
|
||||||
if (dwType & (NO_CONTEXT | FIXING_SPLIT))
|
if (dwType & (NO_CONTEXT | FIXING_SPLIT))
|
||||||
@ -219,24 +213,23 @@ insert:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
*(TextHook**)(common_hook + 9) = this;
|
*(TextHook**)(common_hook + 9) = this;
|
||||||
*(void(TextHook::**)(DWORD))(common_hook + 14) = &TextHook::Send;
|
*(void(TextHook::**)(DWORD))(common_hook + 14) = &TextHook::Send;
|
||||||
*(void**)(common_hook + 24) = original;
|
*(void**)(common_hook + 24) = original;
|
||||||
memcpy(trampoline, common_hook, sizeof(common_hook));
|
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;
|
return MH_EnableHook((void*)hp.insertion_address) == MH_OK;
|
||||||
//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;
|
|
||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
@ -249,10 +242,9 @@ DWORD WINAPI Reader(LPVOID hookPtr)
|
|||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
const void* currentAddress = (void*)hook->hp.insertion_address;
|
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);
|
if (hook->hp.type & DATA_INDIRECT) currentAddress = *((char**)hook->hp.insertion_address + hook->hp.index);
|
||||||
Sleep(500);
|
|
||||||
if (memcmp(buffer, currentAddress, dataLen + 1) == 0)
|
if (memcmp(buffer, currentAddress, dataLen + 1) == 0)
|
||||||
{
|
{
|
||||||
changeCount = 0;
|
changeCount = 0;
|
||||||
@ -261,6 +253,7 @@ DWORD WINAPI Reader(LPVOID hookPtr)
|
|||||||
if (++changeCount > 10)
|
if (++changeCount > 10)
|
||||||
{
|
{
|
||||||
ConsoleOutput(GARBAGE_MEMORY);
|
ConsoleOutput(GARBAGE_MEMORY);
|
||||||
|
hook->Clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,27 +269,18 @@ DWORD WINAPI Reader(LPVOID hookPtr)
|
|||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
ConsoleOutput("Textractor: Reader ERROR (likely an incorrect R-code)");
|
ConsoleOutput("Textractor: Reader ERROR (likely an incorrect R-code)");
|
||||||
|
hook->Clear();
|
||||||
}
|
}
|
||||||
hook->ClearHook();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextHook::InsertReadCode()
|
bool TextHook::InsertReadCode()
|
||||||
{
|
{
|
||||||
//RemoveHook(hp.address); // Artikash 8/25/2018: clear existing
|
readerThread = CreateThread(nullptr, 0, Reader, this, 0, nullptr);
|
||||||
readerHandle = CreateThread(nullptr, 0, Reader, this, 0, nullptr);
|
readerEvent = CreateEventW(nullptr, FALSE, FALSE, NULL);
|
||||||
return true;
|
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<HOOK_NAME_SIZE>(hookName, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextHook::RemoveHookCode()
|
void TextHook::RemoveHookCode()
|
||||||
{
|
{
|
||||||
MH_DisableHook((void*)hp.insertion_address);
|
MH_DisableHook((void*)hp.insertion_address);
|
||||||
@ -305,14 +289,16 @@ void TextHook::RemoveHookCode()
|
|||||||
|
|
||||||
void TextHook::RemoveReadCode()
|
void TextHook::RemoveReadCode()
|
||||||
{
|
{
|
||||||
TerminateThread(readerHandle, 0);
|
SetEvent(readerEvent);
|
||||||
CloseHandle(readerHandle);
|
if (GetThreadId(readerThread) != GetCurrentThreadId()) WaitForSingleObject(readerThread, 1000);
|
||||||
|
CloseHandle(readerEvent);
|
||||||
|
CloseHandle(readerThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHook::ClearHook()
|
void TextHook::Clear()
|
||||||
{
|
{
|
||||||
LOCK(*sectionMutex);
|
LOCK(*viewMutex);
|
||||||
ConsoleOutput((REMOVING_HOOK + std::string(hookName)).c_str());
|
ConsoleOutput(REMOVING_HOOK, hp.name);
|
||||||
if (hp.type & DIRECT_READ) RemoveReadCode();
|
if (hp.type & DIRECT_READ) RemoveReadCode();
|
||||||
else RemoveHookCode();
|
else RemoveHookCode();
|
||||||
NotifyHookRemove(hp.insertion_address);
|
NotifyHookRemove(hp.insertion_address);
|
||||||
|
@ -23,16 +23,15 @@ class TextHook
|
|||||||
void RemoveHookCode();
|
void RemoveHookCode();
|
||||||
void RemoveReadCode();
|
void RemoveReadCode();
|
||||||
|
|
||||||
|
HANDLE readerThread, readerEvent;
|
||||||
|
BYTE trampoline[120];
|
||||||
public:
|
public:
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
char hookName[HOOK_NAME_SIZE];
|
|
||||||
BYTE trampoline[120];
|
|
||||||
HANDLE readerHandle;
|
|
||||||
|
|
||||||
bool InsertHook();
|
bool Insert(HookParam hp, DWORD set_flag);
|
||||||
void InitHook(HookParam hp, LPCSTR name, DWORD set_flag);
|
|
||||||
void Send(DWORD dwDataBase);
|
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 };
|
enum { MAX_HOOK = 300, HOOK_BUFFER_SIZE = MAX_HOOK * sizeof(TextHook), HOOK_SECTION_SIZE = HOOK_BUFFER_SIZE * 2 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user