mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-26 23:24:13 +08:00
.
This commit is contained in:
parent
269168d2e7
commit
1dcf749c53
@ -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()
|
||||
|
@ -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");
|
||||
|
147
cpp/LunaHook/LunaHook/engine64/BGI.cpp
Normal file
147
cpp/LunaHook/LunaHook/engine64/BGI.cpp
Normal 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+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();
|
||||
}
|
11
cpp/LunaHook/LunaHook/engine64/BGI.h
Normal file
11
cpp/LunaHook/LunaHook/engine64/BGI.h
Normal 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();
|
||||
};
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user