diff --git a/LunaHook/engine32/Cotopha.cpp b/LunaHook/engine32/Cotopha.cpp index 17ab8a5..8bf81b9 100644 --- a/LunaHook/engine32/Cotopha.cpp +++ b/LunaHook/engine32/Cotopha.cpp @@ -596,7 +596,40 @@ namespace Private { } // namespace ScenarioHook } // unnamed namespace +bool CotophaFilter(LPVOID data, size_t *size, HookParam *) +{ + auto text = reinterpret_cast(data); + auto len = reinterpret_cast(size); + if (*len<=2 || text[0] != L'\\') + return false; + + size_t lenPurged = 0; + for (size_t i = 0; i < *len/2; i++) { + if (text[i] != L'\\') { + text[lenPurged++] = text[i]; + } else { + // start command + wchar_t cmd=text[++i]; + if (cmd == 'r') { // ruby + i++; // skip ';' char + while (text[++i] != L':') { + if (text[i] == L';') // when we reach '; ' we have the kanji part + break; + text[lenPurged++] = text[i]; + } + } + else if (cmd == L'n' && lenPurged) // newline + text[lenPurged++] = L' '; // for Western language compatibility + while (text[++i] != L':') + ; + } + } + if (lenPurged) + text[lenPurged++] = L' '; // for Western language compatibility + *len = lenPurged * 2; + return true; +} bool InsertCotophaHook1() { enum : DWORD { ins = 0xec8b55 }; // mov ebp,esp, sub esp,* ; jichi 7/12/2014 @@ -611,6 +644,7 @@ bool InsertCotophaHook1() hp.split = get_reg(regs::ebp); hp.type = CODEC_UTF16|USING_SPLIT|USING_STRING|EMBED_ABLE|EMBED_AFTER_NEW; hp.hook_before=ScenarioHook::Private::hookBefore; + hp.filter_fun = CotophaFilter; ConsoleOutput("INSERT Cotopha"); //RegisterEngineType(ENGINE_COTOPHA); @@ -677,7 +711,7 @@ bool InsertCotophaHook4() ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR); ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range); if (!addr) { - ConsoleOutput("vnreng:Cotopha4: pattern not found"); + ConsoleOutput("Cotopha4: pattern not found"); return false; } @@ -685,36 +719,7 @@ bool InsertCotophaHook4() hp.address = addr + 1; hp.offset = get_stack(1); hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT ; - hp.filter_fun = [](void* data, size_t* size, HookParam*) - { - auto text = reinterpret_cast(data); - auto len = reinterpret_cast(size); - - if (text[0] != L'\\') - return false; - - size_t lenPurged = 0; - for (size_t i = 0; i < *len/2; i++) { - if (text[i] != L'\\') - text[lenPurged++] = text[i]; - else { - // start command - wchar_t cmd=text[++i]; - if (cmd == 'r') { // ruby - i++; // skip ';' char - while (text[++i] != L':') { - if (text[i] == L';') // when we reach '; ' we have the kanji part - break; - text[lenPurged++] = text[i]; - } - } - while (text[++i] != L':') - ; - } - } - *len = lenPurged * 2; - return true; - }; + hp.filter_fun = CotophaFilter; NewHook(hp, "Cotopha4"); return true; } diff --git a/LunaHook/engine32/KiriKiri.cpp b/LunaHook/engine32/KiriKiri.cpp index 41299ee..4d0b6f6 100644 --- a/LunaHook/engine32/KiriKiri.cpp +++ b/LunaHook/engine32/KiriKiri.cpp @@ -1549,6 +1549,65 @@ bool InsertKiriKiri3Hook() return NewHook(hp, "KiriKiri3"); } +bool KiriKiri4Filter(LPVOID data, size_t *size, HookParam *) +{ + auto text = reinterpret_cast(data); + auto len = reinterpret_cast(size); + + if (text[0] == L'[' || text[0] == L'@' || (*len<=2 && text[0] == L' ')) + return false; + + if (cpp_wcsnstr(text, L"[", *len/sizeof(wchar_t))) { + StringCharReplacer(text, len, L"[r]", 3, L' '); + StringFilterBetween(text, len, L"[", 1, L"]\\", 2); + // ruby type 1 + StringFilterBetween(text, len, L"[mruby r=", 9, L"\" text=\"", 8); // [mruby r="ゆきみ" text="由紀美"] + // ruby type 2 + StringFilterBetween(text, len, L"[ruby text=", 11, L"]", 1); // [ruby text="せんがわ" align="e"][ch text="仙川"] + StringFilter(text, len, L"[ch text=\"", 10); // [ruby text="せんがわ" align="e"][ch text="仙川"] + // ruby type 1-2 + StringFilter(text, len, L"\"]", 2); + // end ruby + StringFilterBetween(text, len, L"[", 1, L"]", 1); + } + + return true; +} + +bool InsertKiriKiri4Hook() +{ + /* + * Sample games: + * https://vndb.org/r114393 + * https://vndb.org/v2916 + * https://vndb.org/r117083 + * https://vndb.org/v3851 + * https://vndb.org/v7804 + * https://vndb.org/v11123 + * https://vndb.org/v18650 + */ + const BYTE bytes[] = { + 0xE8, XX4, // call Kansen1._GetExceptDLLinfo+67B <-- hook here + 0x8D, 0x45, 0xA4, // lea eax,[ebp-5C] + 0xFF, 0x45, 0x9C, // inc [ebp-64] + 0xE8, XX4 // call Kansen1.exe+1D561C + }; + ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR); + ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range); + if (!addr) { + ConsoleOutput("KiriKiri4: pattern not found"); + return false; + } + + HookParam hp = {}; + hp.address = addr; + hp.offset = get_reg(regs::edx); + hp.type = NO_CONTEXT | CODEC_UTF16 | USING_STRING; + hp.filter_fun = KiriKiri4Filter; + ConsoleOutput(" INSERT KiriKiri4"); + NewHook(hp, "KiriKiri4"); + return true; +} bool KiriKiri::attach_function() { if (Util::SearchResourceString(L"TVP(KIRIKIRI) Z ")) { // TVP(KIRIKIRI) Z CORE // jichi 11/24/2014: Disabled that might crash VBH @@ -1563,5 +1622,5 @@ bool KiriKiri::attach_function() { bool b1=attachkr2(processStartAddress,processStopAddress); bool _3=wcslen_wcscpy(); auto _= InsertKiriKiriHook() || InsertKiriKiriZHook()||b1||_3; - return InsertKiriKiri3Hook()||_; + return (InsertKiriKiri4Hook()|InsertKiriKiri3Hook())||_; }