LunaHook-mirror/LunaHook/engine32/cef.cpp
2024-02-07 20:59:24 +08:00

177 lines
5.1 KiB
C++

#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;
}
bool libcefhook(HMODULE module) {
if (module == 0)return false;
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
ConsoleOutput("check v8libcefhook %p %p", minAddress,maxAddress);
const BYTE bytes[] = {
0x83,0xc4,0x10,
0x8b,0x4d,XX,
0x89,0xc6,
0x31,0xe9,
0xe8,XX4,
0x89,0xF0,
0x83,0xC4,0x18
};
auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE_READ, minAddress, maxAddress);
ConsoleOutput("v8libcefhook matches %d", addrs.size());
bool succ=false;
for (auto addr : addrs) {
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.filter_fun=[] (void* data, uintptr_t * size, HookParam*) {
std::wstring s = L"";
int i = 0;
for (; i < *size /2; i++) {
auto c = ((LPWSTR)data)[i];
if (c == L'[') {
break;
}
else {
s += c;
}
}
wcscpy((LPWSTR)data, s.c_str());
*size = i * 2;
return true;
};
hp.type = USING_STRING | CODEC_UTF16|NO_CONTEXT;
ConsoleOutput("v8libcefhook %p", addr);
succ|=NewHook(hp, "v8libcefhook");
}
return succ;
}
bool cef::attach_function(){
auto hm = GetModuleHandleW(L"libcef.dll");
//InsertlibcefHook(hm);
return libcefhook(hm);
}