forked from Public-Mirror/Textractor
improve x64 mono
This commit is contained in:
parent
8db76f86e0
commit
f7c2641d58
@ -40,12 +40,13 @@ struct HookParam
|
|||||||
DWORD type; // flags
|
DWORD type; // flags
|
||||||
UINT codepage; // text encoding
|
UINT codepage; // text encoding
|
||||||
short length_offset; // index of the string length
|
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
|
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);
|
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(*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.
|
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];
|
char name[HOOK_NAME_SIZE];
|
||||||
};
|
};
|
||||||
|
@ -63,7 +63,7 @@ namespace Engine
|
|||||||
How to hook Mono/Unity3D:
|
How to hook Mono/Unity3D:
|
||||||
Find all standard function prologs in memory with write/execute permission: these represent possible JIT compiled functions
|
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
|
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
|
Must be dynamic hook bootstrapped from other mono api or mono_domain_get won't work
|
||||||
*/
|
*/
|
||||||
trigger_fun = [](LPVOID addr, DWORD, DWORD)
|
trigger_fun = [](LPVOID addr, DWORD, DWORD)
|
||||||
@ -74,8 +74,10 @@ 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;
|
||||||
const BYTE prolog[] = { 0x55, 0x48, 0x8b, 0xec };
|
const BYTE prolog1[] = { 0x55, 0x48, 0x8b, 0xec };
|
||||||
for (auto addr : Util::SearchMemory(prolog, sizeof(prolog), PAGE_EXECUTE_READWRITE))
|
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)
|
[](uint64_t addr)
|
||||||
{
|
{
|
||||||
@ -83,13 +85,21 @@ namespace Engine
|
|||||||
{
|
{
|
||||||
if (getJitInfo(domain, addr))
|
if (getJitInfo(domain, addr))
|
||||||
if (char* name = getName(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 = {};
|
HookParam hp = {};
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
hp.type = USING_STRING | USING_UNICODE;
|
hp.type = USING_STRING | USING_UNICODE;
|
||||||
hp.offset = -0x20;
|
hp.offset = -0x20;
|
||||||
hp.padding = 20;
|
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);
|
NewHook(hp, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,7 @@ void TextHook::Clear()
|
|||||||
int TextHook::GetLength(uintptr_t base, uintptr_t in)
|
int TextHook::GetLength(uintptr_t base, uintptr_t in)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
if (hp.length_fun) return hp.length_fun(base, in);
|
||||||
switch (hp.length_offset) {
|
switch (hp.length_offset) {
|
||||||
default: // jichi 12/26/2013: I should not put this default branch to the end
|
default: // jichi 12/26/2013: I should not put this default branch to the end
|
||||||
len = *((uintptr_t*)base + hp.length_offset);
|
len = *((uintptr_t*)base + hp.length_offset);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user