caramelbox

This commit is contained in:
恍兮惚兮 2024-09-15 21:37:47 +08:00
parent c68e64538e
commit 4fc9e5232e

View File

@ -68,12 +68,12 @@
static bool _yk2garbage(const char *p)
{
// Q_ASSERT(p);
while (char ch = *p++) {
while (char ch = *p++)
{
if (!(
ch >= '0' && ch <= '9' ||
ch >= 'A' && ch <= 'z' || // also ignore ASCII 91-96: [ \ ] ^ _ `
ch == '"' || ch == '.' || ch == '-' || ch == '#'
))
ch == '"' || ch == '.' || ch == '-' || ch == '#'))
return false;
}
return true;
@ -86,7 +86,8 @@ static void SpecialHookYukaSystem2(hook_stack* stack, HookParam *hp, uintptr_t
arg3 = stack->stack[3]; // [esp+0xc]
// arg4 = argof(4, esp_base); // there is no arg4. arg4 is properlly a function pointer
LPCSTR text = (LPCSTR)arg2;
if (*text && !_yk2garbage(text)) { // I am sure this could be null
if (*text && !_yk2garbage(text))
{ // I am sure this could be null
*data = (DWORD)text;
*len = ::strlen(text); // UTF-8 is null-terminated
if (arg3)
@ -94,7 +95,6 @@ static void SpecialHookYukaSystem2(hook_stack* stack, HookParam *hp, uintptr_t
}
}
bool InsertYukaSystem2Hook()
{
const BYTE bytes[] = {
@ -111,35 +111,39 @@ bool InsertYukaSystem2Hook()
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
// GROWL_DWORD(addr); // supposed to be 0x4010e0
if (!addr) {
ConsoleOutput("YukaSystem2: pattern not found");
if (!addr)
return false;
}
HookParam hp;
hp.address = addr;
hp.offset = get_stack(1);
hp.split = get_stack(2);
hp.type = USING_SPLIT | USING_STRING | CODEC_UTF8; // UTF-8, though
hp.filter_fun=[](void* data, size_t* len, HookParam* hp){
hp.filter_fun = [](void *data, size_t *len, HookParam *hp)
{
// セミラミスの天秤
// セミラミスの天秤 Fated Dolls
if(data==0)return false;
if (data == 0)
return false;
if(all_ascii(reinterpret_cast<char*>(data),*len))return false;
if (all_ascii(reinterpret_cast<char *>(data), *len))
return false;
auto str = std::string(reinterpret_cast<char *>(data), *len);
str = std::regex_replace(str, std::regex(R"(@r\((.*?),(.*?)\))"), "$1");
auto wstr = StringToWideString(str);
if(wstr.size()==1)return false;
if (wstr.size() == 1)
return false;
for(auto wc:wstr){
for (auto wc : wstr)
{
if ((wc >= 'A' && wc <= 'z') ||
(wc >= '0' && wc <= '9') ||
(wc == '"') || (wc == '.') || (wc == '-') || (wc == '#') ||
(wc==65533)||(wc==2))return false;
(wc == 65533) || (wc == 2))
return false;
}
return write_string_overwrite(data, len, str);
@ -148,8 +152,10 @@ bool InsertYukaSystem2Hook()
ConsoleOutput("INSERT YukaSystem2");
return NewHook(hp, "YukaSystem2");
}
namespace{
bool hook2(){
namespace
{
bool hook2()
{
// 君を仰ぎ乙女は姫に
// ずっとつくしてあげるの!
const BYTE bytes[] = {
@ -163,15 +169,16 @@ namespace{
0x0F, 0xB6, 0x41, 0x01,
0x83, 0xC1, 0x01,
0x83, 0xE8, 0x66,
0x74,XX
};
0x74, XX};
// enum { addr_offset = 0 };
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
// GROWL_DWORD(addr); // supposed to be 0x4010e0
if (!addr) return false;
if (!addr)
return false;
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (!addr) return false;
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset = get_stack(2);
@ -181,19 +188,22 @@ namespace{
return NewHook(hp, "YukaSystem2");
}
}
namespace __{
namespace __
{
bool YukaSystem1Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
if (*len == 0) return false;
if (*len == 0)
return false;
// if acii add a space at the end of the sentence overwriting null terminator
if (*len >= 2 && text[*len - 2] > 0)
text[(*len)++] = ' ';
if (cpp_strnstr(text, "@r(", *len)) {
if (cpp_strnstr(text, "@r(", *len))
{
StringFilterBetween(text, len, "@r(", 3, ")", 1); // @r(2,はと)
}
@ -215,7 +225,8 @@ bool InsertYukaSystem1Hook()
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("YukaSystem1: pattern not found");
return false;
}
@ -229,8 +240,61 @@ bool InsertYukaSystem1Hook()
return NewHook(hp, "YukaSystem1");
}
}
namespace
{
bool h1()
{
// https://vndb.org/v540
// シャマナシャマナ~月とこころと太陽の魔法~
auto addr = Util::FindImportEntry(processStartAddress, (DWORD)IsDBCSLeadByteEx);
if (!addr)
return false;
const BYTE bytes[] = {
0xff, 0x15, XX4,
0x83, 0xf8, 0x01,
0x0f, 0x85, XX4,
0x33, 0xd2,
0xb9, 0x02, 0x00, 0x00, 0x00,
0xbf, XX4,
0x8b, 0xf3,
0x33, 0xc0,
0xf3, 0xa6,
0x74, XX,
0xb8, XX4,
0x8a, 0x48, 0x02,
0x83, 0xc0, 0x02,
0x83, 0xc2, 0x02,
0x84, 0xc9,
0x74, XX,
0xb9, 0x02, 0x00, 0x00, 0x00,
0x8b, 0xf8,
0x8b, 0xf3,
0x33, 0xed,
0xf3, 0xa6};
memcpy((void *)(bytes + 2), &addr, 4);
addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;
addr = MemDbg::findEnclosingAlignedFunction(addr, 0x100);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset = get_stack(2);
hp.type = USING_CHAR | DATA_INDIRECT;
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
CharFilter(text, len, '@');
bool YukaSystem2::attach_function() {
bool _1=__::InsertYukaSystem1Hook();
return true;
};
return NewHook(hp, "caramelbox");
}
}
bool YukaSystem2::attach_function()
{
bool _1 = h1() || __::InsertYukaSystem1Hook();
return InsertYukaSystem2Hook() || hook2() || _1;
}