From 1dcf749c531e8c93124ddf52815f02ad46775fe2 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: Sat, 30 Nov 2024 00:22:15 +0800 Subject: [PATCH] . --- cpp/LunaHook/LunaHook/CMakeLists.txt | 2 +- cpp/LunaHook/LunaHook/engine32/BGI.cpp | 3 +- cpp/LunaHook/LunaHook/engine64/BGI.cpp | 147 +++++++++++++++++++ cpp/LunaHook/LunaHook/engine64/BGI.h | 11 ++ cpp/LunaHook/LunaHook/enginecollection64.cpp | 2 + cpp/LunaHook/LunaHook/texthook.cc | 13 +- cpp/LunaHook/LunaHook/util/util.cc | 51 +++---- cpp/LunaHook/LunaHook/util/util.h | 2 +- cpp/version.cmake | 2 +- 9 files changed, 197 insertions(+), 36 deletions(-) create mode 100644 cpp/LunaHook/LunaHook/engine64/BGI.cpp create mode 100644 cpp/LunaHook/LunaHook/engine64/BGI.h diff --git a/cpp/LunaHook/LunaHook/CMakeLists.txt b/cpp/LunaHook/LunaHook/CMakeLists.txt index 39035eca..5fc9dd77 100644 --- a/cpp/LunaHook/LunaHook/CMakeLists.txt +++ b/cpp/LunaHook/LunaHook/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(. util engines) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) - set(enginessrc MKXPZ Ryujinx livecaptions Kincaid vita3k rpcs3 yuzu TYPEMOON UnrealEngine AGES7 mono Godot 5pb lucasystem LightVN V8 Artemis KiriKiri YOX PPSSPP CMVS Suika2 ) + set(enginessrc BGI MKXPZ Ryujinx livecaptions Kincaid vita3k rpcs3 yuzu TYPEMOON UnrealEngine AGES7 mono Godot 5pb lucasystem LightVN V8 Artemis KiriKiri YOX PPSSPP CMVS Suika2 ) set(enginepath "engine64") set(collector "enginecollection64.cpp") else() diff --git a/cpp/LunaHook/LunaHook/engine32/BGI.cpp b/cpp/LunaHook/LunaHook/engine32/BGI.cpp index cf586691..67861b1e 100644 --- a/cpp/LunaHook/LunaHook/engine32/BGI.cpp +++ b/cpp/LunaHook/LunaHook/engine32/BGI.cpp @@ -1593,8 +1593,7 @@ bool InsertBGI4Hook() buffer->from((wchar_t *)stack->stack[2]); } }; - hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT | EMBED_ABLE | EMBED_AFTER_OVERWRITE; - hp.embed_hook_font = F_TextOutW | F_GetTextExtentPoint32W; + hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT; hp.filter_fun = BGI7Filter; hp.offset = get_stack(2); ConsoleOutput("BGI4"); diff --git a/cpp/LunaHook/LunaHook/engine64/BGI.cpp b/cpp/LunaHook/LunaHook/engine64/BGI.cpp new file mode 100644 index 00000000..0d80aa80 --- /dev/null +++ b/cpp/LunaHook/LunaHook/engine64/BGI.cpp @@ -0,0 +1,147 @@ +#include "BGI.h" +//[241129][1305014][Tily] あの日の君を振り向かせて。 DL版 (files) +void BGI7Filter(TextBuffer *buffer, HookParam *) +{ + auto text = reinterpret_cast(buffer->buff); + CharFilter(buffer, L'\x0001'); + CharFilter(buffer, L'\x0002'); + CharFilter(buffer, L'\x0003'); + CharFilter(buffer, L'\x0004'); + CharFilter(buffer, L'\x0005'); + CharFilter(buffer, L'\x000A'); + if (text[0] == L'\u3000') + { + buffer->size -= 2; + ::memmove(text, text + 1, buffer->size); + } + CharReplacer(buffer, L'\u3000', L' '); // IDSP + + if (cpp_wcsnstr(text, L"<", buffer->size / sizeof(wchar_t))) + { + StringFilterBetween(buffer, L"<", 1, L">", 1); + } +} +void BGI7FilterA(TextBuffer *buffer, HookParam *) +{ + auto text = reinterpret_cast(buffer->buff); + StringFilterBetween(buffer, "<", 1, ">", 1); +} +bool BGIattach_function1() +{ + /* +CHAR *__fastcall sub_1400F5BC0(LPSTR lpMultiByteStr, LPCWCH lpWideCharStr) +{ + CHAR *v3; // rdi + UINT v5; // ebx + int v6; // r8d + int v7; // eax + int cbMultiByte; // ebp + + v3 = 0i64; + v5 = sub_1400F4740(); + if ( v6 ) + { + if ( v6 == 1 ) + v5 = 65001; + } + else + { + v5 = 932; + } + v7 = WideCharToMultiByte(v5, 0, lpWideCharStr, -1, 0i64, 0, 0i64, 0i64); + cbMultiByte = v7; + if ( v7 >= 1 ) + { + if ( !lpMultiByteStr ) + { + v3 = (CHAR *)operator new(v7 + 1); + lpMultiByteStr = v3; + } + WideCharToMultiByte(v5, 0, lpWideCharStr, -1, lpMultiByteStr, cbMultiByte, 0i64, 0i64); + } + return v3; +} +.text:00000001400F5BF6 mov ebx, 0FDE9h +.text:00000001400F5BFB jmp short loc_1400F5C02 +.text:00000001400F5BFD ; --------------------------------------------------------------------------- +.text:00000001400F5BFD +.text:00000001400F5BFD loc_1400F5BFD: ; CODE XREF: sub_1400F5BC0+2E↑j +.text:00000001400F5BFD mov ebx, 3A4h*/ + const BYTE bytes[] = { + 0xBB, 0xE9, 0xFD, 0x00, 0x00, // cp=65001 + XX2, + 0xBB, 0xA4, 0x03, 0x00, 0x00 // cp=932 + }; + auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); + if (!addr) + return false; + addr = MemDbg::findEnclosingAlignedFunction(addr); + if (!addr) + return false; + HookParam hp; + hp.address = addr; + hp.type = CODEC_UTF16 | USING_STRING; + hp.filter_fun = BGI7Filter; + hp.offset = GETARG2; + return NewHook(hp, "BGI"); +} + +bool BGIattach_function2() +{ + /* + if ( *(unsigned __int8 *)v1 == 239 ) + { + v12 = *((unsigned __int8 *)v1 + 1) | 0xEF00; + goto LABEL_16; + } + if ( *(unsigned __int8 *)v1 == 255 ) + { + v12 = *((unsigned __int8 *)v1 + 1) | 0xF000; +.text:000000014007051C movzx eax, byte ptr [rbx+1] +.text:0000000140070520 or eax, 0F000h +.text:0000000140070525 jmp short loc_140070530 +.text:0000000140070527 ; --------------------------------------------------------------------------- +.text:0000000140070527 +.text:0000000140070527 loc_140070527: ; CODE XREF: sub_140070430+D2↑j +.text:0000000140070527 movzx eax, byte ptr [rbx+1] +.text:000000014007052B or eax, 0EF00h*/ + const BYTE bytes[] = { + 0x0F, 0xB6, 0x43, 0x01, + 0x0D, 0x00, 0xF0, 0x00, 0x00, + XX2, + 0x0F, 0xB6, 0x43, 0x01, + 0x0D, 0x00, 0xEF, 0x00, 0x00}; + auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); + if (!addr) + return false; + addr = MemDbg::findEnclosingAlignedFunction(addr); + if (!addr) + return false; + auto addrs = findxref_reverse_checkcallop(addr, processStartAddress, processStopAddress, 0xe8); + if (1 != addrs.size()) + { + HookParam hp; + hp.address = addrs[0]; + hp.type = USING_STRING; + hp.filter_fun = BGI7FilterA; + hp.offset = GETARG1; + return NewHook(hp, "BGI"); + } + HookParam hp; + hp.address = addrs[0] + 5; + hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT | EMBED_ABLE | EMBED_AFTER_NEW; + hp.embed_hook_font = F_TextOutW | F_GetTextExtentPoint32W; + hp.filter_fun = BGI7Filter; + hp.offset = get_reg(regs::rax); + static uintptr_t replaceaddr = addr; + patch_fun = []() + { + ReplaceFunction((void *)replaceaddr, +[](LPCCH lpMultiByteStr) + { return allocateString(StringToWideString(lpMultiByteStr, 932).value_or(L"")); }); + }; + return NewHook(hp, "BGI"); +} +bool BGI::attach_function() +{ + return BGIattach_function2() || BGIattach_function1(); +} \ No newline at end of file diff --git a/cpp/LunaHook/LunaHook/engine64/BGI.h b/cpp/LunaHook/LunaHook/engine64/BGI.h new file mode 100644 index 00000000..326a9bb6 --- /dev/null +++ b/cpp/LunaHook/LunaHook/engine64/BGI.h @@ -0,0 +1,11 @@ + + +class BGI:public ENGINE{ + public: + BGI(){ + + check_by=CHECK_BY::FILE_ANY; + check_by_target=check_by_list{L"bgi.*",L"sysgrp.arc"}; + }; + bool attach_function(); +}; diff --git a/cpp/LunaHook/LunaHook/enginecollection64.cpp b/cpp/LunaHook/LunaHook/enginecollection64.cpp index 4eac4253..7e2b3b8d 100644 --- a/cpp/LunaHook/LunaHook/enginecollection64.cpp +++ b/cpp/LunaHook/LunaHook/enginecollection64.cpp @@ -14,6 +14,7 @@ #include "engine64/UnrealEngine.h" #include "engine64/TYPEMOON.h" #include "engine64/Kincaid.h" +#include "engine64/BGI.h" #include "engine64/LightVN.h" #include "engine64/yuzu.h" #include "engine64/Ryujinx.h" @@ -49,5 +50,6 @@ std::vector check_engines() new Kincaid, new lua51, new MKXPZ, + new BGI, }; } diff --git a/cpp/LunaHook/LunaHook/texthook.cc b/cpp/LunaHook/LunaHook/texthook.cc index 27aed600..dce5f941 100644 --- a/cpp/LunaHook/LunaHook/texthook.cc +++ b/cpp/LunaHook/LunaHook/texthook.cc @@ -392,11 +392,16 @@ void TextHook::Send(uintptr_t lpDataBase) if (canembed && (check_embed_able(tp))) { auto lpCountsave = buff.size; + auto zeros = 1; + if (hp.type & CODEC_UTF16) + zeros = 2; + else if (hp.type & CODEC_UTF32) + zeros = 4; if (waitfornotify(&buff, tp)) { if (hp.type & EMBED_AFTER_NEW) { - auto size = max(lpCountsave, buff.size + 1); + auto size = max(lpCountsave, buff.size + zeros); auto _ = new char[size]; memcpy(_, buff.buff, buff.size); memset(_ + buff.size, 0, size - buff.size); @@ -405,11 +410,7 @@ void TextHook::Send(uintptr_t lpDataBase) else if (hp.type & EMBED_AFTER_OVERWRITE) { memcpy((void *)lpDataIn, buff.buff, buff.size); - auto zeros = 1; - if (hp.type & CODEC_UTF16) - zeros = 2; - else if (hp.type & CODEC_UTF32) - zeros = 4; + memset((char *)lpDataIn + buff.size, 0, max(lpCountsave, zeros)); } else if (hp.embed_fun) diff --git a/cpp/LunaHook/LunaHook/util/util.cc b/cpp/LunaHook/LunaHook/util/util.cc index 2dca52eb..d7705bb8 100644 --- a/cpp/LunaHook/LunaHook/util/util.cc +++ b/cpp/LunaHook/LunaHook/util/util.cc @@ -455,31 +455,6 @@ std::vector findrelativecall(const BYTE *pattern, int length, DWORD calla } return save; } -std::vector findxref_reverse_checkcallop(DWORD addr, DWORD from, DWORD to, BYTE op) -{ - // op可以为E8 call E9 jump - // 上面的版本其实就应该checkcallop的,之前忘了,但不敢乱改破坏之前的了,不然还要重新测试。 - std::vector res; - if (addr == 0) - return res; - DWORD now = to; - while (now > from) - { - DWORD calladdr = now - 5; - if (IsBadReadPtr((LPVOID)(calladdr + 1), 4) == 0) - { - DWORD relative = *(DWORD *)(calladdr + 1); - if (now + relative == addr) - { - if (*(BYTE *)calladdr == op) - res.push_back(calladdr); - } - } - - now -= 1; - } - return res; -} uintptr_t finddllfunctioncall(uintptr_t funcptr, uintptr_t start, uintptr_t end, WORD sig, bool reverse) { auto entry = Util::FindImportEntry(start, funcptr); @@ -567,6 +542,32 @@ uintptr_t reverseFindBytes(const BYTE *pattern, int length, uintptr_t start, uin } return 0; } + +std::vector findxref_reverse_checkcallop(uintptr_t addr, uintptr_t from, uintptr_t to, BYTE op) +{ + // op可以为E8 call E9 jump + // 上面的版本其实就应该checkcallop的,之前忘了,但不敢乱改破坏之前的了,不然还要重新测试。 + std::vector res; + if (addr == 0) + return res; + uintptr_t now = to; + while (now > from) + { + uintptr_t calladdr = now - 5; + if (IsBadReadPtr((LPVOID)(calladdr + 1), 4) == 0) + { + int relative = *(int *)(calladdr + 1); + if (now + relative == addr) + { + if (*(BYTE *)calladdr == op) + res.push_back(calladdr); + } + } + + now -= 1; + } + return res; +} std::vector findxref_reverse(uintptr_t addr, uintptr_t from, uintptr_t to) { std::vector res; diff --git a/cpp/LunaHook/LunaHook/util/util.h b/cpp/LunaHook/LunaHook/util/util.h index 4b2f6548..e403792f 100644 --- a/cpp/LunaHook/LunaHook/util/util.h +++ b/cpp/LunaHook/LunaHook/util/util.h @@ -60,7 +60,6 @@ ULONG _SafeMatchBytesInMappedMemory(LPCVOID pattern, DWORD patternSize, BYTE wil ULONG SafeMatchBytesInGCMemory(LPCVOID pattern, DWORD patternSize); std::vector findrelativecall(const BYTE *pattern, int length, DWORD calladdress, DWORD start, DWORD end); -std::vector findxref_reverse_checkcallop(DWORD addr, DWORD from, DWORD to, BYTE op); uintptr_t finddllfunctioncall(uintptr_t funcptr, uintptr_t start, uintptr_t end, WORD sig = 0x15ff, bool reverse = false); uintptr_t findfuncstart(uintptr_t addr, uintptr_t range = 0x100, bool checkalign = false); uintptr_t findiatcallormov(uintptr_t addr, DWORD hmodule, uintptr_t start, uintptr_t end, bool reverse = false, BYTE movreg = 0); @@ -72,6 +71,7 @@ uintptr_t find_pattern(const char *pattern, uintptr_t start, uintptr_t end); uintptr_t reverseFindBytes(const BYTE *pattern, int length, uintptr_t start, uintptr_t end, int offset = 0, bool checkalign = false); std::vector findxref_reverse(uintptr_t addr, uintptr_t from, uintptr_t to); +std::vector findxref_reverse_checkcallop(uintptr_t addr, uintptr_t from, uintptr_t to, BYTE op); namespace Engine { diff --git a/cpp/version.cmake b/cpp/version.cmake index 372d04ea..32ecd7fe 100644 --- a/cpp/version.cmake +++ b/cpp/version.cmake @@ -1,7 +1,7 @@ set(VERSION_MAJOR 6) set(VERSION_MINOR 8) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) set(VERSION_REVISION 0) set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp)