This commit is contained in:
恍兮惚兮 2024-11-30 00:22:15 +08:00
parent 269168d2e7
commit 1dcf749c53
9 changed files with 197 additions and 36 deletions

View File

@ -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()

View File

@ -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");

View File

@ -0,0 +1,147 @@
#include "BGI.h"
//[241129][1305014][Tily] あの日の君を振り向かせて。 DL版 (files)
void BGI7Filter(TextBuffer *buffer, HookParam *)
{
auto text = reinterpret_cast<LPWSTR>(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<LPCSTR>(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+2Ej
.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+D2j
.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();
}

View File

@ -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();
};

View File

@ -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<ENGINE *> check_engines()
new Kincaid,
new lua51,
new MKXPZ,
new BGI,
};
}

View File

@ -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)

View File

@ -455,31 +455,6 @@ std::vector<DWORD> findrelativecall(const BYTE *pattern, int length, DWORD calla
}
return save;
}
std::vector<DWORD> findxref_reverse_checkcallop(DWORD addr, DWORD from, DWORD to, BYTE op)
{
// op可以为E8 call E9 jump
// 上面的版本其实就应该checkcallop的之前忘了但不敢乱改破坏之前的了不然还要重新测试。
std::vector<DWORD> 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<uintptr_t> findxref_reverse_checkcallop(uintptr_t addr, uintptr_t from, uintptr_t to, BYTE op)
{
// op可以为E8 call E9 jump
// 上面的版本其实就应该checkcallop的之前忘了但不敢乱改破坏之前的了不然还要重新测试。
std::vector<uintptr_t> 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<uintptr_t> findxref_reverse(uintptr_t addr, uintptr_t from, uintptr_t to)
{
std::vector<uintptr_t> res;

View File

@ -60,7 +60,6 @@ ULONG _SafeMatchBytesInMappedMemory(LPCVOID pattern, DWORD patternSize, BYTE wil
ULONG SafeMatchBytesInGCMemory(LPCVOID pattern, DWORD patternSize);
std::vector<DWORD> findrelativecall(const BYTE *pattern, int length, DWORD calladdress, DWORD start, DWORD end);
std::vector<DWORD> 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<uintptr_t> findxref_reverse(uintptr_t addr, uintptr_t from, uintptr_t to);
std::vector<uintptr_t> findxref_reverse_checkcallop(uintptr_t addr, uintptr_t from, uintptr_t to, BYTE op);
namespace Engine
{

View File

@ -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)