This commit is contained in:
恍兮惚兮 2024-12-05 14:26:03 +08:00
parent cf38f74a2e
commit 22322391db
8 changed files with 7 additions and 477 deletions

View File

@ -33,7 +33,6 @@ add_subdirectory(exec)
add_subdirectory(winsharedutils) add_subdirectory(winsharedutils)
add_subdirectory(shareddllproxy) add_subdirectory(shareddllproxy)
if(NOT WINXP) if(NOT WINXP)
add_subdirectory(hookmagpie)
add_subdirectory(LunaOCR) add_subdirectory(LunaOCR)
add_subdirectory(winrtutils) add_subdirectory(winrtutils)
add_subdirectory(wcocr) add_subdirectory(wcocr)

View File

@ -1,8 +0,0 @@
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
add_library(hookmagpie MODULE hookmagpie.cpp veh_hook.cpp)
target_precompile_headers(hookmagpie REUSE_FROM pch)
endif()

View File

@ -1,213 +0,0 @@
#include "veh_hook.h"
namespace Win32Utils
{
static HANDLE SafeHandle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
struct HandleCloser
{
void operator()(HANDLE h) noexcept
{
assert(h != INVALID_HANDLE_VALUE);
if (h)
CloseHandle(h);
}
};
using ScopedHandle = std::unique_ptr<std::remove_pointer<HANDLE>::type, HandleCloser>;
std::wstring GetPathOfWnd(HWND hWnd)
{
ScopedHandle hProc;
DWORD dwProcId = 0;
if (GetWindowThreadProcessId(hWnd, &dwProcId))
{
hProc.reset(SafeHandle(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcId)));
if (!hProc)
{
}
}
else
{
}
if (!hProc)
{
static const auto getProcessHandleFromHwnd = (HANDLE(WINAPI *)(HWND))GetProcAddress(
LoadLibraryEx(L"Oleacc.dll", NULL, 0), "GetProcessHandleFromHwnd");
if (getProcessHandleFromHwnd)
{
hProc.reset(getProcessHandleFromHwnd(hWnd));
if (!hProc)
{
}
}
if (!hProc)
{
return {};
}
}
std::wstring fileName(MAX_PATH, 0);
DWORD size = MAX_PATH;
if (!QueryFullProcessImageName(hProc.get(), 0, fileName.data(), &size))
{
return {};
}
fileName.resize(size);
return fileName;
}
}
namespace StrUtils
{
template <typename CHAR_T>
static void ToLowerCase(std::basic_string<CHAR_T> &str) noexcept
{
for (CHAR_T &c : str)
{
c = tolower(c);
}
}
}
static std::wstring GetExeName(HWND hWnd) noexcept
{
std::wstring exeName = Win32Utils::GetPathOfWnd(hWnd);
exeName = exeName.substr(exeName.find_last_of(L'\\') + 1);
StrUtils::ToLowerCase(exeName);
return exeName;
}
bool (*IsValidSrcWindow)(HWND);
struct hook_stack
{
#ifndef _WIN64
uintptr_t _eflags; // pushfd
uintptr_t edi, // pushad
esi,
ebp,
esp,
ebx,
edx,
ecx, // this
eax; // 0x28
#else
uintptr_t r15,
r14,
r13,
r12,
r11,
r10,
r9,
r8,
rdi,
rsi,
rbp,
rsp,
rdx,
rcx,
rbx,
rax;
#endif
uintptr_t eflags; // pushaf
union
{
uintptr_t stack[1]; // beginning of the runtime stack
uintptr_t retaddr;
BYTE base[1];
};
};
uintptr_t findEnclosingAlignedFunction_strict(uintptr_t start, uintptr_t back_range)
{
start &= ~0xf;
for (uintptr_t i = start, j = start - back_range; i > j; i -= 0x10)
{
DWORD k = *(DWORD *)(i - 4);
if (k == 0xcccccccc || k == 0x90909090 || k == 0xccccccc3 || k == 0x909090c3)
return i;
}
return 0;
}
bool checkislunawindow(HWND hwndSrc)
{
wchar_t title[100];
GetWindowText(hwndSrc, title, 100);
if (wcscmp(title, L"LunaTranslator") == 0 || GetExeName(hwndSrc) == L"lunatranslator_main.exe" || GetExeName(hwndSrc) == L"lunatranslator.exe")
return true;
else
return false;
}
void hookedisvalidwindow(PCONTEXT context)
{
auto hwndSrc = (HWND)(context->Rcx);
if (checkislunawindow(hwndSrc))
{
// MessageBoxW(0,GetExeName(hwndSrc).c_str(),L"",0);
context->Rcx = (uintptr_t)FindWindow(L"Shell_TrayWnd", nullptr);
}
}
void starthookmagpie()
{
uintptr_t IsValidSrcWindow = 0;
wchar_t target[] = L"Shell_TrayWnd";
auto base = (uintptr_t)GetModuleHandle(L"Magpie.App.dll");
BYTE lea[] = {0x48, 0x8D, 0x05};
//.text:0000000180146AD0 48 8D 05 91 87 10 00 lea rax, aShellTraywnd ; "Shell_TrayWnd"
//.rdata:000000018024F268 53 00 68 00 65 00 6C 00 6C 00+text "UTF-16LE", 'Shell_TrayWnd',0
__try
{
for (int i = 0; i < 0x1000000; i++)
{
if (memcmp(lea, (LPVOID)(i + base), 3) == 0)
{
auto addr = base + i;
auto leastr = (*(int *)(addr + 3)) + 7 + addr;
if (IsBadReadPtr((LPVOID)leastr, sizeof(target)) == 0)
if (wcscmp((wchar_t *)leastr, target) == 0)
{
IsValidSrcWindow = findEnclosingAlignedFunction_strict(addr, 0x1000);
break;
}
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return;
}
if (IsValidSrcWindow == 0)
return;
// IsValidSrcWindow=(decltype(IsValidSrcWindow))((uintptr_t)GetModuleHandle(L"Magpie.App.dll")+0x180146860-0x180000000);
add_veh_hook((LPVOID)IsValidSrcWindow, hookedisvalidwindow, 0);
// DetourTransactionBegin();
// DetourUpdateThread(GetCurrentThread());
// DetourAttach(&(PVOID&)IsValidSrcWindow,IsValidSrcWindow_hooked);
// DetourTransactionCommit();
}
void starthook()
{
if (GetModuleHandle(L"Magpie.App.dll"))
starthookmagpie();
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
starthook();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@ -1,180 +0,0 @@
/**
veh_hook Vectored Exception Handler hooking library
Version: 24-March-2008
**/
// #define WINVER 0x0501
// #define _WIN32_WINNT 0x0501
#include "veh_hook.h"
static veh_list_t *list = NULL;
char int3bp[] = "\xCC";
std::mutex vehlistlock;
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;
void *handle = AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)veh_dispatch);
veh_node_t *newnode = insert_veh_node(list, 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;
VirtualProtect(origFunc, sizeof(int), PAGE_EXECUTE_READWRITE, &newnode->OldProtect);
memcpy((void *)(&newnode->origBaseByte), (const void *)origFunc, sizeof(BYTE));
memcpy((void *)origFunc, (const void *)&int3bp, sizeof(BYTE));
VirtualProtect(origFunc, sizeof(int), newnode->OldProtect, &oldProtect);
return true;
}
bool remove_veh_hook(void *origFunc)
{
std::lock_guard _(vehlistlock);
if (list == NULL)
return false;
veh_node_t *node = get_veh_node(list, origFunc);
if (node == NULL)
return false;
DWORD _p;
VirtualProtect(node->origFunc, sizeof(int), PAGE_EXECUTE_READWRITE, &_p);
memcpy((void *)node->origFunc, (const void *)(&node->origBaseByte), sizeof(char));
VirtualProtect(node->origFunc, sizeof(int), node->OldProtect, &_p);
RemoveVectoredExceptionHandler(node->handle);
return remove_veh_node(list, origFunc);
}
bool remove_veh_node(veh_list_t *list, void *origFunc)
{
veh_node_t *searchnode;
veh_node_t *lastsearchnode = NULL;
searchnode = list->head;
while (searchnode != NULL)
{
if (searchnode->origFunc == origFunc)
{
if (lastsearchnode == NULL)
{
list->head = searchnode->next;
if (list->tail == searchnode)
list->tail = searchnode->next;
}
else
{
lastsearchnode->next = searchnode->next;
}
delete (searchnode);
return true;
}
lastsearchnode = searchnode;
searchnode = searchnode->next;
}
return false;
}
LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo)
{
DWORD oldProtect;
void *Addr = ExceptionInfo->ExceptionRecord->ExceptionAddress;
ULONG Code = ExceptionInfo->ExceptionRecord->ExceptionCode;
if (Code != STATUS_BREAKPOINT && Code != STATUS_SINGLE_STEP)
return EXCEPTION_CONTINUE_SEARCH;
// Try to find the node associated with the address of the current exception, continue searching for handlers if not found;
std::lock_guard _(vehlistlock);
if (Code == STATUS_BREAKPOINT) //&& hooktype == VEH_HK_INT3)
{
veh_node_t *currnode = get_veh_node(list, Addr);
if (currnode == NULL)
return EXCEPTION_CONTINUE_SEARCH;
VirtualProtect(Addr, sizeof(int), PAGE_EXECUTE_READWRITE, &currnode->OldProtect);
memcpy((void *)Addr, (const void *)(&currnode->origBaseByte), sizeof(char));
currnode->newFunc(ExceptionInfo->ContextRecord);
VirtualProtect(Addr, sizeof(int), currnode->OldProtect, &oldProtect);
ExceptionInfo->ContextRecord->EFlags |= 0x100;
}
else if (Code == STATUS_SINGLE_STEP) //&& hooktype == VEH_HK_INT3)
{
veh_node_t *currnode = get_veh_node(list, Addr, 0x10);
if (currnode == NULL)
return EXCEPTION_CONTINUE_SEARCH;
VirtualProtect(Addr, sizeof(int), PAGE_EXECUTE_READWRITE, &currnode->OldProtect);
memcpy((void *)currnode->origFunc, (const void *)&int3bp, sizeof(BYTE));
VirtualProtect(Addr, sizeof(int), currnode->OldProtect, &oldProtect);
ExceptionInfo->ContextRecord->EFlags &= ~0x00000100; // Remove TRACE from EFLAGS
}
// 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;
}
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 *insert_veh_node(veh_list_t *list, void *origFunc, newFuncType newFunc, void *handle, DWORD hook_type)
{
if (list == NULL)
return NULL;
/* create a new node and fill in the blanks */
veh_node_t *newnode = new veh_node_t;
if (newnode == NULL)
return NULL;
newnode->origFunc = origFunc;
newnode->newFunc = newFunc;
newnode->handle = handle;
newnode->OldProtect = PAGE_EXECUTE_READWRITE;
newnode->next = NULL;
newnode->hooktype = hook_type;
if (list->head == NULL)
{
list->head = newnode;
list->tail = newnode;
}
else
{
list->tail->next = newnode;
list->tail = newnode;
}
return 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;
}

