refactor. less global variables

This commit is contained in:
Akash Mozumdar 2018-11-10 23:29:12 -05:00
parent f351148b3d
commit d0f48a67a4
9 changed files with 159 additions and 197 deletions

View File

@ -5,7 +5,7 @@
#include "host.h" #include "host.h"
#include "const.h" #include "const.h"
#include "defs.h" #include "defs.h"
#include "../vnrhook/hijack/texthook.h" #include "../vnrhook/texthook.h"
namespace namespace
{ {
@ -51,7 +51,7 @@ namespace
std::recursive_mutex hostMutex; std::recursive_mutex hostMutex;
DWORD DUMMY[1]; DWORD DUMMY;
ThreadParam CONSOLE{ 0, -1ULL, -1ULL, -1ULL }, CLIPBOARD{ 0, 0, -1ULL, -1ULL }; ThreadParam CONSOLE{ 0, -1ULL, -1ULL, -1ULL }, CLIPBOARD{ 0, 0, -1ULL, -1ULL };
void DispatchText(ThreadParam tp, const BYTE* text, int len) void DispatchText(ThreadParam tp, const BYTE* text, int len)
@ -111,7 +111,7 @@ namespace
CreatePipe(); CreatePipe();
while (ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr)) while (ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr))
switch (*(int*)buffer) switch (*(HostNotificationType*)buffer)
{ {
case HOST_NOTIFICATION_RMVHOOK: case HOST_NOTIFICATION_RMVHOOK:
{ {
@ -242,22 +242,22 @@ namespace Host
void DetachProcess(DWORD processId) void DetachProcess(DWORD processId)
{ {
LOCK(hostMutex); LOCK(hostMutex);
auto command = HOST_COMMAND_DETACH; HostCommandType buffer(HOST_COMMAND_DETACH);
WriteFile(processRecordsByIds.at(processId)->hostPipe, &command, sizeof(command), DUMMY, nullptr); WriteFile(processRecordsByIds.at(processId)->hostPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
} }
void InsertHook(DWORD processId, HookParam hp, std::string name) void InsertHook(DWORD processId, HookParam hp, std::string name)
{ {
LOCK(hostMutex); LOCK(hostMutex);
auto command = InsertHookCmd(hp, name); InsertHookCmd buffer(hp, name);
WriteFile(processRecordsByIds.at(processId)->hostPipe, &command, sizeof(command), DUMMY, nullptr); WriteFile(processRecordsByIds.at(processId)->hostPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
} }
void RemoveHook(DWORD processId, uint64_t addr) void RemoveHook(DWORD processId, uint64_t addr)
{ {
LOCK(hostMutex); LOCK(hostMutex);
auto command = RemoveHookCmd(addr); RemoveHookCmd buffer(addr);
WriteFile(processRecordsByIds.at(processId)->hostPipe, &command, sizeof(command), DUMMY, nullptr); WriteFile(processRecordsByIds.at(processId)->hostPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
} }
HookParam GetHookParam(DWORD processId, uint64_t addr) HookParam GetHookParam(DWORD processId, uint64_t addr)

View File

@ -3,18 +3,16 @@ include_directories(. util)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(vnrhook_src set(vnrhook_src
main.cc main.cc
pipe.cc texthook.cc
util/ithsys/ithsys.cc util/ithsys/ithsys.cc
hijack/texthook.cc
) )
else() else()
set(vnrhook_src set(vnrhook_src
main.cc main.cc
pipe.cc texthook.cc
engine/engine.cc engine/engine.cc
engine/match.cc engine/match.cc
engine/native/pchooks.cc engine/native/pchooks.cc
hijack/texthook.cc
util/util.cc util/util.cc
util/ithsys/ithsys.cc util/ithsys/ithsys.cc
util/disasm/disasm.cc util/disasm/disasm.cc

View File

@ -11,6 +11,7 @@
#include "engine/match.h" #include "engine/match.h"
#include "util/util.h" #include "util/util.h"
#include "main.h" #include "main.h"
#include "texthook.h"
#include "engine/mono/funcinfo.h" #include "engine/mono/funcinfo.h"
#include "engine/ppsspp/funcinfo.h" #include "engine/ppsspp/funcinfo.h"
#include "ithsys/ithsys.h" #include "ithsys/ithsys.h"
@ -2232,7 +2233,7 @@ void InsertRealliveHook()
//ConsoleOutput("Probably Reallive. Wait for text."); //ConsoleOutput("Probably Reallive. Wait for text.");
ConsoleOutput("vnreng: TRIGGER Reallive"); ConsoleOutput("vnreng: TRIGGER Reallive");
trigger_fun_ = InsertRealliveDynamicHook; trigger_fun_ = InsertRealliveDynamicHook;
SwitchTrigger(true); SetTrigger();
} }
namespace { // unnamed namespace { // unnamed
@ -5766,7 +5767,8 @@ int GetShinaRioVersion()
//char *buffer,*version;//,*ptr; //char *buffer,*version;//,*ptr;
enum { BufferSize = 0x40 }; enum { BufferSize = 0x40 };
char buffer[BufferSize]; char buffer[BufferSize];
ReadFile(hFile, buffer, BufferSize, (DWORD*)buffer, nullptr); DWORD DUMMY;
ReadFile(hFile, buffer, BufferSize, &DUMMY, nullptr);
CloseHandle(hFile); CloseHandle(hFile);
if (buffer[0] == '[') { if (buffer[0] == '[') {
buffer[0x3f] = 0; // jichi 8/24/2013: prevent strstr from overflow buffer[0x3f] = 0; // jichi 8/24/2013: prevent strstr from overflow
@ -5785,7 +5787,7 @@ bool InsertShinaHook()
{ {
int ver = GetShinaRioVersion(); int ver = GetShinaRioVersion();
if (ver >= 50) { if (ver >= 50) {
SwitchTrigger(true); SetTrigger();
trigger_fun_ = StackSearchingTrigger<GetGlyphOutlineA, NULL>; trigger_fun_ = StackSearchingTrigger<GetGlyphOutlineA, NULL>;
ConsoleOutput("Textractor: ShinaRio 2.50+: adding trigger"); ConsoleOutput("Textractor: ShinaRio 2.50+: adding trigger");
return true; return true;
@ -5960,7 +5962,7 @@ void InsertWaffleHook()
} }
//ConsoleOutput("Probably Waffle. Wait for text."); //ConsoleOutput("Probably Waffle. Wait for text.");
trigger_fun_ = InsertWaffleDynamicHook; trigger_fun_ = InsertWaffleDynamicHook;
SwitchTrigger(true); SetTrigger();
//ConsoleOutput("vnreng:WAFFLE: failed"); //ConsoleOutput("vnreng:WAFFLE: failed");
} }
@ -8503,7 +8505,7 @@ bool InsertSystemAoiDynamic()
ConsoleOutput("vnreng: DYNAMIC SystemAoi"); ConsoleOutput("vnreng: DYNAMIC SystemAoi");
//ConsoleOutput("Probably SoftHouseChara. Wait for text."); //ConsoleOutput("Probably SoftHouseChara. Wait for text.");
trigger_fun_ = InsertSystemAoiDynamicHook; trigger_fun_ = InsertSystemAoiDynamicHook;
SwitchTrigger(true); SetTrigger();
return true; return true;
} }
@ -8818,7 +8820,7 @@ void InsertIronGameSystemHook()
{ {
//ConsoleOutput("Probably IronGameSystem. Wait for text."); //ConsoleOutput("Probably IronGameSystem. Wait for text.");
trigger_fun_ = InsertIGSDynamicHook; trigger_fun_ = InsertIGSDynamicHook;
SwitchTrigger(true); SetTrigger();
ConsoleOutput("vnreng: TRIGGER IronGameSystem"); ConsoleOutput("vnreng: TRIGGER IronGameSystem");
} }
@ -9454,7 +9456,7 @@ void InsertRyokuchaHook()
{ {
//ConsoleOutput("Probably Ryokucha. Wait for text."); //ConsoleOutput("Probably Ryokucha. Wait for text.");
trigger_fun_ = InsertRyokuchaDynamicHook; trigger_fun_ = InsertRyokuchaDynamicHook;
SwitchTrigger(true); SetTrigger();
ConsoleOutput("vnreng: TRIGGER Ryokucha"); ConsoleOutput("vnreng: TRIGGER Ryokucha");
} }

View File

@ -11,18 +11,107 @@
#include "main.h" #include "main.h"
#include "defs.h" #include "defs.h"
#include "MinHook.h" #include "MinHook.h"
#include "pipe.h"
#include "engine/engine.h" #include "engine/engine.h"
#include "engine/match.h" #include "engine/match.h"
#include "hijack/texthook.h" #include "texthook.h"
#include "util/growl.h" #include "util/growl.h"
HANDLE hSection; HANDLE hSection, hookPipe;
TextHook* hooks;
bool running; bool running;
int currentHook = 0, userhookCount = 0; int currentHook = 0, userhookCount = 0;
DWORD trigger = 0; DWORD DUMMY;
std::unique_ptr<WinMutex> sectionMutex; std::unique_ptr<WinMutex> sectionMutex;
DWORD WINAPI Pipe(LPVOID)
{
while (running)
{
DWORD count = 0;
BYTE buffer[PIPE_BUFFER_SIZE] = {};
HANDLE hostPipe = hookPipe = INVALID_HANDLE_VALUE;
while (hookPipe == INVALID_HANDLE_VALUE || hostPipe == INVALID_HANDLE_VALUE)
{
if (hookPipe == INVALID_HANDLE_VALUE)
{
hookPipe = CreateFileW(HOOK_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
}
if (hookPipe != INVALID_HANDLE_VALUE && hostPipe == INVALID_HANDLE_VALUE)
{
hostPipe = CreateFileW(HOST_PIPE, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
DWORD mode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(hostPipe, &mode, NULL, NULL);
continue;
}
Sleep(50);
}
*(DWORD*)buffer = GetCurrentProcessId();
WriteFile(hookPipe, buffer, sizeof(DWORD), &count, nullptr);
ConsoleOutput("Textractor: pipe connected");
#ifdef _WIN64
ConsoleOutput("Hooks don't work on x64, only read codes work. Engine disabled.");
#else
Engine::Hijack();
#endif
while (running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr))
switch (*(HostCommandType*)buffer)
{
case HOST_COMMAND_NEW_HOOK:
{
auto info = *(InsertHookCmd*)buffer;
NewHook(info.hp, info.name, 0);
}
break;
case HOST_COMMAND_REMOVE_HOOK:
{
auto info = *(RemoveHookCmd*)buffer;
RemoveHook(info.address);
}
break;
case HOST_COMMAND_DETACH:
{
running = false;
}
break;
}
CloseHandle(hostPipe);
CloseHandle(hookPipe);
}
FreeLibraryAndExitThread(GetModuleHandleW(ITH_DLL), 0);
return 0;
}
void TextOutput(ThreadParam tp, BYTE* text, int len)
{
if (len < 0) return;
BYTE buffer[PIPE_BUFFER_SIZE] = {};
*(ThreadParam*)buffer = tp;
memcpy_s(buffer + sizeof(ThreadParam), sizeof(buffer) - sizeof(ThreadParam), text, len);
WriteFile(hookPipe, buffer, sizeof(ThreadParam) + len, &DUMMY, nullptr);
}
void ConsoleOutput(LPCSTR text)
{
ConsoleOutputNotif buffer(text);
WriteFile(hookPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
}
void ConsoleOutput(std::string text)
{
ConsoleOutput(text.c_str());
}
void NotifyHookRemove(uint64_t addr)
{
HookRemovedNotif buffer(addr);
WriteFile(hookPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
}
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID) BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
{ {
switch (fdwReason) switch (fdwReason)
@ -35,23 +124,22 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
// jichi 9/25/2013: Interprocedural communication with vnrsrv. // jichi 9/25/2013: Interprocedural communication with vnrsrv.
hSection = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_EXECUTE_READWRITE, 0, HOOK_SECTION_SIZE, (ITH_SECTION_ + std::to_wstring(GetCurrentProcessId())).c_str()); hSection = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_EXECUTE_READWRITE, 0, HOOK_SECTION_SIZE, (ITH_SECTION_ + std::to_wstring(GetCurrentProcessId())).c_str());
::hookman = (TextHook*)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE); hooks = (TextHook*)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
memset(::hookman, 0, HOOK_BUFFER_SIZE); memset(hooks, 0, HOOK_BUFFER_SIZE);
MH_Initialize(); MH_Initialize();
running = true;
::running = true; CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr);
CreatePipe();
} }
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
{ {
::running = false; running = false;
MH_Uninitialize(); MH_Uninitialize();
for (TextHook *man = ::hookman; man < ::hookman + MAX_HOOK; man++) if (man->hp.insertion_address) man->ClearHook(); for (int i = 0; i < MAX_HOOK; ++i) if (hooks[i].hp.insertion_address) hooks[i].ClearHook();
//if (ith_has_section) //if (ith_has_section)
UnmapViewOfFile(::hookman); UnmapViewOfFile(hooks);
CloseHandle(hSection); CloseHandle(hSection);
//} ITH_EXCEPT {} //} ITH_EXCEPT {}
} }
@ -61,17 +149,17 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
} }
//extern "C" { //extern "C" {
void NewHook(const HookParam &hp, LPCSTR lpname, DWORD flag) void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
{ {
std::string name = lpname; std::string name = lpname;
if (++currentHook < MAX_HOOK) if (++currentHook < MAX_HOOK)
{ {
if (name[0] == '\0') name = "UserHook" + std::to_string(userhookCount++); if (name.empty()) name = "UserHook" + std::to_string(userhookCount++);
ConsoleOutput(("Textractor: try inserting hook: " + name).c_str()); ConsoleOutput("Textractor: try inserting hook: " + name);
// jichi 7/13/2014: This function would raise when too many hooks added // jichi 7/13/2014: This function would raise when too many hooks added
::hookman[currentHook].InitHook(hp, name.c_str(), flag); hooks[currentHook].InitHook(hp, name.c_str(), flag);
if (::hookman[currentHook].InsertHook()) ConsoleOutput(("Textractor: inserted hook: " + name).c_str()); if (hooks[currentHook].InsertHook()) ConsoleOutput("Textractor: inserted hook: " + name);
else ConsoleOutput("Textractor:WARNING: failed to insert hook"); else ConsoleOutput("Textractor:WARNING: failed to insert hook");
} }
else ConsoleOutput("Textractor: too many hooks: can't insert"); else ConsoleOutput("Textractor: too many hooks: can't insert");
@ -80,16 +168,7 @@ void NewHook(const HookParam &hp, LPCSTR lpname, DWORD flag)
void RemoveHook(uint64_t addr) void RemoveHook(uint64_t addr)
{ {
for (int i = 0; i < MAX_HOOK; i++) for (int i = 0; i < MAX_HOOK; i++)
if (abs((long long)(::hookman[i].hp.insertion_address - addr)) < 9) if (abs((long long)(hooks[i].hp.insertion_address - addr)) < 9) return hooks[i].ClearHook();
{
::hookman[i].ClearHook();
return;
}
}
void SwitchTrigger(DWORD t)
{
trigger = t;
} }
// EOF // EOF

View File

@ -6,11 +6,12 @@
#include "common.h" #include "common.h"
#include "types.h" #include "types.h"
#include "pipe.h"
void NewHook(const HookParam &hp, LPCSTR name, DWORD flag = HOOK_ENGINE); void TextOutput(ThreadParam tp, BYTE* text, int len);
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);
void SwitchTrigger(DWORD on);
#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

View File

@ -1,100 +0,0 @@
// pipe.cc
// 8/24/2013 jichi
// Branch: ITH_DLL/pipe.cpp, rev 66
// 8/24/2013 TODO: Clean up this file
#ifdef _MSC_VER
# pragma warning (disable:4100) // C4100: unreference formal parameter
#endif // _MSC_VER
#include "pipe.h"
#include "main.h"
#include "hijack/texthook.h"
#include "engine/match.h"
#include "defs.h"
#include "const.h"
#include "growl.h"
HANDLE hookPipe;
DWORD DUMMY[100];
void CreatePipe()
{
CreateThread(nullptr, 0, [](LPVOID)
{
while (::running)
{
DWORD count = 0;
BYTE buffer[PIPE_BUFFER_SIZE] = {};
HANDLE hostPipe = ::hookPipe = INVALID_HANDLE_VALUE;
while (::hookPipe == INVALID_HANDLE_VALUE || hostPipe == INVALID_HANDLE_VALUE)
{
if (::hookPipe == INVALID_HANDLE_VALUE)
{
::hookPipe = CreateFileW(HOOK_PIPE, GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
}
if (::hookPipe != INVALID_HANDLE_VALUE && hostPipe == INVALID_HANDLE_VALUE)
{
hostPipe = CreateFileW(HOST_PIPE, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
DWORD mode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(hostPipe, &mode, NULL, NULL);
continue;
}
Sleep(50);
}
*(DWORD*)buffer = GetCurrentProcessId();
WriteFile(::hookPipe, buffer, sizeof(DWORD), &count, nullptr);
ConsoleOutput("Textractor: pipe connected");
#ifdef _WIN64
ConsoleOutput("Hooks don't work on x64, only read codes work. Engine disabled.");
#else
Engine::Hijack();
#endif
while (::running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr))
switch (*(int*)buffer)
{
case HOST_COMMAND_NEW_HOOK:
{
auto info = *(InsertHookCmd*)buffer;
NewHook(info.hp, info.name, 0);
}
break;
case HOST_COMMAND_REMOVE_HOOK:
{
auto info = *(RemoveHookCmd*)buffer;
RemoveHook(info.address);
}
break;
case HOST_COMMAND_DETACH:
{
::running = false;
}
break;
}
CloseHandle(hostPipe);
CloseHandle(::hookPipe);
}
FreeLibraryAndExitThread(GetModuleHandleW(ITH_DLL), 0);
return (DWORD)0;
}, nullptr, 0, nullptr);
}
void ConsoleOutput(LPCSTR text)
{
auto info = ConsoleOutputNotif(text);
WriteFile(::hookPipe, &info, strlen(text) + sizeof(info), DUMMY, nullptr);
}
void NotifyHookRemove(uint64_t addr)
{
auto info = HookRemovedNotif(addr);
WriteFile(::hookPipe, &info, sizeof(info), DUMMY, nullptr);
}
// EOF

View File

@ -1,8 +0,0 @@
#pragma once
#include "common.h"
#include "types.h"
void CreatePipe();
void NotifyHookRemove(uint64_t addr);
void ConsoleOutput(LPCSTR text); // jichi 12/25/2013: Used to return length of sent text

View File

@ -9,17 +9,22 @@
//# pragma warning (disable:4733) // C4733: Inline asm assigning to 'FS:0' : handler not registered as safe handler //# pragma warning (disable:4733) // C4733: Inline asm assigning to 'FS:0' : handler not registered as safe handler
#endif // _MSC_VER #endif // _MSC_VER
#include "hijack/texthook.h" #include "texthook.h"
#include "MinHook.h" #include "MinHook.h"
#include "engine/match.h" #include "engine/match.h"
#include "main.h" #include "main.h"
#include "pipe.h"
#include "const.h" #include "const.h"
#include "ithsys/ithsys.h" #include "ithsys/ithsys.h"
#include "growl.h" #include "growl.h"
#include <Psapi.h> #include <Psapi.h>
TextHook *hookman; extern std::unique_ptr<WinMutex> sectionMutex;
bool trigger = 0;
void SetTrigger()
{
trigger = true;
}
// - Unnamed helpers - // - Unnamed helpers -
@ -125,8 +130,8 @@ void TextHook::Send(DWORD dwDataBase)
* @param stack address of current stack - 4 * @param stack address of current stack - 4
* @return If success, which is reverted * @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));
// jichi 10/24/2014: generic hook function // jichi 10/24/2014: generic hook function
if (hp.hook_fun && !hp.hook_fun(dwDataBase, &hp)) if (hp.hook_fun && !hp.hook_fun(dwDataBase, &hp))
@ -168,25 +173,18 @@ void TextHook::Send(DWORD dwDataBase)
dwDataIn = _byteswap_ushort(dwDataIn & 0xffff); dwDataIn = _byteswap_ushort(dwDataIn & 0xffff);
if (dwCount == 1) if (dwCount == 1)
dwDataIn &= 0xff; dwDataIn &= 0xff;
*(WORD *)(pbData + sizeof(ThreadParam)) = dwDataIn & 0xffff; *(WORD*)pbData = dwDataIn & 0xffff;
} }
else else
::memcpy(pbData + sizeof(ThreadParam), (void *)dwDataIn, dwCount); ::memcpy(pbData, (void*)dwDataIn, dwCount);
// jichi 10/14/2014: Add filter function // jichi 10/14/2014: Add filter function
if (hp.filter_fun && !hp.filter_fun(pbData + sizeof(ThreadParam), &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))
dwRetn = 0; dwRetn = 0;
*(ThreadParam*)pbData = { GetCurrentProcessId(), dwAddr, dwRetn, dwSplit }; TextOutput({ GetCurrentProcessId(), dwAddr, dwRetn, dwSplit }, pbData, dwCount);
if (dwCount) {
DWORD unused;
//CliLockPipe();
WriteFile(::hookPipe, pbData, dwCount + sizeof(ThreadParam), &unused, nullptr);
//CliUnlockPipe();
}
} }
__except (EXCEPTION_EXECUTE_HANDLER) __except (EXCEPTION_EXECUTE_HANDLER)
{ {
@ -205,9 +203,9 @@ bool TextHook::InsertHookCode()
else if (HMODULE moduleBase = GetModuleHandleW(hp.module)) hp.insertion_address += (uint64_t)moduleBase; else if (HMODULE moduleBase = GetModuleHandleW(hp.module)) hp.insertion_address += (uint64_t)moduleBase;
else return ConsoleOutput("Textractor: InsertHookCode FAILED: module not present"), false; else return ConsoleOutput("Textractor: InsertHookCode FAILED: module not present"), false;
BYTE* original; void* original;
insert: insert:
if (MH_STATUS err = MH_CreateHook((void*)hp.insertion_address, (void*)trampoline, (void**)&original)) if (MH_STATUS err = MH_CreateHook((void*)hp.insertion_address, (void*)trampoline, &original))
if (err == MH_ERROR_ALREADY_CREATED) if (err == MH_ERROR_ALREADY_CREATED)
{ {
RemoveHook(hp.insertion_address); RemoveHook(hp.insertion_address);
@ -222,7 +220,7 @@ insert:
*(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;
*(BYTE**)(common_hook + 24) = original; *(void**)(common_hook + 24) = original;
memcpy(trampoline, common_hook, sizeof(common_hook)); memcpy(trampoline, common_hook, sizeof(common_hook));
//BYTE* original; //BYTE* original;
@ -240,7 +238,7 @@ insert:
} }
#endif // _WIN32 #endif // _WIN32
DWORD WINAPI ReaderThread(LPVOID hookPtr) DWORD WINAPI Reader(LPVOID hookPtr)
{ {
TextHook* hook = (TextHook*)hookPtr; TextHook* hook = (TextHook*)hookPtr;
BYTE buffer[PIPE_BUFFER_SIZE] = {}; BYTE buffer[PIPE_BUFFER_SIZE] = {};
@ -253,7 +251,7 @@ DWORD WINAPI ReaderThread(LPVOID hookPtr)
{ {
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); Sleep(500);
if (memcmp(buffer + sizeof(ThreadParam), currentAddress, dataLen + 1) == 0) if (memcmp(buffer, currentAddress, dataLen + 1) == 0)
{ {
changeCount = 0; changeCount = 0;
continue; continue;
@ -269,15 +267,13 @@ DWORD WINAPI ReaderThread(LPVOID hookPtr)
else else
dataLen = strlen((const char*)currentAddress); dataLen = strlen((const char*)currentAddress);
*(ThreadParam*)buffer = { GetCurrentProcessId(), hook->hp.insertion_address, 0, 0 }; memcpy(buffer, currentAddress, dataLen + 1);
memcpy(buffer + sizeof(ThreadParam), currentAddress, dataLen + 1); TextOutput({ GetCurrentProcessId(), hook->hp.insertion_address, 0, 0 }, buffer, dataLen);
DWORD unused;
WriteFile(::hookPipe, buffer, dataLen + sizeof(ThreadParam), &unused, nullptr);
} }
} }
__except (EXCEPTION_EXECUTE_HANDLER) __except (EXCEPTION_EXECUTE_HANDLER)
{ {
ConsoleOutput("Textractor: ReaderThread ERROR (likely an incorrect R-code)"); ConsoleOutput("Textractor: Reader ERROR (likely an incorrect R-code)");
} }
ConsoleOutput("Textractor: remove read code"); ConsoleOutput("Textractor: remove read code");
hook->ClearHook(); hook->ClearHook();
@ -287,14 +283,14 @@ DWORD WINAPI ReaderThread(LPVOID hookPtr)
bool TextHook::InsertReadCode() bool TextHook::InsertReadCode()
{ {
//RemoveHook(hp.address); // Artikash 8/25/2018: clear existing //RemoveHook(hp.address); // Artikash 8/25/2018: clear existing
readerHandle = CreateThread(nullptr, 0, ReaderThread, this, 0, nullptr); readerHandle = CreateThread(nullptr, 0, Reader, this, 0, nullptr);
return true; return true;
} }
void TextHook::InitHook(const HookParam &h, LPCSTR name, DWORD set_flag) void TextHook::InitHook(HookParam h, LPCSTR name, DWORD set_flag)
{ {
LOCK(*sectionMutex); LOCK(*sectionMutex);
hp = h; this->hp = h;
hp.insertion_address = hp.address; hp.insertion_address = hp.address;
hp.type |= set_flag; hp.type |= set_flag;
strcpy_s<HOOK_NAME_SIZE>(hookName, name); strcpy_s<HOOK_NAME_SIZE>(hookName, name);

View File

@ -10,8 +10,7 @@
#include "common.h" #include "common.h"
#include "types.h" #include "types.h"
extern int currentHook; void SetTrigger();
extern DWORD trigger;
// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor // jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
// interprocedure communication, where constructor/destructor will NOT work. // interprocedure communication, where constructor/destructor will NOT work.
@ -23,6 +22,7 @@ class TextHook
int GetLength(DWORD base, DWORD in); // jichi 12/25/2013: Return 0 if failed int GetLength(DWORD base, DWORD in); // jichi 12/25/2013: Return 0 if failed
void RemoveHookCode(); void RemoveHookCode();
void RemoveReadCode(); void RemoveReadCode();
public: public:
HookParam hp; HookParam hp;
char hookName[HOOK_NAME_SIZE]; char hookName[HOOK_NAME_SIZE];
@ -30,17 +30,11 @@ public:
HANDLE readerHandle; HANDLE readerHandle;
bool InsertHook(); bool InsertHook();
void InitHook(const HookParam &hp, LPCSTR name, DWORD set_flag); void InitHook(HookParam hp, LPCSTR name, DWORD set_flag);
void Send(DWORD dwDataBase); void Send(DWORD dwDataBase);
void ClearHook(); void ClearHook();
}; };
enum { MAX_HOOK = 300 }; enum { MAX_HOOK = 300, HOOK_BUFFER_SIZE = MAX_HOOK * sizeof(TextHook), HOOK_SECTION_SIZE = HOOK_BUFFER_SIZE * 2 };
enum { HOOK_SECTION_SIZE = MAX_HOOK * sizeof(TextHook) * 2, HOOK_BUFFER_SIZE = MAX_HOOK * sizeof(TextHook) };
extern TextHook *hookman;
extern bool running;
extern HANDLE hookPipe;
extern std::unique_ptr<WinMutex> sectionMutex;
// EOF // EOF