implement communication with emulator for virtual addresses

This commit is contained in:
Akash Mozumdar 2020-09-08 22:19:33 -06:00
parent 93238e13ed
commit 94f5e5983e
7 changed files with 46 additions and 22 deletions

View File

@ -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))

View File

@ -31,4 +31,5 @@ enum HookParamType : unsigned
HOOK_ENGINE = 0x8000,
HOOK_ADDITIONAL = 0x10000,
KNOWN_UNSTABLE = 0x20000,
VIRTUALIZED = 0x40000,
};

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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];