mirror of
https://github.com/Artikash/Textractor.git
synced 2024-12-23 08:54:12 +08:00
refactor. less global variables
This commit is contained in:
parent
f351148b3d
commit
d0f48a67a4
@ -5,7 +5,7 @@
|
||||
#include "host.h"
|
||||
#include "const.h"
|
||||
#include "defs.h"
|
||||
#include "../vnrhook/hijack/texthook.h"
|
||||
#include "../vnrhook/texthook.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -51,7 +51,7 @@ namespace
|
||||
|
||||
std::recursive_mutex hostMutex;
|
||||
|
||||
DWORD DUMMY[1];
|
||||
DWORD DUMMY;
|
||||
ThreadParam CONSOLE{ 0, -1ULL, -1ULL, -1ULL }, CLIPBOARD{ 0, 0, -1ULL, -1ULL };
|
||||
|
||||
void DispatchText(ThreadParam tp, const BYTE* text, int len)
|
||||
@ -111,7 +111,7 @@ namespace
|
||||
CreatePipe();
|
||||
|
||||
while (ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr))
|
||||
switch (*(int*)buffer)
|
||||
switch (*(HostNotificationType*)buffer)
|
||||
{
|
||||
case HOST_NOTIFICATION_RMVHOOK:
|
||||
{
|
||||
@ -242,22 +242,22 @@ namespace Host
|
||||
void DetachProcess(DWORD processId)
|
||||
{
|
||||
LOCK(hostMutex);
|
||||
auto command = HOST_COMMAND_DETACH;
|
||||
WriteFile(processRecordsByIds.at(processId)->hostPipe, &command, sizeof(command), DUMMY, nullptr);
|
||||
HostCommandType buffer(HOST_COMMAND_DETACH);
|
||||
WriteFile(processRecordsByIds.at(processId)->hostPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
|
||||
}
|
||||
|
||||
void InsertHook(DWORD processId, HookParam hp, std::string name)
|
||||
{
|
||||
LOCK(hostMutex);
|
||||
auto command = InsertHookCmd(hp, name);
|
||||
WriteFile(processRecordsByIds.at(processId)->hostPipe, &command, sizeof(command), DUMMY, nullptr);
|
||||
InsertHookCmd buffer(hp, name);
|
||||
WriteFile(processRecordsByIds.at(processId)->hostPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
|
||||
}
|
||||
|
||||
void RemoveHook(DWORD processId, uint64_t addr)
|
||||
{
|
||||
LOCK(hostMutex);
|
||||
auto command = RemoveHookCmd(addr);
|
||||
WriteFile(processRecordsByIds.at(processId)->hostPipe, &command, sizeof(command), DUMMY, nullptr);
|
||||
RemoveHookCmd buffer(addr);
|
||||
WriteFile(processRecordsByIds.at(processId)->hostPipe, &buffer, sizeof(buffer), &DUMMY, nullptr);
|
||||
}
|
||||
|
||||
HookParam GetHookParam(DWORD processId, uint64_t addr)
|
||||
|
@ -3,18 +3,16 @@ include_directories(. util)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(vnrhook_src
|
||||
main.cc
|
||||
pipe.cc
|
||||
texthook.cc
|
||||
util/ithsys/ithsys.cc
|
||||
hijack/texthook.cc
|
||||
)
|
||||
else()
|
||||
set(vnrhook_src
|
||||
main.cc
|
||||
pipe.cc
|
||||
texthook.cc
|
||||
engine/engine.cc
|
||||
engine/match.cc
|
||||
engine/native/pchooks.cc
|
||||
hijack/texthook.cc
|
||||
util/util.cc
|
||||
util/ithsys/ithsys.cc
|
||||
util/disasm/disasm.cc
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "engine/match.h"
|
||||
#include "util/util.h"
|
||||
#include "main.h"
|
||||
#include "texthook.h"
|
||||
#include "engine/mono/funcinfo.h"
|
||||
#include "engine/ppsspp/funcinfo.h"
|
||||
#include "ithsys/ithsys.h"
|
||||
@ -2232,7 +2233,7 @@ void InsertRealliveHook()
|
||||
//ConsoleOutput("Probably Reallive. Wait for text.");
|
||||
ConsoleOutput("vnreng: TRIGGER Reallive");
|
||||
trigger_fun_ = InsertRealliveDynamicHook;
|
||||
SwitchTrigger(true);
|
||||
SetTrigger();
|
||||
}
|
||||
|
||||
namespace { // unnamed
|
||||
@ -5766,7 +5767,8 @@ int GetShinaRioVersion()
|
||||
//char *buffer,*version;//,*ptr;
|
||||
enum { BufferSize = 0x40 };
|
||||
char buffer[BufferSize];
|
||||
ReadFile(hFile, buffer, BufferSize, (DWORD*)buffer, nullptr);
|
||||
DWORD DUMMY;
|
||||
ReadFile(hFile, buffer, BufferSize, &DUMMY, nullptr);
|
||||
CloseHandle(hFile);
|
||||
if (buffer[0] == '[') {
|
||||
buffer[0x3f] = 0; // jichi 8/24/2013: prevent strstr from overflow
|
||||
@ -5785,7 +5787,7 @@ bool InsertShinaHook()
|
||||
{
|
||||
int ver = GetShinaRioVersion();
|
||||
if (ver >= 50) {
|
||||
SwitchTrigger(true);
|
||||
SetTrigger();
|
||||
trigger_fun_ = StackSearchingTrigger<GetGlyphOutlineA, NULL>;
|
||||
ConsoleOutput("Textractor: ShinaRio 2.50+: adding trigger");
|
||||
return true;
|
||||
@ -5960,7 +5962,7 @@ void InsertWaffleHook()
|
||||
}
|
||||
//ConsoleOutput("Probably Waffle. Wait for text.");
|
||||
trigger_fun_ = InsertWaffleDynamicHook;
|
||||
SwitchTrigger(true);
|
||||
SetTrigger();
|
||||
//ConsoleOutput("vnreng:WAFFLE: failed");
|
||||
}
|
||||
|
||||
@ -8503,7 +8505,7 @@ bool InsertSystemAoiDynamic()
|
||||
ConsoleOutput("vnreng: DYNAMIC SystemAoi");
|
||||
//ConsoleOutput("Probably SoftHouseChara. Wait for text.");
|
||||
trigger_fun_ = InsertSystemAoiDynamicHook;
|
||||
SwitchTrigger(true);
|
||||
SetTrigger();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8818,7 +8820,7 @@ void InsertIronGameSystemHook()
|
||||
{
|
||||
//ConsoleOutput("Probably IronGameSystem. Wait for text.");
|
||||
trigger_fun_ = InsertIGSDynamicHook;
|
||||
SwitchTrigger(true);
|
||||
SetTrigger();
|
||||
ConsoleOutput("vnreng: TRIGGER IronGameSystem");
|
||||
}
|
||||
|
||||
@ -9454,7 +9456,7 @@ void InsertRyokuchaHook()
|
||||
{
|
||||
//ConsoleOutput("Probably Ryokucha. Wait for text.");
|
||||
trigger_fun_ = InsertRyokuchaDynamicHook;
|
||||
SwitchTrigger(true);
|
||||
SetTrigger();
|
||||
ConsoleOutput("vnreng: TRIGGER Ryokucha");
|
||||
}
|
||||
|
||||
|
133
vnrhook/main.cc
133
vnrhook/main.cc
@ -11,18 +11,107 @@
|
||||
#include "main.h"
|
||||
#include "defs.h"
|
||||
#include "MinHook.h"
|
||||
#include "pipe.h"
|
||||
#include "engine/engine.h"
|
||||
#include "engine/match.h"
|
||||
#include "hijack/texthook.h"
|
||||
#include "texthook.h"
|
||||
#include "util/growl.h"
|
||||
|
||||
HANDLE hSection;
|
||||
HANDLE hSection, hookPipe;
|
||||
TextHook* hooks;
|
||||
bool running;
|
||||
int currentHook = 0, userhookCount = 0;
|
||||
DWORD trigger = 0;
|
||||
DWORD DUMMY;
|
||||
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)
|
||||
{
|
||||
switch (fdwReason)
|
||||
@ -35,23 +124,22 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
||||
|
||||
// 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());
|
||||
::hookman = (TextHook*)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
|
||||
memset(::hookman, 0, HOOK_BUFFER_SIZE);
|
||||
hooks = (TextHook*)MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, HOOK_BUFFER_SIZE);
|
||||
memset(hooks, 0, HOOK_BUFFER_SIZE);
|
||||
|
||||
MH_Initialize();
|
||||
running = true;
|
||||
|
||||
::running = true;
|
||||
|
||||
CreatePipe();
|
||||
CreateThread(nullptr, 0, Pipe, nullptr, 0, nullptr);
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
::running = false;
|
||||
running = false;
|
||||
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)
|
||||
UnmapViewOfFile(::hookman);
|
||||
UnmapViewOfFile(hooks);
|
||||
CloseHandle(hSection);
|
||||
//} ITH_EXCEPT {}
|
||||
}
|
||||
@ -61,17 +149,17 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID)
|
||||
}
|
||||
|
||||
//extern "C" {
|
||||
void NewHook(const HookParam &hp, LPCSTR lpname, DWORD flag)
|
||||
void NewHook(HookParam hp, LPCSTR lpname, DWORD flag)
|
||||
{
|
||||
std::string name = lpname;
|
||||
if (++currentHook < MAX_HOOK)
|
||||
{
|
||||
if (name[0] == '\0') name = "UserHook" + std::to_string(userhookCount++);
|
||||
ConsoleOutput(("Textractor: try inserting hook: " + name).c_str());
|
||||
if (name.empty()) name = "UserHook" + std::to_string(userhookCount++);
|
||||
ConsoleOutput("Textractor: try inserting hook: " + name);
|
||||
|
||||
// jichi 7/13/2014: This function would raise when too many hooks added
|
||||
::hookman[currentHook].InitHook(hp, name.c_str(), flag);
|
||||
if (::hookman[currentHook].InsertHook()) ConsoleOutput(("Textractor: inserted hook: " + name).c_str());
|
||||
hooks[currentHook].InitHook(hp, name.c_str(), flag);
|
||||
if (hooks[currentHook].InsertHook()) ConsoleOutput("Textractor: inserted hook: " + name);
|
||||
else ConsoleOutput("Textractor:WARNING: failed to insert hook");
|
||||
}
|
||||
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)
|
||||
{
|
||||
for (int i = 0; i < MAX_HOOK; i++)
|
||||
if (abs((long long)(::hookman[i].hp.insertion_address - addr)) < 9)
|
||||
{
|
||||
::hookman[i].ClearHook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchTrigger(DWORD t)
|
||||
{
|
||||
trigger = t;
|
||||
if (abs((long long)(hooks[i].hp.insertion_address - addr)) < 9) return hooks[i].ClearHook();
|
||||
}
|
||||
|
||||
// EOF
|
@ -6,11 +6,12 @@
|
||||
|
||||
#include "common.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 SwitchTrigger(DWORD on);
|
||||
|
||||
#define ITH_RAISE (*(int*)0 = 0) // raise C000005, for debugging only
|
||||
#define ITH_TRY __try
|
||||
|
100
vnrhook/pipe.cc
100
vnrhook/pipe.cc
@ -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
|
@ -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
|
@ -9,17 +9,22 @@
|
||||
//# pragma warning (disable:4733) // C4733: Inline asm assigning to 'FS:0' : handler not registered as safe handler
|
||||
#endif // _MSC_VER
|
||||
|
||||
#include "hijack/texthook.h"
|
||||
#include "texthook.h"
|
||||
#include "MinHook.h"
|
||||
#include "engine/match.h"
|
||||
#include "main.h"
|
||||
#include "pipe.h"
|
||||
#include "const.h"
|
||||
#include "ithsys/ithsys.h"
|
||||
#include "growl.h"
|
||||
#include <Psapi.h>
|
||||
|
||||
TextHook *hookman;
|
||||
extern std::unique_ptr<WinMutex> sectionMutex;
|
||||
|
||||
bool trigger = 0;
|
||||
void SetTrigger()
|
||||
{
|
||||
trigger = true;
|
||||
}
|
||||
|
||||
// - Unnamed helpers -
|
||||
|
||||
@ -125,8 +130,8 @@ void TextHook::Send(DWORD dwDataBase)
|
||||
* @param stack address of current stack - 4
|
||||
* @return If success, which is reverted
|
||||
*/
|
||||
if (::trigger)
|
||||
::trigger = Engine::InsertDynamicHook((LPVOID)dwAddr, *(DWORD *)(dwDataBase - 0x1c), *(DWORD *)(dwDataBase - 0x18));
|
||||
if (trigger)
|
||||
trigger = Engine::InsertDynamicHook((LPVOID)dwAddr, *(DWORD *)(dwDataBase - 0x1c), *(DWORD *)(dwDataBase - 0x18));
|
||||
|
||||
// jichi 10/24/2014: generic hook function
|
||||
if (hp.hook_fun && !hp.hook_fun(dwDataBase, &hp))
|
||||
@ -168,25 +173,18 @@ void TextHook::Send(DWORD dwDataBase)
|
||||
dwDataIn = _byteswap_ushort(dwDataIn & 0xffff);
|
||||
if (dwCount == 1)
|
||||
dwDataIn &= 0xff;
|
||||
*(WORD *)(pbData + sizeof(ThreadParam)) = dwDataIn & 0xffff;
|
||||
*(WORD*)pbData = dwDataIn & 0xffff;
|
||||
}
|
||||
else
|
||||
::memcpy(pbData + sizeof(ThreadParam), (void *)dwDataIn, dwCount);
|
||||
::memcpy(pbData, (void*)dwDataIn, dwCount);
|
||||
|
||||
// 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))
|
||||
dwRetn = 0;
|
||||
|
||||
*(ThreadParam*)pbData = { GetCurrentProcessId(), dwAddr, dwRetn, dwSplit };
|
||||
if (dwCount) {
|
||||
DWORD unused;
|
||||
|
||||
//CliLockPipe();
|
||||
WriteFile(::hookPipe, pbData, dwCount + sizeof(ThreadParam), &unused, nullptr);
|
||||
//CliUnlockPipe();
|
||||
}
|
||||
TextOutput({ GetCurrentProcessId(), dwAddr, dwRetn, dwSplit }, pbData, dwCount);
|
||||
}
|
||||
__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 return ConsoleOutput("Textractor: InsertHookCode FAILED: module not present"), false;
|
||||
|
||||
BYTE* original;
|
||||
void* original;
|
||||
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)
|
||||
{
|
||||
RemoveHook(hp.insertion_address);
|
||||
@ -222,7 +220,7 @@ insert:
|
||||
|
||||
*(TextHook**)(common_hook + 9) = this;
|
||||
*(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));
|
||||
|
||||
//BYTE* original;
|
||||
@ -240,7 +238,7 @@ insert:
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
DWORD WINAPI ReaderThread(LPVOID hookPtr)
|
||||
DWORD WINAPI Reader(LPVOID hookPtr)
|
||||
{
|
||||
TextHook* hook = (TextHook*)hookPtr;
|
||||
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);
|
||||
Sleep(500);
|
||||
if (memcmp(buffer + sizeof(ThreadParam), currentAddress, dataLen + 1) == 0)
|
||||
if (memcmp(buffer, currentAddress, dataLen + 1) == 0)
|
||||
{
|
||||
changeCount = 0;
|
||||
continue;
|
||||
@ -269,15 +267,13 @@ DWORD WINAPI ReaderThread(LPVOID hookPtr)
|
||||
else
|
||||
dataLen = strlen((const char*)currentAddress);
|
||||
|
||||
*(ThreadParam*)buffer = { GetCurrentProcessId(), hook->hp.insertion_address, 0, 0 };
|
||||
memcpy(buffer + sizeof(ThreadParam), currentAddress, dataLen + 1);
|
||||
DWORD unused;
|
||||
WriteFile(::hookPipe, buffer, dataLen + sizeof(ThreadParam), &unused, nullptr);
|
||||
memcpy(buffer, currentAddress, dataLen + 1);
|
||||
TextOutput({ GetCurrentProcessId(), hook->hp.insertion_address, 0, 0 }, buffer, dataLen);
|
||||
}
|
||||
}
|
||||
__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");
|
||||
hook->ClearHook();
|
||||
@ -287,14 +283,14 @@ DWORD WINAPI ReaderThread(LPVOID hookPtr)
|
||||
bool TextHook::InsertReadCode()
|
||||
{
|
||||
//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;
|
||||
}
|
||||
|
||||
void TextHook::InitHook(const HookParam &h, LPCSTR name, DWORD set_flag)
|
||||
void TextHook::InitHook(HookParam h, LPCSTR name, DWORD set_flag)
|
||||
{
|
||||
LOCK(*sectionMutex);
|
||||
hp = h;
|
||||
this->hp = h;
|
||||
hp.insertion_address = hp.address;
|
||||
hp.type |= set_flag;
|
||||
strcpy_s<HOOK_NAME_SIZE>(hookName, name);
|
@ -10,8 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
|
||||
extern int currentHook;
|
||||
extern DWORD trigger;
|
||||
void SetTrigger();
|
||||
|
||||
// jichi 9/25/2013: This class will be used by NtMapViewOfSectionfor
|
||||
// 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
|
||||
void RemoveHookCode();
|
||||
void RemoveReadCode();
|
||||
|
||||
public:
|
||||
HookParam hp;
|
||||
char hookName[HOOK_NAME_SIZE];
|
||||
@ -30,17 +30,11 @@ public:
|
||||
HANDLE readerHandle;
|
||||
|
||||
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 ClearHook();
|
||||
};
|
||||
|
||||
enum { MAX_HOOK = 300 };
|
||||
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;
|
||||
enum { MAX_HOOK = 300, HOOK_BUFFER_SIZE = MAX_HOOK * sizeof(TextHook), HOOK_SECTION_SIZE = HOOK_BUFFER_SIZE * 2 };
|
||||
|
||||
// EOF
|
Loading…
x
Reference in New Issue
Block a user