This commit is contained in:
恍兮惚兮 2024-03-12 17:02:41 +08:00
parent 2e711d9dc6
commit 018c299abd
2 changed files with 96 additions and 32 deletions

View File

@ -596,7 +596,40 @@ namespace Private {
} // namespace ScenarioHook } // namespace ScenarioHook
} // unnamed namespace } // unnamed namespace
bool CotophaFilter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPWSTR>(data);
auto len = reinterpret_cast<size_t *>(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() bool InsertCotophaHook1()
{ {
enum : DWORD { ins = 0xec8b55 }; // mov ebp,esp, sub esp,* ; jichi 7/12/2014 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.split = get_reg(regs::ebp);
hp.type = CODEC_UTF16|USING_SPLIT|USING_STRING|EMBED_ABLE|EMBED_AFTER_NEW; hp.type = CODEC_UTF16|USING_SPLIT|USING_STRING|EMBED_ABLE|EMBED_AFTER_NEW;
hp.hook_before=ScenarioHook::Private::hookBefore; hp.hook_before=ScenarioHook::Private::hookBefore;
hp.filter_fun = CotophaFilter;
ConsoleOutput("INSERT Cotopha"); ConsoleOutput("INSERT Cotopha");
//RegisterEngineType(ENGINE_COTOPHA); //RegisterEngineType(ENGINE_COTOPHA);
@ -677,7 +711,7 @@ bool InsertCotophaHook4()
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR); ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range); ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) { if (!addr) {
ConsoleOutput("vnreng:Cotopha4: pattern not found"); ConsoleOutput("Cotopha4: pattern not found");
return false; return false;
} }
@ -685,36 +719,7 @@ bool InsertCotophaHook4()
hp.address = addr + 1; hp.address = addr + 1;
hp.offset = get_stack(1); hp.offset = get_stack(1);
hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT ; hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT ;
hp.filter_fun = [](void* data, size_t* size, HookParam*) hp.filter_fun = CotophaFilter;
{
auto text = reinterpret_cast<LPWSTR>(data);
auto len = reinterpret_cast<size_t *>(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;
};
NewHook(hp, "Cotopha4"); NewHook(hp, "Cotopha4");
return true; return true;
} }

View File

@ -1549,6 +1549,65 @@ bool InsertKiriKiri3Hook()
return NewHook(hp, "KiriKiri3"); return NewHook(hp, "KiriKiri3");
} }
bool KiriKiri4Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPWSTR>(data);
auto len = reinterpret_cast<size_t *>(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() { bool KiriKiri::attach_function() {
if (Util::SearchResourceString(L"TVP(KIRIKIRI) Z ")) { // TVP(KIRIKIRI) Z CORE if (Util::SearchResourceString(L"TVP(KIRIKIRI) Z ")) { // TVP(KIRIKIRI) Z CORE
// jichi 11/24/2014: Disabled that might crash VBH // jichi 11/24/2014: Disabled that might crash VBH
@ -1563,5 +1622,5 @@ bool KiriKiri::attach_function() {
bool b1=attachkr2(processStartAddress,processStopAddress); bool b1=attachkr2(processStartAddress,processStopAddress);
bool _3=wcslen_wcscpy(); bool _3=wcslen_wcscpy();
auto _= InsertKiriKiriHook() || InsertKiriKiriZHook()||b1||_3; auto _= InsertKiriKiriHook() || InsertKiriKiriZHook()||b1||_3;
return InsertKiriKiri3Hook()||_; return (InsertKiriKiri4Hook()|InsertKiriKiri3Hook())||_;
} }