multiple mono hooks and fix crash

This commit is contained in:
Akash Mozumdar 2020-03-17 13:53:46 -06:00
parent d1d453f359
commit bc01179626
7 changed files with 35 additions and 47 deletions

View File

@ -2244,7 +2244,6 @@ 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;
SetTrigger();
} }
namespace { // unnamed namespace { // unnamed
@ -5804,7 +5803,6 @@ bool InsertShinaHook()
{ {
int ver = GetShinaRioVersion(); int ver = GetShinaRioVersion();
if (ver >= 50) { if (ver >= 50) {
SetTrigger();
//trigger_fun = StackSearchingTrigger<GetGlyphOutlineA, NULL>; //trigger_fun = StackSearchingTrigger<GetGlyphOutlineA, NULL>;
trigger_fun = [](LPVOID funcAddr, DWORD, DWORD stack) trigger_fun = [](LPVOID funcAddr, DWORD, DWORD stack)
{ {
@ -6003,7 +6001,6 @@ void InsertWaffleHook()
} }
//ConsoleOutput("Probably Waffle. Wait for text."); //ConsoleOutput("Probably Waffle. Wait for text.");
trigger_fun = InsertWaffleDynamicHook; trigger_fun = InsertWaffleDynamicHook;
SetTrigger();
//ConsoleOutput("vnreng:WAFFLE: failed"); //ConsoleOutput("vnreng:WAFFLE: failed");
} }
@ -8595,7 +8592,6 @@ 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;
SetTrigger();
return true; return true;
} }
@ -8882,7 +8878,6 @@ void InsertIronGameSystemHook()
{ {
//ConsoleOutput("Probably IronGameSystem. Wait for text."); //ConsoleOutput("Probably IronGameSystem. Wait for text.");
trigger_fun = InsertIGSDynamicHook; trigger_fun = InsertIGSDynamicHook;
SetTrigger();
ConsoleOutput("vnreng: TRIGGER IronGameSystem"); ConsoleOutput("vnreng: TRIGGER IronGameSystem");
} }
@ -9519,7 +9514,6 @@ void InsertRyokuchaHook()
{ {
//ConsoleOutput("Probably Ryokucha. Wait for text."); //ConsoleOutput("Probably Ryokucha. Wait for text.");
trigger_fun = InsertRyokuchaDynamicHook; trigger_fun = InsertRyokuchaDynamicHook;
SetTrigger();
ConsoleOutput("vnreng: TRIGGER Ryokucha"); ConsoleOutput("vnreng: TRIGGER Ryokucha");
} }
@ -16719,7 +16713,7 @@ void InsertMonoHook(HMODULE h)
if (!getDomain || !getName || !getJitInfo) goto failed; if (!getDomain || !getName || !getJitInfo) goto failed;
static auto domain = getDomain(); static auto domain = getDomain();
if (!domain) goto failed; if (!domain) goto failed;
ConsoleOutput("Textractor: Mono Dynamic ENTER (hook = %s)", loadedConfig ? loadedConfig : "brute force"); ConsoleOutput("Textractor: Mono Dynamic ENTER (hooks = %s)", loadedConfig ? loadedConfig : "brute force");
const BYTE prolog[] = { 0x55, 0x8b, 0xec }; const BYTE prolog[] = { 0x55, 0x8b, 0xec };
for (auto addr : Util::SearchMemory(prolog, sizeof(prolog), PAGE_EXECUTE_READWRITE)) for (auto addr : Util::SearchMemory(prolog, sizeof(prolog), PAGE_EXECUTE_READWRITE))
{ {
@ -16729,7 +16723,7 @@ void InsertMonoHook(HMODULE h)
{ {
if (getJitInfo(domain, addr)) if (getJitInfo(domain, addr))
if (char* name = getName(addr)) if (char* name = getName(addr))
if ((!loadedConfig && strstr(name, "string:") && !strstr(name, "string:mem")) || (loadedConfig && strstr(name, loadedConfig))) if (ShouldMonoHook(name))
{ {
HookParam hp = {}; HookParam hp = {};
hp.address = addr; hp.address = addr;
@ -16758,7 +16752,6 @@ void InsertMonoHook(HMODULE h)
ConsoleOutput("Textractor: Mono Dynamic failed"); ConsoleOutput("Textractor: Mono Dynamic failed");
return true; return true;
}; };
SetTrigger();
} }
/** jichi 12/26/2014 Mono /** jichi 12/26/2014 Mono

View File

@ -16,15 +16,6 @@ extern wchar_t *processName, // cached
processPath[MAX_PATH]; // cached processPath[MAX_PATH]; // cached
inline const char *requestedEngine = nullptr, *loadedConfig = nullptr; inline const char *requestedEngine = nullptr, *loadedConfig = nullptr;
// Artikash 6/17/2019 TODO: These have the wrong values on x64
/** jichi 12/24/2014
* @param addr function address
* @param frame real address of the function, supposed to be the same as addr
* @param stack address of current stack - 4
* @return If success, which is reverted
*/
inline bool (*trigger_fun)(LPVOID addr, DWORD frame, DWORD stack);
bool InsertMonoHooks(); // Mono bool InsertMonoHooks(); // Mono
// Wii engines // Wii engines

View File

@ -33,11 +33,6 @@ namespace Engine
return found; return found;
} }
DWORD InsertDynamicHook(LPVOID addr, DWORD frame, DWORD stack)
{
return trigger_fun ? !trigger_fun(addr, frame, stack) : 0;
}
void Hijack() void Hijack()
{ {
static auto _ = [] static auto _ = []
@ -56,6 +51,7 @@ namespace Engine
ConsoleOutput("Textractor: Engine = %s", requestedEngine = configFileData + 7); ConsoleOutput("Textractor: Engine = %s", requestedEngine = configFileData + 7);
} }
else loadedConfig = configFileData; else loadedConfig = configFileData;
if (loadedConfig && !*loadedConfig) loadedConfig = nullptr;
} }
processStartAddress = processStopAddress = (uintptr_t)GetModuleHandleW(nullptr); processStartAddress = processStopAddress = (uintptr_t)GetModuleHandleW(nullptr);
@ -74,4 +70,15 @@ namespace Engine
return NULL; return NULL;
}(); }();
} }
bool ShouldMonoHook(const char* name)
{
if (!loadedConfig) return strstr(name, "string:") && !strstr(name, "string:mem");
for (const char* hook = loadedConfig; hook; hook = strchr(hook + 1, '\t'))
for (auto start = name; *start; ++start)
for (int i = 0; ; ++i)
if (start[i] != hook[i + 1]) break;
else if (!hook[i + 2] || hook[i + 2] == '\t') return true;
return false;
}
} }

