From 41670e543f7e586b715ad0b371bde6889f977ced 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, 9 Jan 2025 12:57:51 +0800 Subject: [PATCH] . --- cpp/LunaHook/LunaHook/texthook.cc | 13 +++-- cpp/LunaHook/LunaHook/veh_hook.cpp | 82 ++++++++---------------------- cpp/LunaHook/LunaHook/veh_hook.h | 7 ++- 3 files changed, 33 insertions(+), 69 deletions(-) diff --git a/cpp/LunaHook/LunaHook/texthook.cc b/cpp/LunaHook/LunaHook/texthook.cc index 482e8fb6..407a6e74 100644 --- a/cpp/LunaHook/LunaHook/texthook.cc +++ b/cpp/LunaHook/LunaHook/texthook.cc @@ -447,10 +447,15 @@ extern bool safeleave; bool TextHook::InsertBreakPoint() { // MH_CreateHook 64位unity/yuzu-emu经常 MH_ERROR_MEMORY_ALLOC - for (int i = 0; i < 1 + safeleave; i++) - if (add_veh_hook(location, std::bind(&TextHook::breakpointcontext, this, std::placeholders::_1))) - return true; - return false; + + if (!safeleave) + return add_veh_hook(location, std::bind(&TextHook::breakpointcontext, this, std::placeholders::_1)); + + if (add_veh_hook(location, std::bind(&TextHook::breakpointcontext, this, std::placeholders::_1))) + return true; + if (!remove_veh_hook(location)) + return false; + return add_veh_hook(location, std::bind(&TextHook::breakpointcontext, this, std::placeholders::_1)); } void TextHook::RemoveBreakPoint() { diff --git a/cpp/LunaHook/LunaHook/veh_hook.cpp b/cpp/LunaHook/LunaHook/veh_hook.cpp index f0c523d2..da2a99e1 100644 --- a/cpp/LunaHook/LunaHook/veh_hook.cpp +++ b/cpp/LunaHook/LunaHook/veh_hook.cpp @@ -18,8 +18,7 @@ struct veh_node BYTE origBaseByte; DWORD OldProtect; int usecount; - bool removed; - veh_node(void *origFunc, newFuncType newFunc, void *handle, DWORD hooktype) : hooktype(hooktype), handle(handle), newFunc(newFunc), origFunc(origFunc), OldProtect(PAGE_EXECUTE_READWRITE), usecount(0), removed(false) + veh_node(void *origFunc, newFuncType newFunc, void *handle, DWORD hooktype) : hooktype(hooktype), handle(handle), newFunc(newFunc), origFunc(origFunc), OldProtect(PAGE_EXECUTE_READWRITE), usecount(0) { } }; @@ -36,14 +35,9 @@ veh_node *get_veh_node(void *origFunc) bool __add_veh_hook(void *origFunc, newFuncType newFunc, DWORD hook_type) { DWORD oldProtect; - auto hasexitst = get_veh_node(origFunc); // hookfinder不删除钩子 - if (hasexitst) + if (get_veh_node(origFunc)) { - if (!hasexitst->removed) - return false; - hasexitst->newFunc = newFunc; - hasexitst->removed = false; - return true; + return false; } void *handle = AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)veh_dispatch); veh_node newnode{origFunc, newFunc, handle, hook_type}; @@ -87,43 +81,18 @@ void repair_origin(veh_node *node) *(BYTE *)node->origFunc = node->origBaseByte; VirtualProtect(node->origFunc, sizeof(int), node->OldProtect, &_p); } -bool __remove_veh_hook(void *origFunc) +bool remove_veh_hook(void *origFunc) { + std::lock_guard _(vehlistlock); veh_node *node = get_veh_node(origFunc); if (!node) return true; - if (node->usecount <= 0) - { - repair_origin(node); - RemoveVectoredExceptionHandler(node->handle); - list.erase(origFunc); - return true; - } - else - { - node->removed = true; + if (node->usecount > 0) return false; - } -} -void remove_veh_hook(void *origFunc) -{ - // 仅会在手动移除时被调用 - // while (true) - // { - // std::lock_guard _(vehlistlock); - if (__remove_veh_hook(origFunc)) - ; - // break; - //} -} -void remove_veh_hook(std::vector origFuncs) -{ - std::lock_guard _(vehlistlock); - for (auto origFunc : origFuncs) - { - // hookfinder时,usecount有时会无法归零(例如JIT重新写code),所以仅尝试一次即可 - __remove_veh_hook(origFunc); - } + repair_origin(node); + RemoveVectoredExceptionHandler(node->handle); + list.erase(origFunc); + return true; } thread_local veh_node *lastnode; LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo) @@ -143,37 +112,28 @@ LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo) veh_node *currnode = get_veh_node(Addr); if (!currnode) return EXCEPTION_CONTINUE_SEARCH; + currnode->usecount += 1; lastnode = currnode; repair_origin(currnode); - if (!currnode->removed) + if (currnode->newFunc(ExceptionInfo->ContextRecord)) + ExceptionInfo->ContextRecord->EFlags |= 0x100; + else { - currnode->usecount += 1; - if (currnode->newFunc(ExceptionInfo->ContextRecord)) - ExceptionInfo->ContextRecord->EFlags |= 0x100; + currnode->usecount -= 1; + lastnode = nullptr; } } else if (Code == STATUS_SINGLE_STEP) //&& hooktype == VEH_HK_INT3) { if (!lastnode) return EXCEPTION_CONTINUE_SEARCH; - if (!lastnode->removed) - { - VirtualProtect(Addr, sizeof(int), PAGE_EXECUTE_READWRITE, &lastnode->OldProtect); - *(BYTE *)lastnode->origFunc = OPCODE_INT3; - VirtualProtect(Addr, sizeof(int), lastnode->OldProtect, &oldProtect); - ExceptionInfo->ContextRecord->EFlags &= ~0x00000100; // Remove TRACE from EFLAGS - } + + VirtualProtect(Addr, sizeof(int), PAGE_EXECUTE_READWRITE, &lastnode->OldProtect); + *(BYTE *)lastnode->origFunc = OPCODE_INT3; + VirtualProtect(Addr, sizeof(int), lastnode->OldProtect, &oldProtect); + ExceptionInfo->ContextRecord->EFlags &= ~0x00000100; // Remove TRACE from EFLAGS lastnode->usecount -= 1; lastnode = nullptr; } - // else if (Code == STATUS_SINGLE_STEP && hooktype == VEH_HK_HW) - // { - // currnode->newFunc(ExceptionInfo->ContextRecord); - // } - // else if (Code == STATUS_SINGLE_STEP && hooktype == VEH_HK_MEM) - // { - - // currnode->newFunc(ExceptionInfo->ContextRecord); - // } return EXCEPTION_CONTINUE_EXECUTION; } \ No newline at end of file diff --git a/cpp/LunaHook/LunaHook/veh_hook.h b/cpp/LunaHook/LunaHook/veh_hook.h index 2ef6e476..52cfacde 100644 --- a/cpp/LunaHook/LunaHook/veh_hook.h +++ b/cpp/LunaHook/LunaHook/veh_hook.h @@ -23,9 +23,8 @@ using newFuncType = std::function; // VEH hook interface functions for creating and removing hooks. bool add_veh_hook(void *origFunc, newFuncType newFunc, DWORD hook_type = VEH_HK_INT3); -std::vector add_veh_hook(std::vectororigFuncs, std::vector newFuncs, DWORD hook_type = VEH_HK_INT3); -void remove_veh_hook(void *origFunc); -void remove_veh_hook(std::vectororigFuncs); +std::vector add_veh_hook(std::vector origFuncs, std::vector newFuncs, DWORD hook_type = VEH_HK_INT3); +bool remove_veh_hook(void *origFunc); // The VEH dispathing function is called by Windows every time an exception is encountered. // the function dispatches calls to the correct inctercept function. @@ -33,4 +32,4 @@ LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo); // Functions used internally by the library. -#endif // LIST_T_H_INCLUDED +#endif // LIST_T_H_INCLUDED \ No newline at end of file