diff --git a/texthook/engine/engine.cc b/texthook/engine/engine.cc index f2354ae..bb4d080 100644 --- a/texthook/engine/engine.cc +++ b/texthook/engine/engine.cc @@ -10258,6 +10258,129 @@ void InsertStuffScriptHook() NewHook(hp, "StuffScriptEngine"); //RegisterEngine(ENGINE_STUFFSCRIPT); } +bool StuffScript2Filter(LPVOID data, DWORD *size, HookParam *, BYTE) +{ + auto text = reinterpret_cast(data); + auto len = reinterpret_cast(size); + + if (text[0] == '-') { + StringFilter(text, len, "-/-", 3); + StringFilterBetween(text, len, "-", 1, "-", 1); + } + StringCharReplacer(text, len, "_n_r", 4, '\n'); + StringCharReplacer(text, len, "_r", 2, ' '); + StringFilter(text, len, "\\n", 2); + StringFilter(text, len, "_n", 2); + + return true; +} +bool InsertStuffScript2Hook() +{ + //by Blu3train + /* + * Sample games: + * https://vndb.org/r41537 + * https://vndb.org/r41539 + */ + const BYTE bytes[] = { + 0x0F, XX, XX4, // jne tokyobabel.exe+3D4E8 + 0xB9, XX4, // mov ecx,tokyobabel.exe+54EAC + 0x8D, 0x85, XX4, // lea eax,[ebp+tokyobabel.exe+59B968] + 0x8A, 0x10, // mov dl,[eax] <-- hook here + 0x3A, 0x11, // cmp dl,[ecx] + 0x75, 0x1A, // jne tokyobabel.exe+3D1D7 + 0x84, 0xD2, // test dl,dl + 0x74, 0x12, // je tokyobabel.exe+3D1D3 + 0x8A, 0x50, 0x01, // mov dl,[eax+01] + 0x3A, 0x51, 0x01, // cmp dl,[ecx+01] + 0x75, 0x0E, // jne tokyobabel.exe+3D1D7 + 0x83, 0xC0, 0x02, // add eax,02 + 0x83, 0xC1, 0x02, // add ecx,02 + 0x84, 0xD2, // test dl,dl + 0x75, 0xE4, // jne Agreement.exe+4F538 + 0x33, 0xC0, // xor eax,eax + 0xEB, 0x05, // jmp Agreement.exe+4F55D + 0x1B, 0xC0, // sbb eax,eax + 0x83, 0xD8, 0xFF, // sbb eax,-01 + XX2, // cmp eax,edi + 0x0F, 0x84, XX4 // je tokyobabel.exe+3D4E8 + }; + ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR); + ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range); + if (!addr) + return false; + + HookParam hp = {}; + hp.address = addr + 0x11; + hp.offset = pusha_eax_off -4; + hp.index = 0; + hp.type = USING_STRING | NO_CONTEXT; + hp.filter_fun = StuffScript2Filter; + ConsoleOutput("vnreng: INSERT StuffScript2"); + NewHook(hp, "StuffScript2"); + return true; +} +bool StuffScript3Filter(LPVOID data, DWORD *size, HookParam *, BYTE) +{ + auto text = reinterpret_cast(data); + auto len = reinterpret_cast(size); + + if (text[0] == '\x81' && text[1] == '\x40') { //removes space at the beginning of the sentence + *len -= 2; + ::memmove(text, text + 2, *len); + } + + StringFilterBetween(text, len, "/\x81\x79", 3, "\x81\x7A", 2); //remove hidden name + StringFilterBetween(text, len, "[", 1, "]", 1); //garbage + + //ruby + CharFilter(text, len, '<'); + StringFilterBetween(text, len, ",", 1, ">", 1); + + StringCharReplacer(text, len, "_r\x81\x40", 4, ' '); + StringCharReplacer(text, len, "_r", 2, ' '); + + return true; +} +bool InsertStuffScript3Hook() +{ + //by Blu3train + /* + * Sample games: + * https://vndb.org/v3111 + */ + const BYTE bytes[] = { + 0xCC, // int 3 + 0x81, 0xEC, XX4, // sub esp,00000140 <-- hook here + 0xA1, XX4, // mov eax,[EVOLIMIT.exe+8C1F0] + 0x33, 0xC4, // xor eax,esp + 0x89, 0x84, 0x24, XX4, // mov [esp+0000013C],eax + 0x53, // push ebx + 0x55, // push ebp + 0x8B, 0xAC, 0x24, XX4, // mov ebp,[esp+0000014C] + 0x8B, 0x45, 0x2C // mov eax,[ebp+2C] + }; + ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR); + ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range); + if (!addr) + return false; + + HookParam hp = {}; + hp.address = addr + 1; + hp.offset = pusha_ecx_off -4; + hp.index = 0; + hp.type = USING_STRING | NO_CONTEXT; + hp.filter_fun = StuffScript3Filter; + ConsoleOutput("vnreng: INSERT StuffScript3"); + NewHook(hp, "StuffScript3"); + return true; +} +void InsertStuffScriptHooks() +{ + InsertStuffScriptHook(); + InsertStuffScript2Hook(); + InsertStuffScript3Hook(); +} bool InsertTriangleHook() { for (DWORD i = processStartAddress; i < processStopAddress - 4; i++) diff --git a/texthook/engine/engine.h b/texthook/engine/engine.h index 5fb4fb3..c765642 100644 --- a/texthook/engine/engine.h +++ b/texthook/engine/engine.h @@ -178,7 +178,7 @@ void InsertIronGameSystemHook();// IroneGameSystem: igs_sample.exe void InsertLucifenHook(); // Lucifen@Navel: *.lpk void InsertRyokuchaHook(); // Ryokucha: _checksum.exe void InsertRealliveHook(); // RealLive: RealLive*.exe -void InsertStuffScriptHook(); // Stuff: *.mpk +void InsertStuffScriptHooks(); // Stuff: *.mpk bool InsertTinkerBellHook(); // TinkerBell: arc00.dat bool InsertWaffleHook(); // WAFFLE: cg.pak bool InsertSekaiProjectHooks(); // Sekai Project: Packs/*.GPK diff --git a/texthook/engine/match32.cc b/texthook/engine/match32.cc index af57b78..b14fd66 100644 --- a/texthook/engine/match32.cc +++ b/texthook/engine/match32.cc @@ -351,11 +351,11 @@ bool DetermineEngineByFile3() return true; } if (Util::CheckFile(L"*.mpk")) { - InsertStuffScriptHook(); + InsertStuffScriptHooks(); return true; } if (Util::CheckFile(L"USRDIR\\*.mpk")) { // jichi 12/2/2014 - InsertStuffScriptHook(); + InsertStuffScriptHooks(); return true; } if (Util::CheckFile(L"Execle.exe")) {