View File

@ -1,52 +0,0 @@
/**
veh_hook Vectored Exception Handler hooking library
Version: 24-March-2008
**/
#ifndef LIST_T_H_INCLUDED
#define LIST_T_H_INCLUDED
// VEH Hooking types
#define VEH_HK_INT3 0
#define VEH_HK_MEM 1
#define VEH_HK_HW 2
// -
#define OPCODE_INT3 "\xCC"
// typedef void (*pfvoid)();
// typedef void (*newFuncType)(PCONTEXT);
using newFuncType = void (*)(PCONTEXT); // std::function<void(PCONTEXT)>;
typedef 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;
struct veh_node *next;
} 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);
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.
LONG CALLBACK veh_dispatch(PEXCEPTION_POINTERS ExceptionInfo);
// Functions used internally by the library.
veh_list_t *new_veh_list();
veh_node_t *insert_veh_node(veh_list_t *list, void *origFunc, newFuncType newFunc, void *handle, DWORD hook_type);
bool 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

View File

@ -1,7 +1,7 @@
set(VERSION_MAJOR 6) set(VERSION_MAJOR 6)
set(VERSION_MINOR 10) set(VERSION_MINOR 10)
set(VERSION_PATCH 1) set(VERSION_PATCH 2)
set(VERSION_REVISION 0) set(VERSION_REVISION 0)
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")
add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp) add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp)

