forked from Public-Mirror/Textractor
implement communication with emulator for virtual addresses
This commit is contained in:
parent
93238e13ed
commit
94f5e5983e
@ -88,7 +88,7 @@ namespace
|
||||
}
|
||||
HCode.erase(0, 1);
|
||||
|
||||
if ((hp.type & USING_STRING))
|
||||
if (hp.type & USING_STRING)
|
||||
{
|
||||
if (HCode[0] == L'F')
|
||||
{
|
||||
@ -247,7 +247,7 @@ namespace
|
||||
if (hp.type & SPLIT_INDIRECT) HCode += L'*' + HexString(hp.split_index);
|
||||
|
||||
// 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 (MEMORY_BASIC_INFORMATION info = {}; VirtualQueryEx(process, (LPCVOID)hp.address, &info, sizeof(info)))
|
||||
if (auto moduleName = GetModuleFilename(processId, (HMODULE)info.AllocationBase))
|
||||
|
@ -31,4 +31,5 @@ enum HookParamType : unsigned
|
||||
HOOK_ENGINE = 0x8000,
|
||||
HOOK_ADDITIONAL = 0x10000,
|
||||
KNOWN_UNSTABLE = 0x20000,
|
||||
VIRTUALIZED = 0x40000,
|
||||
};
|
||||
|
@ -241,7 +241,8 @@ void SearchForHooks(SearchParam spUser)
|
||||
HookParam hp = {};
|
||||
hp.offset = records[i].offset;
|
||||
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.codepage = sp.codepage;
|
||||
if (sp.hookPostProcessor) sp.hookPostProcessor(hp);
|
||||
|
@ -13,6 +13,8 @@
|
||||
extern const char* PIPE_CONNECTED;
|
||||
extern const char* INSERTING_HOOK;
|
||||
extern const char* REMOVING_HOOK;
|
||||
extern const char* FUNC_MISSING;
|
||||
extern const char* MODULE_MISSING;
|
||||
extern const char* HOOK_FAILED;
|
||||
extern const char* TOO_MANY_HOOKS;
|
||||
|
||||
@ -132,6 +134,16 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
||||
|
||||
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
|
||||
}
|
||||
break;
|
||||
@ -145,19 +157,36 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
||||
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 (lpname && *lpname) strncpy_s(hp.name, lpname, HOOK_NAME_SIZE - 1);
|
||||
ConsoleOutput(INSERTING_HOOK, hp.name);
|
||||
RemoveHook(hp.address, 0);
|
||||
if (!(*hooks)[currentHook].Insert(hp, flag))
|
||||
if (!(*hooks)[currentHook].Insert(hp, address, realAddress, flag))
|
||||
{
|
||||
ConsoleOutput(HOOK_FAILED);
|
||||
(*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)
|
||||
{
|
||||
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 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
|
||||
{
|
||||
enum MH_STATUS
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include "main.h"
|
||||
#include "ithsys/ithsys.h"
|
||||
|
||||
extern const char* FUNC_MISSING;
|
||||
extern const char* MODULE_MISSING;
|
||||
extern const char* GARBAGE_MEMORY;
|
||||
extern const char* SEND_ERROR;
|
||||
extern const char* READ_ERROR;
|
||||
@ -98,14 +96,15 @@ namespace { // unnamed
|
||||
|
||||
// - 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);
|
||||
hp.type |= set_flag;
|
||||
if (hp.type & USING_UTF8) hp.codepage = CP_UTF8;
|
||||
this->hp = hp;
|
||||
address = hp.address;
|
||||
this->address = address;
|
||||
this->location = realAddress;
|
||||
}
|
||||
if (hp.type & DIRECT_READ) return InsertReadCode();
|
||||
return InsertHookCode();
|
||||
@ -209,13 +208,6 @@ bool TextHook::InsertHookCode()
|
||||
{
|
||||
// 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
|
||||
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);
|
||||
void* original;
|
||||
MH_STATUS error;
|
||||
|
@ -25,13 +25,9 @@ class TextHook
|
||||
{
|
||||
public:
|
||||
HookParam hp;
|
||||
union
|
||||
{
|
||||
uint64_t address;
|
||||
void* location;
|
||||
}; // Absolute address
|
||||
uint64_t address; // Absolute address
|
||||
|
||||
bool Insert(HookParam hp, DWORD set_flag);
|
||||
bool Insert(HookParam hp, uint64_t address, void* realAddress, DWORD set_flag);
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
@ -45,6 +41,7 @@ private:
|
||||
void RemoveReadCode();
|
||||
|
||||
volatile DWORD useCount;
|
||||
void* location;
|
||||
HANDLE readerThread, readerEvent;
|
||||
bool err;
|
||||
BYTE trampoline[x64 ? 140 : 40];
|
||||
|
Loading…
x
Reference in New Issue
Block a user