2024-10-31 13:54:24 +08:00
|
|
|
|
#include "cef.h"
|
2024-02-07 20:59:24 +08:00
|
|
|
|
typedef wchar_t char16;
|
|
|
|
|
|
2024-10-31 13:54:24 +08:00
|
|
|
|
typedef struct _cef_string_wide_t
|
|
|
|
|
{
|
|
|
|
|
wchar_t *str;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
size_t length;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
void (*dtor)(wchar_t *str);
|
2024-02-07 20:59:24 +08:00
|
|
|
|
} cef_string_wide_t;
|
|
|
|
|
|
2024-10-31 13:54:24 +08:00
|
|
|
|
typedef struct _cef_string_utf8_t
|
|
|
|
|
{
|
|
|
|
|
char *str;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
size_t length;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
void (*dtor)(char *str);
|
2024-02-07 20:59:24 +08:00
|
|
|
|
} cef_string_utf8_t;
|
|
|
|
|
|
2024-10-31 13:54:24 +08:00
|
|
|
|
typedef struct _cef_string_utf16_t
|
|
|
|
|
{
|
|
|
|
|
char16 *str;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
size_t length;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
void (*dtor)(char16 *str);
|
2024-02-07 20:59:24 +08:00
|
|
|
|
} cef_string_utf16_t;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
static void hook_cef_string_utf16_t(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
2024-02-07 20:59:24 +08:00
|
|
|
|
{
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (auto p = (_cef_string_utf16_t *)stack->stack[1])
|
|
|
|
|
{
|
2024-02-07 20:59:24 +08:00
|
|
|
|
*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)))
|
2024-10-31 13:54:24 +08:00
|
|
|
|
s = *(DWORD *)s;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
if (!s)
|
|
|
|
|
s = hp->address;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (hp->type & USING_SPLIT)
|
|
|
|
|
*split = s;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-31 13:54:24 +08:00
|
|
|
|
static void hook_cef_string_wide_t(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
2024-02-07 20:59:24 +08:00
|
|
|
|
{
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (auto p = (_cef_string_wide_t *)stack->stack[1])
|
|
|
|
|
{
|
2024-02-07 20:59:24 +08:00
|
|
|
|
*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)))
|
2024-10-31 13:54:24 +08:00
|
|
|
|
s = *(DWORD *)s;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
if (!s)
|
|
|
|
|
s = hp->address;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (hp->type & USING_SPLIT)
|
|
|
|
|
*split = s;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-31 13:54:24 +08:00
|
|
|
|
static void hook_cef_string_utf8_t(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
2024-02-07 20:59:24 +08:00
|
|
|
|
{
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (auto p = (_cef_string_utf8_t *)stack->stack[1])
|
|
|
|
|
{
|
2024-02-07 20:59:24 +08:00
|
|
|
|
*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)))
|
2024-10-31 13:54:24 +08:00
|
|
|
|
s = *(DWORD *)s;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
if (!s)
|
|
|
|
|
s = hp->address;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (hp->type & USING_SPLIT)
|
|
|
|
|
*split = s;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool InsertlibcefHook(HMODULE module)
|
|
|
|
|
{
|
2024-10-31 13:54:24 +08:00
|
|
|
|
if (!module)
|
|
|
|
|
return false;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
bool ret = false;
|
|
|
|
|
|
2024-10-31 13:54:24 +08:00
|
|
|
|
struct libcefFunction
|
|
|
|
|
{ // argument indices start from 0 for SpecialHookMonoString, otherwise 1
|
|
|
|
|
const char *functionName;
|
|
|
|
|
size_t textIndex; // argument index
|
|
|
|
|
short lengthIndex; // argument index
|
2024-02-07 20:59:24 +08:00
|
|
|
|
unsigned long hookType; // HookParam type
|
2024-10-31 13:54:24 +08:00
|
|
|
|
void *text_fun; // HookParam::text_fun_t
|
|
|
|
|
};
|
2024-02-07 20:59:24 +08:00
|
|
|
|
|
|
|
|
|
HookParam hp;
|
|
|
|
|
const libcefFunction funcs[] = {
|
2024-10-31 13:54:24 +08:00
|
|
|
|
{"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;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
hp.address = (DWORD)addr;
|
2024-10-31 13:54:24 +08:00
|
|
|
|
hp.type = func.hookType;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
hp.offset = func.textIndex * 4;
|
|
|
|
|
hp.length_offset = func.lengthIndex * 4;
|
|
|
|
|
hp.text_fun = (decltype(hp.text_fun))func.text_fun;
|
|
|
|
|
ConsoleOutput("libcef: INSERT");
|
2024-10-31 13:54:24 +08:00
|
|
|
|
ret |= NewHook(hp, func.functionName);
|
2024-02-07 20:59:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ret)
|
|
|
|
|
ConsoleOutput("libcef: failed to find function address");
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2024-10-31 13:54:24 +08:00
|
|
|
|
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 ダウンロード版
|
2024-05-07 01:06:35 +08:00
|
|
|
|
|
2024-02-07 20:59:24 +08:00
|
|
|
|
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
|
2024-10-31 13:54:24 +08:00
|
|
|
|
ConsoleOutput("check v8libcefhook %p %p", minAddress, maxAddress);
|
2024-02-07 20:59:24 +08:00
|
|
|
|
const BYTE bytes[] = {
|
2024-05-07 01:06:35 +08:00
|
|
|
|
0x50,
|
|
|
|
|
0x51,
|
|
|
|
|
0x52,
|
|
|
|
|
0x57,
|
2024-10-31 13:54:24 +08:00
|
|
|
|
0xff, 0xd6,
|
|
|
|
|
0x83, 0xc4, 0x10,
|
|
|
|
|
0x8b, 0x4d, XX,
|
|
|
|
|
0x89, 0xc6,
|
|
|
|
|
0x31, 0xe9,
|
|
|
|
|
0xe8, XX4,
|
|
|
|
|
0x89, 0xF0,
|
|
|
|
|
0x83, 0xC4, 0x18,
|
2024-05-07 01:06:35 +08:00
|
|
|
|
0x5e,
|
|
|
|
|
0x5f,
|
|
|
|
|
0x5d,
|
|
|
|
|
0xc3
|
2024-02-07 20:59:24 +08:00
|
|
|
|
|
|
|
|
|
};
|
2024-10-31 13:54:24 +08:00
|
|
|
|
// 対魔忍ユキカゼ2Animation
|
|
|
|
|
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
|
2024-02-07 20:59:24 +08:00
|
|
|
|
|
2024-10-31 13:54:24 +08:00
|
|
|
|
};
|
|
|
|
|
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;
|
2024-02-07 20:59:24 +08:00
|
|
|
|
}
|
2024-10-31 13:54:24 +08:00
|
|
|
|
bool cef::attach_function()
|
|
|
|
|
{
|
2024-02-07 20:59:24 +08:00
|
|
|
|
auto hm = GetModuleHandleW(L"libcef.dll");
|
2024-10-31 13:54:24 +08:00
|
|
|
|
|
|
|
|
|
if (!hm)
|
|
|
|
|
return false;
|
|
|
|
|
// InsertlibcefHook(hm);
|
|
|
|
|
|
2024-02-07 20:59:24 +08:00
|
|
|
|
return libcefhook(hm);
|
|
|
|
|
}
|