mirror of
https://github.com/Artikash/Textractor.git
synced 2024-12-23 08:54:12 +08:00
improve x64 mono
This commit is contained in:
parent
8db76f86e0
commit
f7c2641d58
@ -40,12 +40,13 @@ struct HookParam
|
||||
DWORD type; // flags
|
||||
UINT codepage; // text encoding
|
||||
short length_offset; // index of the string length
|
||||
uintptr_t padding; // padding
|
||||
uintptr_t padding; // padding before string
|
||||
DWORD user_value; // 7/20/2014: jichi additional parameters for PSP games
|
||||
|
||||
void(*text_fun)(DWORD stack, HookParam* hp, BYTE obsoleteAlwaysZero, DWORD* data, DWORD* split, DWORD* len);
|
||||
bool(*filter_fun)(void* data, DWORD* len, HookParam* hp, BYTE obsoleteAlwaysZero); // jichi 10/24/2014: Add filter function. Return true if skip the text
|
||||
bool(*hook_fun)(DWORD stack, HookParam* hp); // jichi 10/24/2014: Add generic hook function, return false if stop execution.
|
||||
int(*length_fun)(uintptr_t stack, uintptr_t data); // data after padding added
|
||||
|
||||
char name[HOOK_NAME_SIZE];
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ namespace Engine
|
||||
How to hook Mono/Unity3D:
|
||||
Find all standard function prologs in memory with write/execute permission: these represent possible JIT compiled functions
|
||||
Then use Mono APIs to reflect what these functions are, and hook them if they are string member functions
|
||||
Mono calling convention uses 'this' as first argument on stack
|
||||
Mono calling convention uses 'this' as first argument
|
||||
Must be dynamic hook bootstrapped from other mono api or mono_domain_get won't work
|
||||
*/
|
||||
trigger_fun = [](LPVOID addr, DWORD, DWORD)
|
||||
@ -74,8 +74,10 @@ namespace Engine
|
||||
if (!getDomain || !getName || !getJitInfo) goto failed;
|
||||
static auto domain = getDomain();
|
||||
if (!domain) goto failed;
|
||||
const BYTE prolog[] = { 0x55, 0x48, 0x8b, 0xec };
|
||||
for (auto addr : Util::SearchMemory(prolog, sizeof(prolog), PAGE_EXECUTE_READWRITE))
|
||||
const BYTE prolog1[] = { 0x55, 0x48, 0x8b, 0xec };
|
||||
const BYTE prolog2[] = { 0x48, 0x83, 0xec };
|
||||
for (auto [prolog, size] : Array<std::tuple<const BYTE*, size_t>>{ { prolog1, sizeof(prolog1) }, { prolog2, sizeof(prolog2) } })
|
||||
for (auto addr : Util::SearchMemory(prolog, size, PAGE_EXECUTE_READWRITE))
|
||||
{
|
||||
[](uint64_t addr)
|
||||
{
|
||||
@ -83,13 +85,21 @@ namespace Engine
|
||||
{
|
||||
if (getJitInfo(domain, addr))
|
||||
if (char* name = getName(addr))
|
||||
if (strstr(name, "string:") && !strstr(name, "string:mem"))
|
||||
if (strstr(name, "string:") && strstr(name, "+ 0x0") && !strstr(name, "string:mem"))
|
||||
{
|
||||
HookParam hp = {};
|
||||
hp.address = addr;
|
||||
hp.type = USING_STRING | USING_UNICODE;
|
||||
hp.offset = -0x20;
|
||||
hp.padding = 20;
|
||||
hp.length_fun = [](uintptr_t, uintptr_t data)
|
||||
{
|
||||
/* Artikash 6/18/2019:
|
||||
even though this should get the true length mono uses internally
|
||||
there's still some garbage picked up on https://vndb.org/v20403 demo, don't know why */
|
||||
int len = *(int*)(data - 4);
|
||||
return len > 0 && len < 1000 ? len * 2 : 0;
|
||||
};
|
||||
NewHook(hp, name);
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +298,7 @@ void TextHook::Clear()
|
||||
int TextHook::GetLength(uintptr_t base, uintptr_t in)
|
||||
{
|
||||
int len;
|
||||
if (hp.length_fun) return hp.length_fun(base, in);
|
||||
switch (hp.length_offset) {
|
||||
default: // jichi 12/26/2013: I should not put this default branch to the end
|
||||
len = *((uintptr_t*)base + hp.length_offset);
|
||||
|
Loading…
x
Reference in New Issue
Block a user