LunaHook-mirror/LunaHook/engine32/cef.cpp
恍兮惚兮 552f76b43e cef
2024-10-31 13:54:24 +08:00

220 lines
5.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "cef.h"
typedef wchar_t char16;
typedef struct _cef_string_wide_t
{
wchar_t *str;
size_t length;
void (*dtor)(wchar_t *str);
} cef_string_wide_t;
typedef struct _cef_string_utf8_t
{
char *str;
size_t length;
void (*dtor)(char *str);
} cef_string_utf8_t;
typedef struct _cef_string_utf16_t
{
char16 *str;
size_t length;
void (*dtor)(char16 *str);
} cef_string_utf16_t;
static void hook_cef_string_utf16_t(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
if (auto p = (_cef_string_utf16_t *)stack->stack[1])
{
*data = (DWORD)p->str;
*len = p->length; // for widechar
auto s = stack->ecx;
for (int i = 0; i < 0x10; i++) // traverse pointers until a non-readable address is met
if (s && !::IsBadReadPtr((LPCVOID)s, sizeof(DWORD)))
s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
if (hp->type & USING_SPLIT)
*split = s;
}
}
static void hook_cef_string_wide_t(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
if (auto p = (_cef_string_wide_t *)stack->stack[1])
{
*data = (DWORD)p->str;
*len = p->length; // for widechar
auto s = stack->ecx;
for (int i = 0; i < 0x10; i++) // traverse pointers until a non-readable address is met
if (s && !::IsBadReadPtr((LPCVOID)s, sizeof(DWORD)))
s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
if (hp->type & USING_SPLIT)
*split = s;
}
}
static void hook_cef_string_utf8_t(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
if (auto p = (_cef_string_utf8_t *)stack->stack[1])
{
*data = (DWORD)p->str;
*len = p->length; // for widechar
auto s = stack->ecx;
for (int i = 0; i < 0x10; i++) // traverse pointers until a non-readable address is met
if (s && !::IsBadReadPtr((LPCVOID)s, sizeof(DWORD)))
s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
if (hp->type & USING_SPLIT)
*split = s;
}
}
bool InsertlibcefHook(HMODULE module)
{
if (!module)
return false;
bool ret = false;
struct libcefFunction
{ // argument indices start from 0 for SpecialHookMonoString, otherwise 1
const char *functionName;
size_t textIndex; // argument index
short lengthIndex; // argument index
unsigned long hookType; // HookParam type
void *text_fun; // HookParam::text_fun_t
};
HookParam hp;
const libcefFunction funcs[] = {
{"cef_string_utf8_set", 1, 0, USING_STRING | CODEC_UTF8 | NO_CONTEXT, NULL}, // ok
{"cef_string_utf8_to_utf16", 1, 0, USING_STRING | CODEC_UTF8 | NO_CONTEXT, NULL},
{"cef_string_utf8_to_wide", 1, 0, USING_STRING | CODEC_UTF8 | NO_CONTEXT, NULL}, // ok
{"cef_string_utf8_clear", 0, 0, USING_STRING | CODEC_UTF8 | NO_CONTEXT, hook_cef_string_utf8_t},
{"cef_string_utf16_set", 1, 0, USING_STRING | CODEC_UTF16 | NO_CONTEXT, NULL}, // ok
{"cef_string_utf16_clear", 0, 0, USING_STRING | CODEC_UTF16, hook_cef_string_utf16_t}, // ok
{"cef_string_utf16_to_utf8", 1, 0, USING_STRING | CODEC_UTF16 | NO_CONTEXT, NULL}, // ok
{"cef_string_utf16_to_wide", 1, 0, USING_STRING | CODEC_UTF16 | NO_CONTEXT, NULL},
{"cef_string_ascii_to_utf16", 1, 0, USING_STRING | NO_CONTEXT, NULL},
{"cef_string_ascii_to_wide", 1, 0, USING_STRING | NO_CONTEXT, NULL},
{"cef_string_wide_set", 1, 0, USING_STRING | CODEC_UTF16 | NO_CONTEXT, NULL}, // ok
{"cef_string_wide_to_utf16", 1, 0, USING_STRING | CODEC_UTF16 | NO_CONTEXT, NULL},
{"cef_string_wide_to_utf8", 1, 0, USING_STRING | CODEC_UTF16 | NO_CONTEXT, NULL},
{"cef_string_wide_clear", 0, 0, USING_STRING | CODEC_UTF16, hook_cef_string_wide_t}};
for (auto func : funcs)
{
if (FARPROC addr = ::GetProcAddress(module, func.functionName))
{
if (addr == 0)
continue;
hp.address = (DWORD)addr;
hp.type = func.hookType;
hp.offset = func.textIndex * 4;
hp.length_offset = func.lengthIndex * 4;
hp.text_fun = (decltype(hp.text_fun))func.text_fun;
ConsoleOutput("libcef: INSERT");
ret |= NewHook(hp, func.functionName);
}
}
if (!ret)
ConsoleOutput("libcef: failed to find function address");
return ret;
}
namespace
{
bool ceffileter(void *data, uintptr_t *size, HookParam *hp)
{
auto s = std::wstring((wchar_t *)data, *size / 2);
if (s == *(std::wstring *)(hp->user_value))
return false;
*(std::wstring *)(hp->user_value) = s;
return true;
};
}
bool libcefhook(HMODULE module)
{
// https://vndb.org/v12297
// 魔降ル夜ノ凜 Animation ダウンロード版
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
ConsoleOutput("check v8libcefhook %p %p", minAddress, maxAddress);
const BYTE bytes[] = {
0x50,
0x51,
0x52,
0x57,
0xff, 0xd6,
0x83, 0xc4, 0x10,
0x8b, 0x4d, XX,
0x89, 0xc6,
0x31, 0xe9,
0xe8, XX4,
0x89, 0xF0,
0x83, 0xC4, 0x18,
0x5e,
0x5f,
0x5d,
0xc3
};
// 対魔忍ユキカゼAnimation
const BYTE bytes2[] = {
0x51,
0x57,
0x52,
0x50,
0xff, 0xd6,
0x83, 0xc4, 0x10,
0x8b, 0x4d, XX,
0x89, 0xc6,
0x31, 0xe9,
0xe8, XX4,
0x89, 0xF0,
0x83, 0xC4, 0x18,
0x5e,
0x5f,
0x5b,
0x5d,
0xc3
};
bool succ = false;
for (auto addrs : {Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE_READWRITE, minAddress, maxAddress), Util::SearchMemory(bytes2, sizeof(bytes2), PAGE_EXECUTE_READWRITE, minAddress, maxAddress)})
{
for (auto addr : addrs)
{
HookParam hp;
hp.address = addr + 4;
hp.offset = get_stack(1);
hp.filter_fun = ceffileter;
hp.newlineseperator = L"<br>";
hp.length_offset = 2;
hp.type = USING_STRING | CODEC_UTF16 | NO_CONTEXT;
hp.user_value = (DWORD) new std::wstring;
succ |= NewHook(hp, "libcef");
}
}
return succ;
}
bool cef::attach_function()
{
auto hm = GetModuleHandleW(L"libcef.dll");
if (!hm)
return false;
// InsertlibcefHook(hm);
return libcefhook(hm);
}