View File

@ -13,10 +13,8 @@ namespace Engine {
// jichi 10/21/2014: Return whether found the engine // jichi 10/21/2014: Return whether found the engine
void Hijack(); void Hijack();
void terminate();
// jichi 10/21/2014: Return 0 if failed bool ShouldMonoHook(const char* name);
DWORD InsertDynamicHook(LPVOID addr, DWORD frame, DWORD stack);
} // namespace Engine } // namespace Engine

View File

@ -80,7 +80,7 @@ namespace Engine
if (!getDomain || !getName || !getJitInfo) goto failed; if (!getDomain || !getName || !getJitInfo) goto failed;
static auto domain = getDomain(); static auto domain = getDomain();
if (!domain) goto failed; if (!domain) goto failed;
ConsoleOutput("Textractor: Mono Dynamic ENTER (hook = %s)", loadedConfig ? loadedConfig : "brute force"); ConsoleOutput("Textractor: Mono Dynamic ENTER (hooks = %s)", loadedConfig ? loadedConfig : "brute force");
const BYTE prolog1[] = { 0x55, 0x48, 0x8b, 0xec }; const BYTE prolog1[] = { 0x55, 0x48, 0x8b, 0xec };
const BYTE prolog2[] = { 0x48, 0x83, 0xec }; const BYTE prolog2[] = { 0x48, 0x83, 0xec };
for (auto [prolog, size] : Array<const BYTE*, size_t>{ { prolog1, sizeof(prolog1) }, { prolog2, sizeof(prolog2) } }) for (auto [prolog, size] : Array<const BYTE*, size_t>{ { prolog1, sizeof(prolog1) }, { prolog2, sizeof(prolog2) } })
@ -92,8 +92,7 @@ namespace Engine
{ {
if (getJitInfo(domain, addr)) if (getJitInfo(domain, addr))
if (char* name = getName(addr)) if (char* name = getName(addr))
if ((!loadedConfig && strstr(name, "string:") && strstr(name, "+ 0x0") && !strstr(name, "string:mem")) || if (strstr(name, "0x0") && ShouldMonoHook(name))
loadedConfig && strstr(name, loadedConfig) && strstr(name, "+ 0x0"))
{ {
HookParam hp = {}; HookParam hp = {};
hp.address = addr; hp.address = addr;
@ -126,7 +125,6 @@ namespace Engine
ConsoleOutput("Textractor: Mono Dynamic failed"); ConsoleOutput("Textractor: Mono Dynamic failed");
return true; return true;
}; };
SetTrigger();
return ret; return ret;
} }

