172 lines
5.1 KiB
C++
Raw Normal View History

2024-02-07 20:59:24 +08:00
#include"IGScript.h"
namespace{
bool LucaSystemFilter1(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
StringFilter(text, len, "\x81\x94", 2);
//秋&冬 官中
StringReplacer(text, len, "\x82\xa1", 2,"\xa3\xac",2);//
StringReplacer(text, len, "\x82\xa3", 2,"\xa1\xa3",2);//。
StringReplacer(text, len, "\x82\xa5", 2,"\xa1\xa2",2);//、
StringReplacer(text, len, "\x83\x48", 2,"\xa1\xb1",2);//”
StringReplacer(text, len, "\x83\x44", 2,"\xa3\xbf",2);//
StringReplacer(text, len, "\x83\x42", 2,"\xa3\xa1",2);//!
StringReplacer(text, len, "\x82\xa7", 2,"\xa1\xb9",2);//」
StringReplacer(text, len, "\x82\xc1", 2,"\xa1\xb7",2);//》
StringReplacer(text, len, "\x83\x46", 2,"\xa1\xaf",2);//
return true;
}
template<int arg>
void SpecialHookigi(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len){
DWORD Src = stack->stack[arg];
DWORD Size = stack->stack[arg+1];
if(strlen((char*)Src)<=2)return;
if(strlen((char*)Src)>=Size)return;
if(strlen((char*)Src)<Size-4)return;
*data = Src;
*len=strlen((char*)Src);
// ConsoleOutput(WideStringToString(StringToWideString((char*)Src,936).value()).c_str());
// std::string xx;
// for(int i=0;i<*len;i++){
// xx+=" "+std::to_string(*(BYTE*)(Src+i));
// }
// ConsoleOutput(xx.c_str());
}
}
bool IGScript1attach_function() {
/*
FLOWERS
* https://vndb.org/v15395
* https://vndb.org/v14267
* https://vndb.org/v18152
* https://vndb.org/r82704
*/
const BYTE bytes[] = {
//memcpy(dst,src,size)
0x81,0xf9,0x00,0x01,0x00,0x00,
0x72,XX,
0x83,0x3d,XX4,0x00,
0x74,XX,
0x57,0x56,
0x83,0xe7,0x0f,
0x83,0xe6,0x0f,
0x3b,0xfe
};
HMODULE module = GetModuleHandleW(L"Script.dll");
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), minAddress, maxAddress);
if (addr == 0)return false;
addr = MemDbg::findEnclosingAlignedFunction(addr,0x100);
if (addr == 0)return false;
HookParam hp;
hp.address = addr;
const BYTE funcstart[] = {
0x55,0x8b,0xec,0x57,0x56
};
bool insertgbk=memcmp(funcstart,(LPVOID*)addr,5)==0;
hp.text_fun=SpecialHookigi<2>;
hp.type=NO_CONTEXT;
//hp.filter_fun=LucaSystemFilter1;
bool succ=NewHook(hp, "IGScript");
if(insertgbk){
hp.address +=5;
hp.text_fun=SpecialHookigi<5>;
//仅官中适用这个过滤器。日语原版不需要过滤
hp.filter_fun=LucaSystemFilter1;
succ|=NewHook(hp, "IGScript_1");
}
return succ;
}
namespace{
bool LucaSystemFilter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
if ( text[0] == '\x81' && text[1] == '\x94')
return false;
StringCharReplacer(text, len, "\x81\x90", 2, ' '); // new line
//replacement from Flowers 4 config.json
CharReplacer(text, len, '\xA5', ' ');
CharReplacer(text, len, '\xA2', '<');
CharReplacer(text, len, '\xA3', '>');
CharReplacer(text, len, '\xA1', '\"');
CharReplacer(text, len, '\xA4', '\'');
CharReplacer(text, len, '\xA7', 'à');
CharReplacer(text, len, '\xA8', 'è');
CharReplacer(text, len, '\xA9', 'é');
CharReplacer(text, len, '\xAA', 'ë');
CharReplacer(text, len, '\xAB', 'ō');
CharReplacer(text, len, '\xB0', '-');
CharReplacer(text, len, '\xBB', ' ');
while(cpp_strnstr(text, " ", *len)) // Erasing all but one whitespace from strings
StringCharReplacer(text, len, " ", 2, ' ');
if (text[0] == ' ')
::memmove(text, text + 1, --*len);
return true;
}
bool InsertLucaSystemHook() {
/*
* Sample games:
* https://vndb.org/v15395
* https://vndb.org/v14267
* https://vndb.org/v18152
* https://vndb.org/r82704
*/
const BYTE bytes[] = {
0xCC, // int 3
0xE9, XX4, // jmp d3d9.dll+1E420
0x56, // push esi
0x57, // push edi
0x8B, 0x7C, 0x24, 0x20, // mov edi,[esp+20]
0x8B, 0xD8, // mov ebx,eax
0x8B, 0x07 // mov eax,[edi]
};
const BYTE bytes2[] = {
0xCC, // int 3
0x83, 0xEC, 0x0C, // sub esp,0C <- hook here
0x53, // push ebx
0x55, // push ebp
0x56 // push esi
};
HMODULE module = GetModuleHandleW(L"Script.dll");
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), minAddress, maxAddress);
if (!addr) {
addr = MemDbg::findBytes(bytes2, sizeof(bytes2), minAddress, maxAddress);
if (!addr) {
ConsoleOutput("LucaSystem: pattern not found");
return false;
}
}
HookParam hp;
hp.address = addr + 1;
hp.offset =get_stack(1);
hp.padding = 0x04;
hp.type = USING_STRING;
hp.filter_fun = LucaSystemFilter;
return NewHook(hp, "LucaSystem");
}
}
bool IGScript::attach_function() {
auto b1= IGScript1attach_function();
b1=InsertLucaSystemHook()||b1;
return b1;
}