This commit is contained in:
恍兮惚兮 2024-07-26 02:38:25 +08:00
parent fe8719cd46
commit ed6e34302e
2 changed files with 170 additions and 130 deletions

View File

@ -1,39 +1,46 @@
#include"Debonosu.h" #include "Debonosu.h"
namespace { // unnamed namespace
int _type; { // unnamed
void SpecialHookDebonosuScenario(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len) int _type;
{ void SpecialHookDebonosuScenario(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
DWORD retn = stack->retaddr; DWORD retn = stack->retaddr;
if (*(WORD *)retn == 0xc483){ // add esp, $ old Debonosu game if (*(WORD *)retn == 0xc483)
{ // add esp, $ old Debonosu game
hp->offset = get_stack(1); hp->offset = get_stack(1);
_type=1; _type = 1;
} }
else{ // new Debonosu game else
{ // new Debonosu game
hp->offset = get_reg(regs::eax); hp->offset = get_reg(regs::eax);
_type=2; _type = 2;
} }
//hp->type ^= EXTERN_HOOK; // hp->type ^= EXTERN_HOOK;
hp->text_fun = nullptr; hp->text_fun = nullptr;
*data = *(DWORD*)(stack->base + hp->offset); *data = *(DWORD *)(stack->base + hp->offset);
*len = ::strlen((char*)*data); *len = ::strlen((char *)*data);
*split = FIXED_SPLIT_VALUE; *split = FIXED_SPLIT_VALUE;
} }
void hook_after(hook_stack*s,void* data, size_t len){ void hook_after(hook_stack *s, void *data, size_t len)
{
static std::string ts; static std::string ts;
ts=std::string((LPSTR)data,len); ts = std::string((LPSTR)data, len);
if(_type==1){ if (_type == 1)
s->stack[1]=(DWORD)ts.c_str(); {
s->stack[1] = (DWORD)ts.c_str();
} }
else{ else
s->ecx=(DWORD)ts.c_str(); {
s->ecx = (DWORD)ts.c_str();
} }
} }
bool InsertDebonosuScenarioHook() bool InsertDebonosuScenarioHook()
{ {
DWORD addr = Util::FindImportEntry(processStartAddress, (DWORD)lstrcatA); DWORD addr = Util::FindImportEntry(processStartAddress, (DWORD)lstrcatA);
if (!addr) { if (!addr)
{
ConsoleOutput("Debonosu: lstrcatA is not called"); ConsoleOutput("Debonosu: lstrcatA is not called");
return false; return false;
} }
@ -42,21 +49,24 @@ bool InsertDebonosuScenarioHook()
for (DWORD i = processStartAddress; i < processStopAddress - 4; i++) for (DWORD i = processStartAddress; i < processStopAddress - 4; i++)
if (*(DWORD *)i == search && if (*(DWORD *)i == search &&
*(WORD *)(i + 4) == addr && // call dword ptr lstrcatA *(WORD *)(i + 4) == addr && // call dword ptr lstrcatA
*(BYTE *)(i - 5) == 0x68) { // push $ *(BYTE *)(i - 5) == 0x68)
{ // push $
DWORD push = *(DWORD *)(i - 4); DWORD push = *(DWORD *)(i - 4);
for (DWORD j = i + 6, k = j + 0x10; j < k; j++) for (DWORD j = i + 6, k = j + 0x10; j < k; j++)
if (*(BYTE *)j == 0xb8 && if (*(BYTE *)j == 0xb8 &&
*(DWORD *)(j + 1) == push) *(DWORD *)(j + 1) == push)
if (DWORD hook_addr = SafeFindEnclosingAlignedFunction(i, 0x200)) { if (DWORD hook_addr = SafeFindEnclosingAlignedFunction(i, 0x200))
{
HookParam hp; HookParam hp;
hp.address = hook_addr; hp.address = hook_addr;
hp.text_fun = SpecialHookDebonosuScenario; hp.text_fun = SpecialHookDebonosuScenario;
//hp.type = USING_STRING; // hp.type = USING_STRING;
hp.hook_after=hook_after; hp.hook_after = hook_after;
hp.hook_font=F_MultiByteToWideChar|F_GetTextExtentPoint32A; hp.hook_font = F_MultiByteToWideChar | F_GetTextExtentPoint32A;
hp.type = USING_STRING|NO_CONTEXT|USING_SPLIT|FIXING_SPLIT|EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_DYNA_SJIS; // there is only one thread hp.type = USING_STRING | NO_CONTEXT | USING_SPLIT | FIXING_SPLIT | EMBED_ABLE | EMBED_BEFORE_SIMPLE | EMBED_DYNA_SJIS; // there is only one thread
hp.filter_fun=[](void* data, size_t* len, HookParam* hp){ hp.filter_fun = [](void *data, size_t *len, HookParam *hp)
return write_string_overwrite(data,len,std::regex_replace(std::string((char*)data,*len), std::regex("\\{(.*?)/(.*?)\\}"), "$1")); {
return write_string_overwrite(data, len, std::regex_replace(std::string((char *)data, *len), std::regex("\\{(.*?)/(.*?)\\}"), "$1"));
}; };
ConsoleOutput("INSERT Debonosu"); ConsoleOutput("INSERT Debonosu");
@ -65,20 +75,20 @@ bool InsertDebonosuScenarioHook()
} }
ConsoleOutput("Debonosu: failed"); ConsoleOutput("Debonosu: failed");
//ConsoleOutput("Unknown Debonosu engine."); // ConsoleOutput("Unknown Debonosu engine.");
return false; return false;
} }
void SpecialHookDebonosuName(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len) void SpecialHookDebonosuName(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{ {
DWORD text = stack->ecx; DWORD text = stack->ecx;
if (!text) if (!text)
return; return;
*data = text; *data = text;
*len = ::strlen((LPCSTR)text); *len = ::strlen((LPCSTR)text);
*split = FIXED_SPLIT_VALUE << 1; *split = FIXED_SPLIT_VALUE << 1;
} }
bool InsertDebonosuNameHook() bool InsertDebonosuNameHook()
{ {
const BYTE bytes[] = { const BYTE bytes[] = {
// 0032f659 32c0 xor al,al // 0032f659 32c0 xor al,al
// 0032f65b 5b pop ebx // 0032f65b 5b pop ebx
@ -86,32 +96,33 @@ bool InsertDebonosuNameHook()
// 0032f65e 5d pop ebp // 0032f65e 5d pop ebp
// 0032f65f c3 retn // 0032f65f c3 retn
0x55, // 0032f660 55 push ebp ; jichi: name text in ecx, which could be zero though 0x55, // 0032f660 55 push ebp ; jichi: name text in ecx, which could be zero though
0x8b,0xec, // 0032f661 8bec mov ebp,esp 0x8b, 0xec, // 0032f661 8bec mov ebp,esp
0x81,0xec, XX4, // 0032f663 81ec 2c080000 sub esp,0x82c 0x81, 0xec, XX4, // 0032f663 81ec 2c080000 sub esp,0x82c
0x8b,0x45, 0x08, // 0032f669 8b45 08 mov eax,dword ptr ss:[ebp+0x8] 0x8b, 0x45, 0x08, // 0032f669 8b45 08 mov eax,dword ptr ss:[ebp+0x8]
0x53, // 0032f66c 53 push ebx 0x53, // 0032f66c 53 push ebx
0x56, // 0032f66d 56 push esi 0x56, // 0032f66d 56 push esi
0x8b,0xf1, // 0032f66e 8bf1 mov esi,ecx 0x8b, 0xf1, // 0032f66e 8bf1 mov esi,ecx
0x85,0xc0, // 0032f670 85c0 test eax,eax 0x85, 0xc0, // 0032f670 85c0 test eax,eax
0x8d,0x4d, 0xf0, // 0032f672 8d4d f0 lea ecx,dword ptr ss:[ebp-0x10] 0x8d, 0x4d, 0xf0, // 0032f672 8d4d f0 lea ecx,dword ptr ss:[ebp-0x10]
0x0f,0x45,0xc8, // 0032f675 0f45c8 cmovne ecx,eax 0x0f, 0x45, 0xc8, // 0032f675 0f45c8 cmovne ecx,eax
0x57 // 0032f678 57 push edi 0x57 // 0032f678 57 push edi
}; };
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr) { if (!addr)
{
ConsoleOutput("DebonosuName: pattern NOT FOUND"); ConsoleOutput("DebonosuName: pattern NOT FOUND");
return false; return false;
} }
HookParam hp; HookParam hp;
hp.address = addr; hp.address = addr;
//hp.text_fun = SpecialHookDebonosuName; // hp.text_fun = SpecialHookDebonosuName;
hp.offset=get_reg(regs::ecx); hp.offset = get_reg(regs::ecx);
//hp.type = USING_STRING; // hp.type = USING_STRING;
hp.type = USING_STRING|NO_CONTEXT|USING_SPLIT|EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_AFTER_NEW; //|FIXING_SPLIT; // there is only one thread hp.type = USING_STRING | NO_CONTEXT | USING_SPLIT | EMBED_ABLE | EMBED_BEFORE_SIMPLE | EMBED_AFTER_NEW; //|FIXING_SPLIT; // there is only one thread
ConsoleOutput("INSERT DebonosuName"); ConsoleOutput("INSERT DebonosuName");
return NewHook(hp, "DebonosuName"); return NewHook(hp, "DebonosuName");
} }
} // unnamed namespace } // unnamed namespace
bool attach(ULONG startAddress, ULONG stopAddress) bool attach(ULONG startAddress, ULONG stopAddress)
@ -119,47 +130,77 @@ bool attach(ULONG startAddress, ULONG stopAddress)
ULONG addr = 0; ULONG addr = 0;
{ {
const char *msg = "D3DFont::Draw"; const char *msg = "D3DFont::Draw";
if (addr = MemDbg::findBytes(msg, ::strlen(msg+1), startAddress, stopAddress)) if (addr = MemDbg::findBytes(msg, ::strlen(msg + 1), startAddress, stopAddress))
addr = MemDbg::findPushAddress(addr, startAddress, stopAddress); addr = MemDbg::findPushAddress(addr, startAddress, stopAddress);
} }
if (!addr) { if (!addr)
{
const uint8_t bytes[] = { const uint8_t bytes[] = {
0x50, // 0010fb80 50 push eax 0x50, // 0010fb80 50 push eax
0xff,0x75, 0x14, // 0010fb81 ff75 14 push dword ptr ss:[ebp+0x14] 0xff, 0x75, 0x14, // 0010fb81 ff75 14 push dword ptr ss:[ebp+0x14]
0x8b,0xce, // 0010fb84 8bce mov ecx,esi 0x8b, 0xce, // 0010fb84 8bce mov ecx,esi
0xff,0x75, 0x10 // 0010fb86 ff75 10 push dword ptr ss:[ebp+0x10] 0xff, 0x75, 0x10 // 0010fb86 ff75 10 push dword ptr ss:[ebp+0x10]
}; };
addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress); addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
} }
if (!addr) { if (!addr)
{
return false; return false;
} }
//addr = MemDbg::findEnclosingAlignedFunction(addr); // This might not work as the address is not always aligned // addr = MemDbg::findEnclosingAlignedFunction(addr); // This might not work as the address is not always aligned
addr = MemDbg::findEnclosingFunctionAfterInt3(addr); addr = MemDbg::findEnclosingFunctionAfterInt3(addr);
if (!addr) { if (!addr)
{
return false; return false;
} }
HookParam hp; HookParam hp;
hp.address = addr; hp.address = addr;
//hp.text_fun = SpecialHookDebonosuName; // hp.text_fun = SpecialHookDebonosuName;
hp.offset=20; hp.offset = 20;
//hp.type = USING_STRING; // hp.type = USING_STRING;
hp.type = USING_STRING|NO_CONTEXT; //|FIXING_SPLIT; // there is only one thread hp.type = USING_STRING | NO_CONTEXT; //|FIXING_SPLIT; // there is only one thread
return NewHook(hp, "Debonosu2"); return NewHook(hp, "Debonosu2");
} }
namespace
{
bool debox()
{
//[240726][1282636][でぼの巣製作所] 神楽漫遊記~桂香と初花~ DL版 (files)
auto lua51 = GetModuleHandle(L"lua5.1.dll");
if (!lua51)
return false;
auto lua_tolstring = (DWORD)GetProcAddress(lua51, "lua_tolstring");
if (!lua_tolstring)
return false;
auto addrs = findiatcallormov_all(lua_tolstring, processStartAddress, processStartAddress, processStopAddress, PAGE_EXECUTE);
auto succ = false;
for (auto addr : addrs)
{
HookParam hp;
hp.address = addr + 6;
hp.type = USING_STRING | NO_CONTEXT;
hp.offset = get_reg(regs::eax);
succ |= NewHook(hp, "debonosu");
}
return succ;
}
}
bool InsertDebonosuHook() bool InsertDebonosuHook()
{ {
bool ok = InsertDebonosuScenarioHook(); bool ok = InsertDebonosuScenarioHook() || debox();
if (ok) if (ok)
InsertDebonosuNameHook(); InsertDebonosuNameHook();
return ok; return ok;
} }
bool Debonosu::attach_function() { bool Debonosu::attach_function()
{
// 1/1/2016 jich: skip izumo4 from studio ego that is not supported by debonosu // 1/1/2016 jich: skip izumo4 from studio ego that is not supported by debonosu
if (Util::CheckFile(L"*izumo4*.exe")) { if (Util::CheckFile(L"*izumo4*.exe"))
{
PcHooks::hookOtherPcFunctions(); PcHooks::hookOtherPcFunctions();
return true; return true;
} }

View File

@ -362,7 +362,6 @@ void TextHook::Send(uintptr_t lpDataBase)
parsenewlineseperator(pbData, &lpCount); parsenewlineseperator(pbData, &lpCount);
bool canembed; bool canembed;
;
if (hp.type & EMBED_ABLE) if (hp.type & EMBED_ABLE)
{ {
if (!checklengthembedable(hp, lpCount)) if (!checklengthembedable(hp, lpCount))