This commit is contained in:
恍兮惚兮 2024-10-11 19:55:15 +08:00
parent a963692d02
commit 12a6f74624

View File

@ -1,5 +1,6 @@
#include "Siglus.h"
namespace { // unnamed
namespace
{ // unnamed
/**
* jichi 8/17/2013: SiglusEngine from siglusengine.exe
@ -81,10 +82,14 @@ bool InsertSiglus3Hook()
// 002667e0 5d pop ebp
// 002667e1 c2 0c00 retn 0xc
};
enum { addr_offset = sizeof(bytes) - 4 };
enum
{
addr_offset = sizeof(bytes) - 4
};
ULONG range = max(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
// ConsoleOutput("Unknown SiglusEngine");
ConsoleOutput("Siglus3: pattern not found");
return false;
@ -205,7 +210,8 @@ void SpecialHookSiglus4(hook_stack* stack, HookParam *hp, uintptr_t *data, uint
*split = FIXED_SPLIT_VALUE;
else if (::IsBadReadPtr((LPCVOID)s0, 4))
*split = s0;
else {
else
{
*split = *(DWORD *)s0; // This value is runtime dependent
if (*split == 0x54)
*split = FIXED_SPLIT_VALUE * 2;
@ -223,11 +229,15 @@ bool InsertSiglus4Hook()
0xe8 // XX4 // 0042cf34 e8 e725f6ff call .0038f520
// hook here
};
enum { addr_offset = sizeof(bytes) + 4 }; // +4 for the call address
enum
{
addr_offset = sizeof(bytes) + 4
}; // +4 for the call address
ULONG range = max(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
// ULONG addr = processStartAddress + 0x0018cf39;
if (!addr) {
if (!addr)
{
// ConsoleOutput("Unknown SiglusEngine");
ConsoleOutput("Siglus4: pattern not found");
return false;
@ -443,7 +453,6 @@ bool InsertSiglus4Hook()
}
#endif // 0
/**
* jichi 8/16/2013: Insert new siglus hook
* See (CaoNiMaGeBi): http://tieba.baidu.com/p/2531786952
@ -1530,7 +1539,8 @@ bool InsertSiglus2Hook()
if (addr)
ConsoleOutput("Siglus2: type 1 pattern found");
}
if (!addr) {
if (!addr)
{
// 81fe0c300000
const BYTE bytes[] = {
0x81, 0xfe, 0x0c, 0x30, 0x00, 0x00 // 0114124a 81fe 0c300000 cmp esi,0x300c ; jichi: hook here
@ -1541,7 +1551,8 @@ bool InsertSiglus2Hook()
ConsoleOutput("Siglus2: type 2 pattern found");
}
if (!addr) {
if (!addr)
{
ConsoleOutput("Siglus2: both type1 and type2 patterns not found");
return false;
}
@ -1568,15 +1579,18 @@ bool InsertSiglus1Hook()
const BYTE bytes[] = {0x33, 0xc0, 0x8b, 0xf9, 0x89, 0x7c, 0x24};
ULONG range = max(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) { // jichi 8/17/2013: Add "== 0" check to prevent breaking new games
if (!addr)
{ // jichi 8/17/2013: Add "== 0" check to prevent breaking new games
// ConsoleOutput("Unknown SiglusEngine");
ConsoleOutput("Siglus: pattern not found");
return false;
}
DWORD limit = addr - 0x100;
while (addr > limit) {
if (*(WORD*)addr == 0xff6a) {
while (addr > limit)
{
if (*(WORD *)addr == 0xff6a)
{
HookParam hp;
hp.address = addr;
hp.text_fun = SpecialHookSiglus1;
@ -1602,23 +1616,27 @@ bool InsertSiglusHook()
ok = InsertSiglus4Hook() || ok;
return ok;
}
bool InsertSiglusHookZ() {
bool InsertSiglusHookZ()
{
BYTE bytes[] = {
0x8b, 0x12,
0x66,0x89,0x04,0x72
};
0x66, 0x89, 0x04, 0x72};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
ConsoleOutput("SiglusHookZ %p", addr);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr + 2;
hp.offset = get_reg(regs::eax);
hp.type = CODEC_UTF16;
return NewHook(hp, "SiglusHookZ");
}
namespace{
namespace ScenarioHook {
namespace Private {
namespace
{
namespace ScenarioHook
{
namespace Private
{
/**
* jichi 8/16/2013: Insert new siglus hook
* See (CaoNiMaGeBi): http://tieba.baidu.com/p/2531786952
@ -1643,9 +1661,11 @@ namespace Private {
* 013baf32 |. 3bd7 |cmp edx,edi ; jichi: ITH hook here, char saved in edi
* 013baf34 |. 75 4b |jnz short siglusen.013baf81
*/
enum Type {
enum Type
{
Type1 // Old SiglusEngine2, arg in ecx
, Type2 // New SiglusENgine2, arg in arg1, since リア充クラスメイト孕ませ催眠 in 9/26/2014
,
Type2 // New SiglusENgine2, arg in arg1, since リア充クラスメイト孕ませ催眠 in 9/26/2014
} type_; // static
/**
* Sample game:
@ -1704,8 +1724,10 @@ ULONG search(ULONG startAddress, ULONG stopAddress, Type *type)
if (addr && type)
*type = Type1;
}
if (!addr) {
const uint8_t bytes2[] = { // 81fe0c300000
if (!addr)
{
const uint8_t bytes2[] = {
// 81fe0c300000
0x81, 0xfe, 0x0c, 0x30, 0x00, 0x00 // 0114124a 81fe 0c300000 cmp esi,0x300c ; jichi: hook here
};
addr = MemDbg::findBytes(bytes2, sizeof(bytes2), startAddress, stopAddress);
@ -1722,7 +1744,10 @@ ULONG search(ULONG startAddress, ULONG stopAddress, Type *type)
};
// enum { range = 0x300 }; // 0x013baf32 - 0x013bac70 = 706 = 0x2c2
// enum { range = 0x400 }; // 0x013baf32 - 0x013bac70 = 0x36a
enum { range = 0x500 }; // 0x00b6bcf8 - 0x00b6b880 = 0x478
enum
{
range = 0x500
}; // 0x00b6bcf8 - 0x00b6b880 = 0x478
return MemDbg::findBytes(bytes, sizeof(bytes), addr - range, addr);
// if (!reladdr)
// //ConsoleOutput("Siglus2: pattern not found");
@ -1731,7 +1756,8 @@ ULONG search(ULONG startAddress, ULONG stopAddress, Type *type)
// return addr;
}
bool text_fun(hook_stack*s,void* data, size_t* len,uintptr_t*role){
bool text_fun(hook_stack *s, void *data, size_t *len, uintptr_t *role)
{
auto arg = (TextUnionW *)(type_ == Type1 ? s->ecx : s->stack[1]);
if (!arg || !arg->isValid())
@ -1740,12 +1766,12 @@ bool text_fun(hook_stack*s,void* data, size_t* len,uintptr_t*role){
write_string_overwrite(data, len, std::wstring(arg->getText(), arg->size));
return true;
}
void hookafter(hook_stack*s,void* data, size_t len){
void hookafter(hook_stack *s, void *data, size_t len)
{
auto arg = (TextUnionW *)(type_ == Type1 ? s->ecx : s->stack[1]);
auto argValue = *arg;
std::wstring newText=std::wstring((wchar_t*)data,len/2);
arg->setLongText(newText);
auto newText = new std::wstring((wchar_t *)data, len / 2);
arg->setLongText(*newText);
// Restoring is indispensible, and as a result, the default hook does not work
//*arg = argValue;
@ -1769,8 +1795,10 @@ bool attach(ULONG startAddress, ULONG stopAddress) // attach scenario
}
}
namespace OtherHook {
namespace Private {
namespace OtherHook
{
namespace Private
{
TextUnionW *arg_,
argValue_;
@ -1788,12 +1816,16 @@ namespace Private {
*role = Engine::OtherRole;
ULONG split = s->stack[3];
if (split <= 0xffff || !Engine::isAddressReadable(split)) { // skip modifying scenario thread
if (split <= 0xffff || !Engine::isAddressReadable(split))
{ // skip modifying scenario thread
// role = Engine::ScenarioRole;
return true;
} else {
}
else
{
split = *(DWORD *)split;
switch (split) {
switch (split)
{
case 0x54:
case 0x26:
*role = Engine::NameRole;
@ -1805,9 +1837,9 @@ namespace Private {
write_string_overwrite(data, len, oldText);
return true;
// newText = EngineController::instance()->dispatchTextWSTD(oldText, role, sig);
}
void hookafter2(hook_stack*s,void* data, size_t len){
void hookafter2(hook_stack *s, void *data, size_t len)
{
auto arg = (TextUnionW *)s->stack[0];
arg_ = arg;
argValue_ = *arg;
@ -1827,7 +1859,10 @@ namespace Private {
0x50, // 0042cf33 50 push eax
0xe8 // XX4 // 0042cf34 e8 e725f6ff call .0038f520 ; jichi: hook here
};
enum { addr_offset = sizeof(bytes) - 1 }; // +4 for the call address
enum
{
addr_offset = sizeof(bytes) - 1
}; // +4 for the call address
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
if (!addr)
return 0;
@ -1839,7 +1874,8 @@ namespace Private {
bool attach(ULONG startAddress, ULONG stopAddress)
{
ULONG addr = Private::search(startAddress, stopAddress);
if(addr==0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr;
hp.type = EMBED_ABLE | CODEC_UTF16; // 0x41
@ -1851,10 +1887,12 @@ bool attach(ULONG startAddress, ULONG stopAddress)
} // namespace OtherHook
bool Siglus::attach_function() {
bool Siglus::attach_function()
{
bool b3 = ScenarioHook::attach(processStartAddress, processStopAddress);
if(b3)OtherHook::attach(processStartAddress, processStopAddress);
if (b3)
OtherHook::attach(processStartAddress, processStopAddress);
bool b1 = InsertSiglusHook();
bool b2 = InsertSiglusHookZ();
return b1 || b2 || b3;