LunaHook-mirror/LunaHook/engine32/IGScript.cpp
2024-02-07 20:59:24 +08:00

172 lines
5.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}