From 552f76b43e986531b454386fa52f042193e96746 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <1173718158@qq.com>
Date: Thu, 31 Oct 2024 13:54:24 +0800
Subject: [PATCH] cef
---
LunaHook/engine32/cef.cpp | 222 ++++++++++++++++++++++----------------
1 file changed, 129 insertions(+), 93 deletions(-)
diff --git a/LunaHook/engine32/cef.cpp b/LunaHook/engine32/cef.cpp
index a6c8038..eb59fff 100644
--- a/LunaHook/engine32/cef.cpp
+++ b/LunaHook/engine32/cef.cpp
@@ -1,118 +1,130 @@
-#include"cef.h"
+#include "cef.h"
typedef wchar_t char16;
-typedef struct _cef_string_wide_t {
- wchar_t* str;
+typedef struct _cef_string_wide_t
+{
+ wchar_t *str;
size_t length;
- void (*dtor)(wchar_t* str);
+ void (*dtor)(wchar_t *str);
} cef_string_wide_t;
-typedef struct _cef_string_utf8_t {
- char* str;
+typedef struct _cef_string_utf8_t
+{
+ char *str;
size_t length;
- void (*dtor)(char* str);
+ void (*dtor)(char *str);
} cef_string_utf8_t;
-typedef struct _cef_string_utf16_t {
- char16* str;
+typedef struct _cef_string_utf16_t
+{
+ char16 *str;
size_t length;
- void (*dtor)(char16* str);
+ 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)
+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]) {
+ 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;
+ s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
- if (hp->type & USING_SPLIT) *split = s;
+ 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)
+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]) {
+ 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;
+ s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
- if (hp->type & USING_SPLIT) *split = s;
+ 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)
+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]) {
+ 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;
+ s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
- if (hp->type & USING_SPLIT) *split = s;
+ if (hp->type & USING_SPLIT)
+ *split = s;
}
}
bool InsertlibcefHook(HMODULE module)
{
- if (!module)return false;
+ 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
+ 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
- };
+ 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_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_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_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;
+ {"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.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);
+ ret |= NewHook(hp, func.functionName);
}
}
@@ -120,65 +132,89 @@ bool InsertlibcefHook(HMODULE module)
ConsoleOutput("libcef: failed to find function address");
return ret;
}
-bool libcefhook(HMODULE module) {
- //https://vndb.org/v12297
- //魔降ル夜ノ凜 Animation ダウンロード版
+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 ダウンロード版
- if (module == 0)return false;
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
- ConsoleOutput("check v8libcefhook %p %p", minAddress,maxAddress);
+ 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,
+ 0xff, 0xd6,
+ 0x83, 0xc4, 0x10,
+ 0x8b, 0x4d, XX,
+ 0x89, 0xc6,
+ 0x31, 0xe9,
+ 0xe8, XX4,
+ 0x89, 0xF0,
+ 0x83, 0xC4, 0x18,
0x5e,
0x5f,
0x5d,
0xc3
};
- auto addr = reverseFindBytes(bytes, sizeof(bytes), minAddress, maxAddress);
+ // 対魔忍ユキカゼ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
- HookParam hp;
- hp.address = addr+6;
- 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;
- }
- }
- strReplace(s,L"
",L"\n");
- static std::wstring last;
- if(s==last)return false;
- last=s;
- return write_string_overwrite(data,size,s);
};
- hp.type = USING_STRING | CODEC_UTF16|NO_CONTEXT;
- ConsoleOutput("v8libcefhook %p", addr);
-
- return NewHook(hp, "v8libcefhook");
-
+ 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"
";
+ 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(){
+bool cef::attach_function()
+{
auto hm = GetModuleHandleW(L"libcef.dll");
-
- //InsertlibcefHook(hm);
-
+
+ if (!hm)
+ return false;
+ // InsertlibcefHook(hm);
+
return libcefhook(hm);
}
\ No newline at end of file