PONScripter engine hook for Ciconia When They Cry

This commit is contained in:
Blu3train 2023-07-28 00:39:09 +02:00
parent f3fbe04409
commit 6bdf59d1bf
3 changed files with 102 additions and 2 deletions

View File

@ -12930,6 +12930,106 @@ bool InsertPONScripterHook()
return false;
}
bool PONScripterFilter(LPVOID data, DWORD *size, HookParam *, BYTE)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
static std::string prevText;
for (int i=0; i<*len; i++) {
if (text[i] == '^' || text[i]=='@' || text[i]=='\\' || text[i]=='\n') {
text[i] = '\0';
*len = i;
break;
}
}
if (!prevText.compare(text))
return false;
prevText = text;
StringFilter(text, len, "#", 7); // remove # followed by 6 chars
return true;
}
bool InsertPONScripterEngHook()
{
//by Blu3train
/*
* Sample games:
* https://vndb.org/v24770
*/
const BYTE bytes[] = {
0x89, 0xD0, // mov eax,edx
0x8D, 0x75, 0xD8, // lea esi,[ebp-28]
0x89, 0x55, 0xB4, // mov [ebp-4C],edx
0x83, 0xC0, 0x01, // add eax,01
0x89, 0x45, 0xC0 // mov [ebp-40],eax << hook here
};
enum { addr_offset = sizeof(bytes) - 3 };
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
ConsoleOutput("vnreng:PONScripterEng: pattern not found");
return false;
}
HookParam hp = {};
hp.address = addr + addr_offset;
hp.offset = pusha_eax_off -4;
hp.index = 0;
hp.codepage = 65001;
hp.type = USING_STRING;
hp.filter_fun = PONScripterFilter;
ConsoleOutput("vnreng: INSERT PONScripterEng");
NewHook(hp, "PONScripterEng");
return true;
}
bool InsertPONScripterJapHook()
{
//by Blu3train
/*
* Sample games:
* https://vndb.org/v24770
*/
const BYTE bytes[] = {
0x8D, 0x87, XX4, // lea eax,[edi+00000198] << hook here
0x8B, 0x0D, XX4, // mov ecx,[ciconia_phase1.exe+3D82C0]
0x89, 0x55, 0xB4, // mov [ebp-4C],edx
0xC6, 0x45, 0xAE, 0x00, // mov byte ptr [ebp-52],00
0x89, 0x45, 0xA4, // mov [ebp-5C],eax
0x8B, 0x01, // mov eax,[ecx]
0x8B, 0x75, 0xB4 // mov esi,[ebp-4C]
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
ConsoleOutput("vnreng:PONScripterJap: pattern not found");
return false;
}
HookParam hp = {};
hp.address = addr;
hp.offset = pusha_edx_off -4;
hp.index = 0;
hp.codepage = 65001;
hp.type = USING_STRING;
hp.filter_fun = PONScripterFilter;
ConsoleOutput("vnreng: INSERT PONScripterJap");
NewHook(hp, "PONScripterJap");
return true;
}
bool InsertPONScripterHooks()
{
bool ok = InsertPONScripterEngHook() && InsertPONScripterJapHook();
return ok || InsertPONScripterHook(); // If a language hook is missing, the original code is executed
}
/** jichi 7/6/2014 NeXAS
* Sample game: BALDRSKYZERO EXTREME
*

View File

@ -128,7 +128,7 @@ bool InsertNitroplusHook(); // Nitroplus: *.npa
bool InsertTokyoNecroHook(); // Nitroplus TokyoNecro: *.npk, resource string
bool InsertPalHook(); // AMUSE CRAFT: *.pac
bool InsertPensilHook(); // Pensil: PSetup.exe
bool InsertPONScripterHook();
bool InsertPONScripterHooks();
bool InsertQLIEHook(); // QLiE: GameData/*.pack
//bool InsertRai7Hook(); // Rai7puk: rai7.exe
bool InsertRejetHook(); // Rejet: Module/{gd.dat,pf.dat,sd.dat}

View File

@ -90,7 +90,7 @@ bool DetermineEngineByFile1()
{
if (Util::SearchResourceString(L"Proportional ONScripter") || Util::SearchResourceString(L"ponscr.exe"))
{
InsertPONScripterHook();
InsertPONScripterHooks();
return true;
}
// Artikash 7/14/2018: AIRNovel - sample game https://vndb.org/v18814