forked from Public-Mirror/Textractor
Compare commits
1 Commits
master
...
virtualize
Author | SHA1 | Date | |
---|---|---|---|
|
94f5e5983e |
@ -88,7 +88,7 @@ namespace
|
|||||||
}
|
}
|
||||||
HCode.erase(0, 1);
|
HCode.erase(0, 1);
|
||||||
|
|
||||||
if ((hp.type & USING_STRING))
|
if (hp.type & USING_STRING)
|
||||||
{
|
{
|
||||||
if (HCode[0] == L'F')
|
if (HCode[0] == L'F')
|
||||||
{
|
{
|
||||||
@ -247,7 +247,7 @@ namespace
|
|||||||
if (hp.type & SPLIT_INDIRECT) HCode += L'*' + HexString(hp.split_index);
|
if (hp.type & SPLIT_INDIRECT) HCode += L'*' + HexString(hp.split_index);
|
||||||
|
|
||||||
// Attempt to make the address relative
|
// Attempt to make the address relative
|
||||||
if (processId && !(hp.type & MODULE_OFFSET))
|
if (processId && !(hp.type & (MODULE_OFFSET | VIRTUALIZED)))
|
||||||
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
||||||
if (MEMORY_BASIC_INFORMATION info = {}; VirtualQueryEx(process, (LPCVOID)hp.address, &info, sizeof(info)))
|
if (MEMORY_BASIC_INFORMATION info = {}; VirtualQueryEx(process, (LPCVOID)hp.address, &info, sizeof(info)))
|
||||||
if (auto moduleName = GetModuleFilename(processId, (HMODULE)info.AllocationBase))
|
if (auto moduleName = GetModuleFilename(processId, (HMODULE)info.AllocationBase))
|
||||||
|
@ -31,4 +31,5 @@ enum HookParamType : unsigned
|
|||||||
HOOK_ENGINE = 0x8000,
|
HOOK_ENGINE = 0x8000,
|
||||||
HOOK_ADDITIONAL = 0x10000,
|
HOOK_ADDITIONAL = 0x10000,
|
||||||
KNOWN_UNSTABLE = 0x20000,
|
KNOWN_UNSTABLE = 0x20000,
|
||||||
|
VIRTUALIZED = 0x40000,
|
||||||
};
|
};
|
||||||
|
@ -241,7 +241,8 @@ void SearchForHooks(SearchParam spUser)
|
|||||||
HookParam hp = {};
|
HookParam hp = {};
|
||||||
hp.offset = records[i].offset;
|
hp.offset = records[i].offset;
|
||||||
hp.type = USING_UNICODE | USING_STRING;
|
hp.type = USING_UNICODE | USING_STRING;
|
||||||
hp.address = records[i].address;
|
if (devirtualizeAddress && (hp.address = devirtualizeAddress((void*)records[i].address))) hp.type |= VIRTUALIZED;
|
||||||
|
else hp.address = records[i].address;
|
||||||
hp.padding = records[i].padding;
|
hp.padding = records[i].padding;
|
||||||
hp.codepage = sp.codepage;
|
hp.codepage = sp.codepage;
|
||||||
if (sp.hookPostProcessor) sp.hookPostProcessor(hp);
|
if (sp.hookPostProcessor) sp.hookPostProcessor(hp);
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
extern const char* PIPE_CONNECTED;
|
extern const char* PIPE_CONNECTED;
|
||||||
extern const char* INSERTING_HOOK;
|
extern const char* INSERTING_HOOK;
|
||||||
extern const char* REMOVING_HOOK;
|
extern const char* REMOVING_HOOK;
|
||||||
|
extern const char* FUNC_MISSING;
|
||||||
|
extern const char* MODULE_MISSING;
|
||||||
extern const char* HOOK_FAILED;
|
extern const char* HOOK_FAILED;
|
||||||
extern const char* TOO_MANY_HOOKS;
|
extern const char* TOO_MANY_HOOKS;
|
||||||
|
|
||||||
@ -132,6 +134,16 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
|||||||
|
|
||||||
MH_Initialize();
|
MH_Initialize();
|
||||||
|
|
||||||
|
if (HMODULE addressVirtualizer = GetModuleHandleW(L"hooker.dll"))
|
||||||
|
{
|
||||||
|
static auto virtualizeAddress = GetProcAddress(addressVirtualizer, "virtualize_address"), devirtualizeAddress = GetProcAddress(addressVirtualizer, "devirtualize_address");
|
||||||
|
if (virtualizeAddress && devirtualizeAddress)
|
||||||
|
{
|
||||||
|
::virtualizeAddress = [](uint32_t virtualAddress) { return std::unique_ptr<void*[], Functor<UniversalFree>>(((void** (*)(uint32_t))virtualizeAddress)(virtualAddress)); };
|
||||||
|
::devirtualizeAddress = (uint32_t(*)(void*))devirtualizeAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle(CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr)); // Using std::thread here = deadlock
|
CloseHandle(CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr)); // Using std::thread here = deadlock
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -145,19 +157,36 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
|
void NewHookImpl(HookParam hp, uint64_t address, void* realAddress, LPCSTR lpname, DWORD flag)
|
||||||
{
|
{
|
||||||
if (++currentHook >= MAX_HOOK) return ConsoleOutput(TOO_MANY_HOOKS);
|
if (++currentHook >= MAX_HOOK) return ConsoleOutput(TOO_MANY_HOOKS);
|
||||||
if (lpname && *lpname) strncpy_s(hp.name, lpname, HOOK_NAME_SIZE - 1);
|
if (lpname && *lpname) strncpy_s(hp.name, lpname, HOOK_NAME_SIZE - 1);
|
||||||
ConsoleOutput(INSERTING_HOOK, hp.name);
|
ConsoleOutput(INSERTING_HOOK, hp.name);
|
||||||
RemoveHook(hp.address, 0);
|
RemoveHook(hp.address, 0);
|
||||||
if (!(*hooks)[currentHook].Insert(hp, flag))
|
if (!(*hooks)[currentHook].Insert(hp, address, realAddress, flag))
|
||||||
{
|
{
|
||||||
ConsoleOutput(HOOK_FAILED);
|
ConsoleOutput(HOOK_FAILED);
|
||||||
(*hooks)[currentHook].Clear();
|
(*hooks)[currentHook].Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
|
||||||
|
{
|
||||||
|
auto address = hp.address;
|
||||||
|
if (hp.type & MODULE_OFFSET) // Map hook offset to real address
|
||||||
|
if (hp.type & FUNCTION_OFFSET)
|
||||||
|
if (FARPROC function = GetProcAddress(GetModuleHandleW(hp.module), hp.function)) address += (uint64_t)function;
|
||||||
|
else return ConsoleOutput(FUNC_MISSING);
|
||||||
|
else if (HMODULE moduleBase = GetModuleHandleW(hp.module)) address += (uint64_t)moduleBase;
|
||||||
|
else return ConsoleOutput(MODULE_MISSING);
|
||||||
|
if (auto realAddresses = virtualizeAddress && address < UINT32_MAX ? virtualizeAddress(address) : nullptr)
|
||||||
|
{
|
||||||
|
hp.type |= VIRTUALIZED;
|
||||||
|
for (int i = 0; realAddresses[i]; ++i) NewHookImpl(hp, address, realAddresses[i], lpname, flag);
|
||||||
|
}
|
||||||
|
else NewHookImpl(hp, address, (void*)address, lpname, flag);
|
||||||
|
}
|
||||||
|
|
||||||
void RemoveHook(uint64_t addr, int maxOffset)
|
void RemoveHook(uint64_t addr, int maxOffset)
|
||||||
{
|
{
|
||||||
for (auto& hook : *hooks) if (abs((long long)(hook.address - addr)) <= maxOffset) return hook.Clear();
|
for (auto& hook : *hooks) if (abs((long long)(hook.address - addr)) <= maxOffset) return hook.Clear();
|
||||||
|
@ -15,6 +15,10 @@ void RemoveHook(uint64_t addr, int maxOffset = 9);
|
|||||||
|
|
||||||
inline SearchParam spDefault;
|
inline SearchParam spDefault;
|
||||||
|
|
||||||
|
inline void UniversalFree(LPVOID address) { HeapFree(GetProcessHeap(), 0, address); }
|
||||||
|
inline std::unique_ptr<void*[], Functor<UniversalFree>>(*virtualizeAddress)(uint32_t virtualAddress) = nullptr;
|
||||||
|
inline uint32_t(*devirtualizeAddress)(void* realAddress) = nullptr;
|
||||||
|
|
||||||
extern "C" // minhook library
|
extern "C" // minhook library
|
||||||
{
|
{
|
||||||
enum MH_STATUS
|
enum MH_STATUS
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "ithsys/ithsys.h"
|
#include "ithsys/ithsys.h"
|
||||||
|
|
||||||
extern const char* FUNC_MISSING;
|
|
||||||
extern const char* MODULE_MISSING;
|
|
||||||
extern const char* GARBAGE_MEMORY;
|
extern const char* GARBAGE_MEMORY;
|
||||||
extern const char* SEND_ERROR;
|
extern const char* SEND_ERROR;
|
||||||
extern const char* READ_ERROR;
|
extern const char* READ_ERROR;
|
||||||
@ -98,14 +96,15 @@ namespace { // unnamed
|
|||||||
|
|
||||||
// - TextHook methods -
|
// - TextHook methods -
|
||||||
|
|
||||||
bool TextHook::Insert(HookParam hp, DWORD set_flag)
|
bool TextHook::Insert(HookParam hp, uint64_t address, void* realAddress, DWORD set_flag)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(viewMutex);
|
std::scoped_lock lock(viewMutex);
|
||||||
hp.type |= set_flag;
|
hp.type |= set_flag;
|
||||||
if (hp.type & USING_UTF8) hp.codepage = CP_UTF8;
|
if (hp.type & USING_UTF8) hp.codepage = CP_UTF8;
|
||||||
this->hp = hp;
|
this->hp = hp;
|
||||||
address = hp.address;
|
this->address = address;
|
||||||
|
this->location = realAddress;
|
||||||
}
|
}
|
||||||
if (hp.type & DIRECT_READ) return InsertReadCode();
|
if (hp.type & DIRECT_READ) return InsertReadCode();
|
||||||
return InsertHookCode();
|
return InsertHookCode();
|
||||||
@ -209,13 +208,6 @@ bool TextHook::InsertHookCode()
|
|||||||
{
|
{
|
||||||
// jichi 9/17/2013: might raise 0xC0000005 AccessViolationException on win7
|
// jichi 9/17/2013: might raise 0xC0000005 AccessViolationException on win7
|
||||||
// Artikash 10/30/2018: No, I think that's impossible now that I moved to minhook
|
// Artikash 10/30/2018: No, I think that's impossible now that I moved to minhook
|
||||||
if (hp.type & MODULE_OFFSET) // Map hook offset to real address
|
|
||||||
if (hp.type & FUNCTION_OFFSET)
|
|
||||||
if (FARPROC function = GetProcAddress(GetModuleHandleW(hp.module), hp.function)) address += (uint64_t)function;
|
|
||||||
else return ConsoleOutput(FUNC_MISSING), false;
|
|
||||||
else if (HMODULE moduleBase = GetModuleHandleW(hp.module)) address += (uint64_t)moduleBase;
|
|
||||||
else return ConsoleOutput(MODULE_MISSING), false;
|
|
||||||
|
|
||||||
VirtualProtect(location, 10, PAGE_EXECUTE_READWRITE, DUMMY);
|
VirtualProtect(location, 10, PAGE_EXECUTE_READWRITE, DUMMY);
|
||||||
void* original;
|
void* original;
|
||||||
MH_STATUS error;
|
MH_STATUS error;
|
||||||
|
@ -25,13 +25,9 @@ class TextHook
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
union
|
uint64_t address; // Absolute address
|
||||||
{
|
|
||||||
uint64_t address;
|
|
||||||
void* location;
|
|
||||||
}; // Absolute address
|
|
||||||
|
|
||||||
bool Insert(HookParam hp, DWORD set_flag);
|
bool Insert(HookParam hp, uint64_t address, void* realAddress, DWORD set_flag);
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -45,6 +41,7 @@ private:
|
|||||||
void RemoveReadCode();
|
void RemoveReadCode();
|
||||||
|
|
||||||
volatile DWORD useCount;
|
volatile DWORD useCount;
|
||||||
|
void* location;
|
||||||
HANDLE readerThread, readerEvent;
|
HANDLE readerThread, readerEvent;
|
||||||
bool err;
|
bool err;
|
||||||
BYTE trampoline[x64 ? 140 : 40];
|
BYTE trampoline[x64 ? 140 : 40];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user