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

123 lines
3.3 KiB
C++

#include"CaramelBox.h"
static void SpecialHookCaramelBox(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
DWORD reg_ecx = *(DWORD*)(stack->base + hp->offset);
BYTE *ptr = (BYTE *)reg_ecx;
buffer_index = 0;
while (ptr[0])
if (ptr[0] == 0x28) { // Furigana format: (Kanji,Furi)
ptr++;
while (ptr[0]!=0x2c) //Copy Kanji
text_buffer[buffer_index++] = *ptr++;
while (ptr[0]!=0x29) // Skip Furi
ptr++;
ptr++;
} else if (ptr[0] == 0x5c)
ptr +=2;
else {
text_buffer[buffer_index++] = ptr[0];
if (LeadByteTable[ptr[0]] == 2) {
ptr++;
text_buffer[buffer_index++] = ptr[0];
}
ptr++;
}
*len = buffer_index;
*data = (DWORD)text_buffer;
*split = 0; // 8/3/2014 jichi: use return address as split
}
// jichi 10/1/2013: Change return type to bool
bool InsertCaramelBoxHook()
{
union { DWORD i; BYTE* pb; WORD* pw; DWORD *pd; };
DWORD reg = -1;
for (i = processStartAddress + 0x1000; i < processStopAddress - 4; i++) {
if (*pd == 0x7ff3d) // cmp eax, 7ff
reg = 0;
else if ((*pd & 0xfffff8fc) == 0x07fff880) // cmp reg, 7ff
reg = pb[1] & 0x7;
if (reg == -1)
continue;
DWORD flag = 0;
if (*(pb - 6) == 3) { //add reg, [ebp+$disp_32]
if (*(pb - 5) == (0x85 | (reg << 3)))
flag = 1;
} else if (*(pb - 3) == 3) { // add reg, [ebp+$disp_8]
if (*(pb - 2) == (0x45 | (reg << 3)))
flag = 1;
} else if (*(pb - 2) == 3) { // add reg, reg
if (((*(pb - 1) >> 3) & 7)== reg)
flag = 1;
}
reg = -1;
if (flag) {
for (DWORD j = i, k = i - 0x100; j > k; j--) {
if ((*(DWORD *)j & 0xffff00ff) == 0x1000b8) { // mov eax,10??
HookParam hp;
hp.address = j & ~0xf;
hp.text_fun = SpecialHookCaramelBox;
hp.type = USING_STRING;
for (i &= ~0xffff; i < processStopAddress - 4; i++)
if (pb[0] == 0xe8) {
pb++;
if (pd[0] + i + 4 == hp.address) {
pb += 4;
if ((pd[0] & 0xffffff) == 0x04c483)
hp.offset=get_stack(1);
else hp.offset=get_reg(regs::ecx);
break;
}
}
if (hp.offset == 0) {
ConsoleOutput("CaramelBox: failed, zero off");
return false;
}
ConsoleOutput("INSERT CaramelBox");
//RegisterEngineType(ENGINE_CARAMEL);
return NewHook(hp, "CaramelBox");
}
}
}
}
ConsoleOutput("CaramelBox: failed");
return false;
//_unknown_engine:
//ConsoleOutput("Unknown CarmelBox engine.");
}
bool CaramelBox::attach_function() {
return InsertCaramelBoxHook();
}
bool CaramelBoxMilkAji::attach_function(){
//雨芳恋歌
//https://vndb.org/v6663
BYTE bytes[] = {
0x33,0xD2,
0xB9,0x8A,0x02,0x00,0x00,
0xF7,0xF1,
0x6B,0xC0,0x44,
0x6B,0xC0,0x03
};
auto addr=MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if(addr==0)return false;
addr=MemDbg::findEnclosingAlignedFunction(addr);
if(addr==0)return false;
HookParam hp;
hp.address = addr;
hp.type = USING_STRING;
hp.offset=get_stack(1);
return NewHook(hp, "CaramelBox");
}