View File

@ -5,7 +5,6 @@
#include "texthook.h" #include "texthook.h"
#include "main.h" #include "main.h"
#include "engine/match.h"
#include "ithsys/ithsys.h" #include "ithsys/ithsys.h"
extern const char* FUNC_MISSING; extern const char* FUNC_MISSING;
@ -93,27 +92,22 @@ namespace { // unnamed
int this_offset = 50, send_offset = 60, original_offset = 126; int this_offset = 50, send_offset = 60, original_offset = 126;
#endif #endif
bool trigger = false;
enum { TEXT_BUFFER_SIZE = PIPE_BUFFER_SIZE - sizeof(ThreadParam) }; enum { TEXT_BUFFER_SIZE = PIPE_BUFFER_SIZE - sizeof(ThreadParam) };
} // unnamed namespace } // unnamed namespace
void SetTrigger()
{
trigger = true;
}
// - TextHook methods - // - TextHook methods -
bool TextHook::Insert(HookParam hp, DWORD set_flag) bool TextHook::Insert(HookParam hp, 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; address = hp.address;
}
if (hp.type & DIRECT_READ) return InsertReadCode(); if (hp.type & DIRECT_READ) return InsertReadCode();
else return InsertHookCode(); return InsertHookCode();
} }
// jichi 5/11/2014: // jichi 5/11/2014:
@ -123,7 +117,8 @@ void TextHook::Send(uintptr_t dwDataBase)
_InterlockedIncrement(&useCount); _InterlockedIncrement(&useCount);
__try __try
{ {
if (trigger) trigger = Engine::InsertDynamicHook(location, *(DWORD *)(dwDataBase - 0x1c), *(DWORD *)(dwDataBase - 0x18)); if (auto current_trigger_fun = trigger_fun.exchange(nullptr))
if (!current_trigger_fun(location, *(DWORD*)(dwDataBase - 0x1c), *(DWORD*)(dwDataBase - 0x18))) trigger_fun = current_trigger_fun;
#ifndef _WIN64 #ifndef _WIN64
DWORD dwCount = 0, DWORD dwCount = 0,
@ -131,7 +126,6 @@ void TextHook::Send(uintptr_t dwDataBase)
dwDataIn = *(DWORD*)(dwDataBase + hp.offset), // default values dwDataIn = *(DWORD*)(dwDataBase + hp.offset), // default values
dwRetn = *(DWORD*)dwDataBase; // first value on stack (if hooked start of function, this is return address) dwRetn = *(DWORD*)dwDataBase; // first value on stack (if hooked start of function, this is return address)
// jichi 10/24/2014: generic hook function // jichi 10/24/2014: generic hook function
if (hp.hook_fun && !hp.hook_fun(dwDataBase, &hp)) hp.hook_fun = nullptr; if (hp.hook_fun && !hp.hook_fun(dwDataBase, &hp)) hp.hook_fun = nullptr;

View File

@ -10,7 +10,14 @@
#include "common.h" #include "common.h"
#include "types.h" #include "types.h"
void SetTrigger(); // Artikash 6/17/2019 TODO: These have the wrong values on x64
/** jichi 12/24/2014
* @param addr function address
* @param frame real address of the function, supposed to be the same as addr
* @param stack address of current stack - 4
* @return If success, which is reverted
*/
inline std::atomic<bool (*)(LPVOID addr, DWORD frame, DWORD stack)> trigger_fun = nullptr;
// 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.