View File

@ -2,42 +2,27 @@ from scalemethod.base import scalebase
import os, json import os, json
import windows, winsharedutils import windows, winsharedutils
from myutils.config import globalconfig from myutils.config import globalconfig
from myutils.hwnd import injectdll
from myutils.subproc import subproc_w from myutils.subproc import subproc_w
import time import time
from myutils.wrapper import threader from myutils.wrapper import threader
class Method(scalebase): class Method(scalebase):
def init(self):
self.injectedpids = set()
def runmagpie(self): def runmagpie(self):
if windows.FindWindow("Magpie_Hotkey", None) == 0: if not windows.FindWindow("Magpie_Hotkey", None):
subproc_w( subproc_w(
os.path.join(globalconfig["magpiepath"], "Magpie.exe"), os.path.join(globalconfig["magpiepath"], "Magpie.exe"),
cwd=globalconfig["magpiepath"], cwd=globalconfig["magpiepath"],
name="magpie", name="magpie",
) )
while windows.FindWindow("Magpie_Hotkey", None) == 0: while not windows.FindWindow("Magpie_Hotkey", None):
time.sleep(0.5) time.sleep(0.5)
if True:
pid = windows.GetWindowThreadProcessId(
windows.FindWindow("Magpie_Hotkey", None)
)
if pid in self.injectedpids:
return
dll = os.path.abspath("./files/plugins/hookmagpie.dll")
injectdll([pid], 64, dll)
self.injectedpids.add(pid)
@threader @threader
def _wait_magpie_stop_external(self): def _wait_magpie_stop_external(self):
while ( while not windows.FindWindow(
windows.FindWindow( "Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", None
"Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", None
)
== 0
): ):
time.sleep(0.5) time.sleep(0.5)
while windows.FindWindow( while windows.FindWindow(

View File

@ -1448,7 +1448,6 @@
"shared": [ "shared": [
"./files/plugins/shareddllproxy32.exe", "./files/plugins/shareddllproxy32.exe",
"./files/plugins/shareddllproxy64.exe", "./files/plugins/shareddllproxy64.exe",
"./files/plugins/hookmagpie.dll",
"./files/plugins/Magpie/Magpie.Core.exe", "./files/plugins/Magpie/Magpie.Core.exe",
"./files/plugins/LunaHook/LunaHook32.dll", "./files/plugins/LunaHook/LunaHook32.dll",
"./files/plugins/LunaHook/LunaHost32.dll", "./files/plugins/LunaHook/LunaHost32.dll",