mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-27 15:44:12 +08:00
.
This commit is contained in:
parent
239b8231f3
commit
9be975e15f
@ -855,35 +855,19 @@ static bool InsertSystem43NewHook(ULONG startAddress, ULONG stopAddress, LPCSTR
|
||||
0x51, // 004eeb43 51 push ecx
|
||||
0xe8 //, XX4, // 004eeb44 e8 42dc1900 call .0068c78b
|
||||
};
|
||||
enum
|
||||
{
|
||||
addr_offset = 0
|
||||
};
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||
// GROWL_DWORD(addr);
|
||||
if (!addr)
|
||||
{
|
||||
ConsoleOutput("System43+: pattern not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// addr = *(DWORD *)(addr+1) + addr + 5; // change to hook to the actual address of function being called
|
||||
|
||||
HookParam hp;
|
||||
hp.address = addr;
|
||||
hp.type = NO_CONTEXT | USING_STRING | USING_SPLIT | SPLIT_INDIRECT;
|
||||
// hp.type = NO_CONTEXT|USING_STRING|FIXING_SPLIT;
|
||||
hp.split_index = 0x10; // use [[esp]+0x10] to differentiate name and thread
|
||||
|
||||
// Only name can be modified here, where the value of split is 0x6, and text in 0x2
|
||||
|
||||
ConsoleOutput("INSERT System43+");
|
||||
|
||||
ConsoleOutput("System43+: disable GDI hooks"); // disable hooking to TextOutA, which is cached
|
||||
|
||||
return NewHook(hp, hookName);
|
||||
}
|
||||
void System43New2Filter(TextBuffer *buffer, HookParam *)
|
||||
void System43aFilter(TextBuffer *buffer, HookParam *)
|
||||
{
|
||||
auto text = reinterpret_cast<LPSTR>(buffer->buff);
|
||||
|
||||
@ -895,7 +879,7 @@ void System43New2Filter(TextBuffer *buffer, HookParam *)
|
||||
}
|
||||
}
|
||||
|
||||
bool InsertSystem43New2Hook()
|
||||
bool InsertSystem43aHook()
|
||||
{
|
||||
|
||||
/*
|
||||
@ -910,30 +894,47 @@ bool InsertSystem43New2Hook()
|
||||
0x57, // push edi
|
||||
0xC6, 0x06, 0x00 // mov byte ptr [esi],00 << hook here
|
||||
};
|
||||
enum
|
||||
{
|
||||
addr_offset = sizeof(bytes) - 3
|
||||
};
|
||||
|
||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||
if (!addr)
|
||||
{
|
||||
ConsoleOutput("System43new: pattern not found");
|
||||
return false;
|
||||
}
|
||||
HookParam hp;
|
||||
hp.address = addr + addr_offset;
|
||||
hp.address = addr + sizeof(bytes) - 3;
|
||||
hp.offset = get_reg(regs::edx);
|
||||
hp.split = get_reg(regs::esp);
|
||||
hp.type = NO_CONTEXT | USING_STRING | USING_SPLIT;
|
||||
hp.filter_fun = System43New2Filter;
|
||||
ConsoleOutput("INSERT System43new");
|
||||
hp.filter_fun = System43aFilter;
|
||||
return NewHook(hp, "System43new");
|
||||
}
|
||||
|
||||
bool InsertSystem43bHook()
|
||||
{
|
||||
/*
|
||||
* Sample games:
|
||||
* https://vndb.org/v10732
|
||||
*/
|
||||
const BYTE bytes[] = {
|
||||
0x8B, 0xCE, // mov ecx,esi << hook here
|
||||
0xE8, XX4, // call Oyakorankan.exe+13D890
|
||||
0x8B, 0x43, 0x04, // mov eax,[ebx+04]
|
||||
0x8D, 0x4C, 0x24, 0x10, // lea ecx,[esp+10]
|
||||
0x3B, 0xC8, // cmp ecx,eax
|
||||
0x73, 0x64 // jae Oyakorankan.exe+1403B2
|
||||
};
|
||||
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||
if (!addr)
|
||||
return false;
|
||||
HookParam hp = {};
|
||||
hp.address = addr;
|
||||
hp.offset = get_reg(regs::edx);
|
||||
hp.split = get_stack(12);
|
||||
hp.type = USING_STRING | USING_SPLIT;
|
||||
NewHook(hp, "System43b");
|
||||
return true;
|
||||
}
|
||||
bool InsertSystem43Hook()
|
||||
{
|
||||
if (InsertSystem43New2Hook())
|
||||
if (InsertSystem43aHook() || InsertSystem43bHook())
|
||||
return true;
|
||||
// bool patched = Util::CheckFile(L"AliceRunPatch.dll");
|
||||
bool patched = ::GetModuleHandleA("AliceRunPatch.dll");
|
||||
|
@ -662,6 +662,22 @@ namespace
|
||||
s = std::regex_replace(s, std::regex(R"(#Color\[\d+?\])"), "");
|
||||
buffer->from(s);
|
||||
}
|
||||
void F0100CF90151E0000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
strReplace(ws, L"^", L"");
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(@c\d)"), L"");
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(@v\(\d+\))"), L"");
|
||||
buffer->from(WideStringToString(ws, 932));
|
||||
}
|
||||
void F010052300F612000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
s = std::regex_replace(s, std::regex(R"(#r(.*?)\|(.*?)#)"), "$1");
|
||||
strReplace(s, R"(\c)", "");
|
||||
strReplace(s, R"(\n)", "");
|
||||
buffer->from(s);
|
||||
}
|
||||
void F010001D015260000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->viewA();
|
||||
@ -892,6 +908,15 @@ namespace
|
||||
s = std::regex_replace(s, colorRegex, L"$1");
|
||||
buffer->from(s);
|
||||
}
|
||||
void F010015600D814000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
StringFilter(buffer, L"\\n", 2);
|
||||
auto s = buffer->viewW();
|
||||
static std::wstring last;
|
||||
if (last == s)
|
||||
return buffer->clear();
|
||||
last = s;
|
||||
}
|
||||
void F0100B0601852A000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->viewW();
|
||||
@ -3363,6 +3388,16 @@ namespace
|
||||
// 猛獣たちとお姫様 for Nintendo Switch 二合一
|
||||
{0x80115C70, {CODEC_UTF8, 0, 0, 0, F010001D015260000, "010035001D1B2000", "1.0.0"}}, // text
|
||||
{0x80115F20, {CODEC_UTF8, 0, 0, 0, F010001D015260000, "010035001D1B2000", "1.0.1"}}, // text
|
||||
// BEAST Darling!-けもみみ男子と秘密の寮-
|
||||
{0x80424D50, {CODEC_UTF16, 8, 0, 0, F0100B0601852A000, "010045F00BF64000", "1.0.0"}}, // text
|
||||
// 恋の花咲く百花園
|
||||
{0x211464, {0, 0, 0, 0, F010052300F612000, "010052300F612000", "1.0.0"}}, // text
|
||||
// 東京24区 -祈-
|
||||
{0x8006F100, {0, 0, 0, 0, F0100CF90151E0000, "0100CF90151E0000", "1.0.0"}}, // text
|
||||
// ディアマジ -魔法少年学科-
|
||||
{0x802B1270, {CODEC_UTF16, 8, 0, 0, F010015600D814000, "010015600D814000", "1.0.0"}}, // text
|
||||
{0x802B19E0, {CODEC_UTF16, 8, 0, 0, F010015600D814000, "010015600D814000", "1.0.1"}}, // text
|
||||
|
||||
};
|
||||
return 1;
|
||||
}();
|
||||
|
@ -7,84 +7,80 @@ Version: 24-March-2008
|
||||
#include <windows.h>
|
||||
#include "veh_hook.h"
|
||||
#include <mutex>
|
||||
static veh_list_t *list = NULL;
|
||||
char int3bp[] = "\xCC";
|
||||
char int3bp[] = OPCODE_INT3;
|
||||
std::mutex vehlistlock;
|
||||
|
||||
struct veh_node
|
||||
{
|
||||
void *origFunc;
|
||||
newFuncType newFunc;
|
||||
void *handle;
|
||||
DWORD hooktype;
|
||||
void *baseAddr; // Address of the page in which origFunc resides.
|
||||
BYTE origBaseByte;
|
||||
DWORD OldProtect;
|
||||
veh_node(void *origFunc, newFuncType newFunc, void *handle, DWORD hooktype) : hooktype(hooktype), handle(handle), newFunc(newFunc), origFunc(origFunc), OldProtect(PAGE_EXECUTE_READWRITE)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static std::map<void *, veh_node> list;
|
||||
|
||||
veh_node *get_veh_node(void *origFunc, int range = 0)
|
||||
{
|
||||
for (int i = 0; i <= range; i++)
|
||||
{
|
||||
auto ptr = (void *)((uintptr_t)origFunc - i);
|
||||
if (list.find(ptr) == list.end())
|
||||
continue;
|
||||
return &list.at(ptr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool add_veh_hook(void *origFunc, newFuncType newFunc, DWORD hook_type)
|
||||
{
|
||||
std::lock_guard _(vehlistlock);
|
||||
// static veh_list_t* list = NULL;
|
||||
DWORD oldProtect;
|
||||
if (list == NULL)
|
||||
list = new_veh_list();
|
||||
if (list == NULL)
|
||||
return false;
|
||||
if (get_veh_node(list, origFunc))
|
||||
if (get_veh_node(origFunc))
|
||||
return false;
|
||||
void *handle = AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)veh_dispatch);
|
||||
auto newnode = create_veh_node(origFunc, newFunc, handle, hook_type);
|
||||
if (newnode == NULL)
|
||||
return false;
|
||||
veh_node newnode{origFunc, newFunc, handle, hook_type};
|
||||
|
||||
// For memory hooks especially, we need to know the address of the start of the relevant page.
|
||||
MEMORY_BASIC_INFORMATION mem_info;
|
||||
VirtualQuery(origFunc, &mem_info, sizeof(MEMORY_BASIC_INFORMATION));
|
||||
newnode->baseAddr = mem_info.BaseAddress;
|
||||
if (!VirtualProtect(origFunc, sizeof(int), PAGE_EXECUTE_READWRITE, &newnode->OldProtect))
|
||||
newnode.baseAddr = mem_info.BaseAddress;
|
||||
if (!VirtualProtect(origFunc, sizeof(int), PAGE_EXECUTE_READWRITE, &newnode.OldProtect))
|
||||
{
|
||||
delete newnode;
|
||||
return false;
|
||||
}
|
||||
memcpy((void *)(&newnode->origBaseByte), (const void *)origFunc, sizeof(BYTE));
|
||||
memcpy((void *)(&newnode.origBaseByte), (const void *)origFunc, sizeof(BYTE));
|
||||
memcpy((void *)origFunc, (const void *)&int3bp, sizeof(BYTE));
|
||||
VirtualProtect(origFunc, sizeof(int), newnode->OldProtect, &oldProtect);
|
||||
insert_veh_node(list, newnode);
|
||||
VirtualProtect(origFunc, sizeof(int), newnode.OldProtect, &oldProtect);
|
||||
list.emplace(std::make_pair(origFunc, newnode));
|
||||
return true;
|
||||
}
|
||||
void repair_origin(veh_node_t *node)
|
||||
void repair_origin(veh_node *node)
|
||||
{
|
||||
DWORD _p;
|
||||
if (!VirtualProtect(node->origFunc, sizeof(int), PAGE_EXECUTE_READWRITE, &_p))
|
||||
return;
|
||||
memcpy((void *)node->origFunc, (const void *)(&node->origBaseByte), sizeof(char));
|
||||
memcpy((void *)node->origFunc, (const void *)(&node->origBaseByte), sizeof(BYTE));
|
||||
VirtualProtect(node->origFunc, sizeof(int), node->OldProtect, &_p);
|
||||
}
|
||||
bool remove_veh_hook(void *origFunc)
|
||||
{
|
||||
std::lock_guard _(vehlistlock);
|
||||
if (list == NULL)
|
||||
return false;
|
||||
veh_node_t *node = get_veh_node(list, origFunc);
|
||||
veh_node *node = get_veh_node(origFunc);
|
||||
if (node == NULL)
|
||||
return false;
|
||||
repair_origin(node);
|
||||
RemoveVectoredExceptionHandler(node->handle);
|
||||
return remove_veh_node(list, origFunc), true;
|
||||
return list.erase(origFunc), true;
|
||||
}
|
||||
|
||||
void remove_veh_node(veh_list_t *list, void *origFunc)
|
||||
{
|
||||
veh_node_t *searchnode = list->head;
|
||||
|
||||
while (searchnode != NULL)
|
||||
{
|
||||
if (searchnode->origFunc == origFunc)
|
||||
{
|
||||
if (list->tail == searchnode)
|
||||
list->tail = searchnode->last;
|
||||
if (list->head == searchnode)
|
||||
list->head = searchnode->next;
|
||||
if (searchnode->last)
|
||||
searchnode->last->next = searchnode->next;
|
||||
if (searchnode->next)
|
||||
searchnode->next->last = searchnode->last;
|
||||
|
||||
delete (searchnode);
|
||||
return;
|
||||
}
|
||||
searchnode = searchnode->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo)
|
||||
{
|
||||
|
||||
@ -98,10 +94,10 @@ LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo)
|
||||
|
||||
if (Code == STATUS_BREAKPOINT) //&& hooktype == VEH_HK_INT3)
|
||||
{
|
||||
veh_node_t *currnode;
|
||||
veh_node *currnode;
|
||||
{
|
||||
std::lock_guard _(vehlistlock);
|
||||
currnode = get_veh_node(list, Addr);
|
||||
currnode = get_veh_node(Addr);
|
||||
}
|
||||
if (currnode == NULL)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
@ -119,7 +115,7 @@ LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo)
|
||||
else if (Code == STATUS_SINGLE_STEP) //&& hooktype == VEH_HK_INT3)
|
||||
{
|
||||
std::lock_guard _(vehlistlock);
|
||||
veh_node_t *currnode = get_veh_node(list, Addr, 0x10);
|
||||
veh_node *currnode = get_veh_node(Addr, 0x10);
|
||||
if (currnode == NULL)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
@ -138,64 +134,4 @@ LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo)
|
||||
// currnode->newFunc(ExceptionInfo->ContextRecord);
|
||||
// }
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
veh_list_t *new_veh_list()
|
||||
{
|
||||
veh_list_t *newlist = (veh_list_t *)malloc(sizeof(veh_list_t));
|
||||
if (newlist == NULL)
|
||||
return NULL;
|
||||
newlist->head = NULL;
|
||||
newlist->tail = NULL;
|
||||
return newlist;
|
||||
}
|
||||
veh_node_t *create_veh_node(void *origFunc, newFuncType newFunc, void *handle, DWORD hook_type)
|
||||
{
|
||||
veh_node_t *newnode = new veh_node_t;
|
||||
if (newnode == NULL)
|
||||
return NULL;
|
||||
newnode->last = NULL;
|
||||
newnode->origFunc = origFunc;
|
||||
newnode->newFunc = newFunc;
|
||||
newnode->handle = handle;
|
||||
newnode->OldProtect = PAGE_EXECUTE_READWRITE;
|
||||
newnode->next = NULL;
|
||||
newnode->hooktype = hook_type;
|
||||
return newnode;
|
||||
}
|
||||
void insert_veh_node(veh_list_t *list, veh_node_t *newnode)
|
||||
{
|
||||
if (list == NULL)
|
||||
return;
|
||||
if (list->head == NULL)
|
||||
{
|
||||
list->head = newnode;
|
||||
list->tail = newnode;
|
||||
}
|
||||
else
|
||||
{
|
||||
list->tail->next = newnode;
|
||||
newnode->last = list->tail;
|
||||
list->tail = newnode;
|
||||
}
|
||||
}
|
||||
veh_node_t *get_veh_node(veh_list_t *list, void *origFunc, int range)
|
||||
{
|
||||
veh_node_t *newnode;
|
||||
veh_node_t *closestnode = NULL;
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
newnode = list->head;
|
||||
while (newnode != NULL)
|
||||
{
|
||||
if (((uintptr_t)origFunc - (uintptr_t)newnode->origFunc) <= range)
|
||||
{
|
||||
closestnode = newnode;
|
||||
if (range == 0)
|
||||
break;
|
||||
range = ((uintptr_t)origFunc - (uintptr_t)newnode->origFunc);
|
||||
}
|
||||
newnode = newnode->next;
|
||||
}
|
||||
return closestnode;
|
||||
}
|
||||
}
|
@ -21,25 +21,6 @@ Version: 24-March-2008
|
||||
// typedef void (*newFuncType)(PCONTEXT);
|
||||
using newFuncType = std::function<bool(PCONTEXT)>;
|
||||
|
||||
typedef struct veh_node
|
||||
{
|
||||
struct veh_node *last;
|
||||
struct veh_node *next;
|
||||
void *origFunc;
|
||||
newFuncType newFunc;
|
||||
void *handle;
|
||||
DWORD hooktype;
|
||||
void *baseAddr; // Address of the page in which origFunc resides.
|
||||
BYTE origBaseByte;
|
||||
DWORD OldProtect;
|
||||
} veh_node_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
veh_node_t *head;
|
||||
veh_node_t *tail;
|
||||
} veh_list_t;
|
||||
|
||||
// VEH hook interface functions for creating and removing hooks.
|
||||
bool add_veh_hook(void *origFunc, newFuncType newFunc, DWORD hook_type = VEH_HK_INT3);
|
||||
bool remove_veh_hook(void *origFunc);
|
||||
@ -49,10 +30,5 @@ bool remove_veh_hook(void *origFunc);
|
||||
LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo);
|
||||
|
||||
// Functions used internally by the library.
|
||||
veh_list_t *new_veh_list();
|
||||
veh_node_t *create_veh_node(void *origFunc, newFuncType newFunc, void *handle, DWORD hook_type);
|
||||
void insert_veh_node(veh_list_t *list, veh_node_t *);
|
||||
void remove_veh_node(veh_list_t *list, void *origFunc);
|
||||
veh_node_t *get_veh_node(veh_list_t *list, void *origFunc, int range = 0);
|
||||
|
||||
#endif // LIST_T_H_INCLUDED
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
set(VERSION_MAJOR 6)
|
||||
set(VERSION_MINOR 6)
|
||||
set(VERSION_PATCH 4)
|
||||
set(VERSION_PATCH 5)
|
||||
set(VERSION_REVISION 0)
|
||||
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")
|
||||
add_library(VERSION_DEF INTERFACE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user