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

View File

@ -1,14 +1,15 @@
#include"Siglus.h"
namespace { // unnamed
#include "Siglus.h"
namespace
{ // unnamed
/**
/**
* jichi 8/17/2013: SiglusEngine from siglusengine.exe
* The old hook does not work for new games.
* The new hook cannot recognize character names.
* Insert old first. As the pattern could also be found in the old engine.
*/
/** jichi 10/25/2014: new SiglusEngine3 that can extract character name
/** jichi 10/25/2014: new SiglusEngine3 that can extract character name
*
* Sample game: <EFBFBD><EFBFBD> -- /HW-4@F67DC:SiglusEngine.exe
* The character is in [edx+ecx*2]. Text in edx, and offset in ecx.
@ -70,43 +71,47 @@ namespace { // unnamed
* Target address (edx) is at [[ecx]] when enter function.
*/
// jichi: 8/17/2013: Change return type to bool
bool InsertSiglus3Hook()
{
// jichi: 8/17/2013: Change return type to bool
bool InsertSiglus3Hook()
{
const BYTE bytes[] = {
0x8b,0x12, // 002667d3 8b12 mov edx,dword ptr ds:[edx]
0x8b,0x4d, 0x08, // 002667d5 8b4d 08 mov ecx,dword ptr ss:[ebp+0x8]
0x66,0x8b,0x45, 0x10, // 002667d8 66:8b45 10 mov ax,word ptr ss:[ebp+0x10]
0x66,0x89,0x04,0x4a // 002667dc 66:89044a mov word ptr ds:[edx+ecx*2],ax ; jichi: wchar_t in ax
0x8b, 0x12, // 002667d3 8b12 mov edx,dword ptr ds:[edx]
0x8b, 0x4d, 0x08, // 002667d5 8b4d 08 mov ecx,dword ptr ss:[ebp+0x8]
0x66, 0x8b, 0x45, 0x10, // 002667d8 66:8b45 10 mov ax,word ptr ss:[ebp+0x10]
0x66, 0x89, 0x04, 0x4a // 002667dc 66:89044a mov word ptr ds:[edx+ecx*2],ax ; jichi: wchar_t in ax
// 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) {
//ConsoleOutput("Unknown SiglusEngine");
if (!addr)
{
// ConsoleOutput("Unknown SiglusEngine");
ConsoleOutput("Siglus3: pattern not found");
return false;
}
//addr = MemDbg::findEnclosingAlignedFunction(addr, 50); // 0x002667dc - 0x002667c0 = 28
//if (!addr) {
// addr = MemDbg::findEnclosingAlignedFunction(addr, 50); // 0x002667dc - 0x002667c0 = 28
// if (!addr) {
// ConsoleOutput("Siglus3: enclosing function not found");
// return false;
//}
// }
HookParam hp;
hp.address = addr + addr_offset;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.type = CODEC_UTF16;
//hp.text_fun = SpecialHookSiglus3;
// hp.text_fun = SpecialHookSiglus3;
ConsoleOutput("INSERT Siglus3");
return NewHook(hp, "SiglusEngine3");
}
}
/** SiglusEngine4 5/23/2015
/** SiglusEngine4 5/23/2015
* Sample game: AngleBeats trial
* Alternative ATcode from EGDB:
* UNIKOFILTER(30),FORCEFONT(5),HOOK(SiglusEngine.exe!0x0018CF39,TRANS(EAX,UNICODE,SMSTR,ADDNULL),RETNPOS(SOURCE))
@ -159,24 +164,24 @@ bool InsertSiglus3Hook()
* 0042CF76 CC INT3
* 0042CF77 CC INT3
*/
bool Siglus4Filter(LPVOID data, size_t *size, HookParam *)
{
bool Siglus4Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPWSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
// Remove "NNLI"
//if (*len > 2 && ::all_ascii(text))
// if (*len > 2 && ::all_ascii(text))
// return false;
//if (*len == 2 && *text == L'N')
// if (*len == 2 && *text == L'N')
// return false;
StringFilter(text, len, L"NLI", 3);
// Replace 『<>(300e, 300f) with 「<>(300c,300d)
//CharReplacer(text, len, 0x300e, 0x300c);
//CharReplacer(text, len, 0x300f, 0x300d);
// CharReplacer(text, len, 0x300e, 0x300c);
// CharReplacer(text, len, 0x300f, 0x300d);
return true;
}
void SpecialHookSiglus4(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len)
{
//static uint64_t lastTextHash_;
}
void SpecialHookSiglus4(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
// static uint64_t lastTextHash_;
DWORD eax = stack->eax; // text
if (!eax || !*(const BYTE *)eax) // empty data
return;
@ -193,11 +198,11 @@ void SpecialHookSiglus4(hook_stack* stack, HookParam *hp, uintptr_t *data, uint
return;
// Avoid duplication
//LPCWSTR text = (LPCWSTR)*data;
//auto hash = hashstr(text);
//if (hash == lastTextHash_)
// LPCWSTR text = (LPCWSTR)*data;
// auto hash = hashstr(text);
// if (hash == lastTextHash_)
// return;
//lastTextHash_ = hash;
// lastTextHash_ = hash;
*len = size * 2; // UTF-16
DWORD s0 = stack->retaddr; // use stack[0] as split
@ -205,52 +210,57 @@ 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;
}
*split += stack->stack[1]; // plus stack[1] as split
}
bool InsertSiglus4Hook()
{
}
bool InsertSiglus4Hook()
{
const BYTE bytes[] = {
0xc7,0x47, 0x14, 0x07,0x00,0x00,0x00, // 0042cf20 c747 14 07000000 mov dword ptr ds:[edi+0x14],0x7
0xc7,0x47, 0x10, 0x00,0x00,0x00,0x00, // 0042cf27 c747 10 00000000 mov dword ptr ds:[edi+0x10],0x0
0x66,0x89,0x0f, // 0042cf2e 66:890f mov word ptr ds:[edi],cx
0x8b,0xcf, // 0042cf31 8bcf mov ecx,edi
0xc7, 0x47, 0x14, 0x07, 0x00, 0x00, 0x00, // 0042cf20 c747 14 07000000 mov dword ptr ds:[edi+0x14],0x7
0xc7, 0x47, 0x10, 0x00, 0x00, 0x00, 0x00, // 0042cf27 c747 10 00000000 mov dword ptr ds:[edi+0x10],0x0
0x66, 0x89, 0x0f, // 0042cf2e 66:890f mov word ptr ds:[edi],cx
0x8b, 0xcf, // 0042cf31 8bcf mov ecx,edi
0x50, // 0042cf33 50 push eax
0xe8 //XX4 // 0042cf34 e8 e725f6ff call .0038f520
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) {
//ConsoleOutput("Unknown SiglusEngine");
// ULONG addr = processStartAddress + 0x0018cf39;
if (!addr)
{
// ConsoleOutput("Unknown SiglusEngine");
ConsoleOutput("Siglus4: pattern not found");
return false;
}
//addr = MemDbg::findEnclosingAlignedFunction(addr, 50); // 0x002667dc - 0x002667c0 = 28
//if (!addr) {
// addr = MemDbg::findEnclosingAlignedFunction(addr, 50); // 0x002667dc - 0x002667c0 = 28
// if (!addr) {
// ConsoleOutput("Siglus3: enclosing function not found");
// return false;
//}
// }
HookParam hp;
hp.address = addr + addr_offset;
hp.type = NO_CONTEXT|CODEC_UTF16;
hp.type = NO_CONTEXT | CODEC_UTF16;
hp.text_fun = SpecialHookSiglus4;
hp.filter_fun = Siglus4Filter;
//hp.offset=get_reg(regs::eax);
//hp.type = CODEC_UTF16|DATA_INDIRECT|USING_SPLIT|NO_CONTEXT;
//hp.type = CODEC_UTF16|USING_SPLIT|NO_CONTEXT;
// hp.offset=get_reg(regs::eax);
// hp.type = CODEC_UTF16|DATA_INDIRECT|USING_SPLIT|NO_CONTEXT;
// hp.type = CODEC_UTF16|USING_SPLIT|NO_CONTEXT;
ConsoleOutput("INSERT Siglus4");
return NewHook(hp, "SiglusEngine4");
}
}
#if 0 // not all text can be extracted
/** jichi: 6/16/2015 Siglus4Engine for Frill games
@ -443,8 +453,7 @@ bool InsertSiglus4Hook()
}
#endif // 0
/**
/**
* jichi 8/16/2013: Insert new siglus hook
* See (CaoNiMaGeBi): http://tieba.baidu.com/p/2531786952
* Issue: floating text
@ -1507,76 +1516,81 @@ bool InsertSiglus4Hook()
* 00B6BD17 74 10 JE SHORT .00B6BD29
* 00B6BD19 56 PUSH ESI
*/
bool InsertSiglus2Hook()
{
//const BYTE bytes[] = { // size = 14
bool InsertSiglus2Hook()
{
// const BYTE bytes[] = { // size = 14
// 0x01,0x53, 0x58, // 0153 58 add dword ptr ds:[ebx+58],edx
// 0x8b,0x95, 0x34,0xfd,0xff,0xff, // 8b95 34fdffff mov edx,dword ptr ss:[ebp-2cc]
// 0x8b,0x43, 0x58, // 8b43 58 mov eax,dword ptr ds:[ebx+58]
// 0x3b,0xd7 // 3bd7 cmp edx,edi ; hook here
//};
//enum { cur_ins_size = 2 };
//enum { addr_offset = sizeof(bytes) - cur_ins_size }; // = 14 - 2 = 12, current inst is the last one
// };
// enum { cur_ins_size = 2 };
// enum { addr_offset = sizeof(bytes) - cur_ins_size }; // = 14 - 2 = 12, current inst is the last one
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr;
{ // type 1
const BYTE bytes[] = {
0x3b,0xd7, // cmp edx,edi ; hook here
0x75,0x4b // jnz short
0x3b, 0xd7, // cmp edx,edi ; hook here
0x75, 0x4b // jnz short
};
//enum { addr_offset = 0 };
// enum { addr_offset = 0 };
addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
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
0x81, 0xfe, 0x0c, 0x30, 0x00, 0x00 // 0114124a 81fe 0c300000 cmp esi,0x300c ; jichi: hook here
};
//enum { addr_offset = 0 };
// enum { addr_offset = 0 };
addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (addr)
ConsoleOutput("Siglus2: type 2 pattern found");
}
if (!addr) {
if (!addr)
{
ConsoleOutput("Siglus2: both type1 and type2 patterns not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::esi);
hp.type = CODEC_UTF16|FIXING_SPLIT; // jichi 6/1/2014: fixing the split value
hp.offset = get_reg(regs::esi);
hp.type = CODEC_UTF16 | FIXING_SPLIT; // jichi 6/1/2014: fixing the split value
ConsoleOutput("INSERT Siglus2");
return NewHook(hp, "SiglusEngine2");
}
static void SpecialHookSiglus1(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len)
{
//写回有乱码
auto textu=(TextUnionW*)(stack->ecx+4);
*len=textu->size*2;
*data=(DWORD)textu->getText();
}
}
static void SpecialHookSiglus1(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
// 写回有乱码
auto textu = (TextUnionW *)(stack->ecx + 4);
*len = textu->size * 2;
*data = (DWORD)textu->getText();
}
// jichi: 8/17/2013: Change return type to bool
bool InsertSiglus1Hook()
{
const BYTE bytes[] = {0x33,0xc0,0x8b,0xf9,0x89,0x7c,0x24};
// jichi: 8/17/2013: Change return type to bool
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
//ConsoleOutput("Unknown SiglusEngine");
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;
@ -1588,7 +1602,7 @@ bool InsertSiglus1Hook()
}
ConsoleOutput("Siglus: failed");
return false;
}
}
} // unnamed namespace
@ -1602,24 +1616,28 @@ bool InsertSiglusHook()
ok = InsertSiglus4Hook() || ok;
return ok;
}
bool InsertSiglusHookZ() {
bool InsertSiglusHookZ()
{
BYTE bytes[] = {
0x8b,0x12,
0x66,0x89,0x04,0x72
};
0x8b, 0x12,
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.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:
@ -1692,21 +1712,23 @@ enum Type {
*
* 0025ee60 01 00 00 00 01 00 00 00 ......
*/
ULONG search(ULONG startAddress, ULONG stopAddress, Type *type)
{
ULONG search(ULONG startAddress, ULONG stopAddress, Type *type)
{
ULONG addr;
{
const uint8_t bytes1[] = {
0x3b,0xd7, // 013baf32 |. 3bd7 |cmp edx,edi ; jichi: ITH hook here, char saved in edi
0x75,0x4b // 013baf34 |. 75 4b |jnz short siglusen.013baf81
0x3b, 0xd7, // 013baf32 |. 3bd7 |cmp edx,edi ; jichi: ITH hook here, char saved in edi
0x75, 0x4b // 013baf34 |. 75 4b |jnz short siglusen.013baf81
};
addr = MemDbg::findBytes(bytes1, sizeof(bytes1), startAddress, stopAddress);
if (addr && type)
*type = Type1;
}
if (!addr) {
const uint8_t bytes2[] = { // 81fe0c300000
0x81,0xfe, 0x0c,0x30,0x00,0x00 // 0114124a 81fe 0c300000 cmp esi,0x300c ; jichi: hook here
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);
if (addr && type)
@ -1717,64 +1739,70 @@ ULONG search(ULONG startAddress, ULONG stopAddress, Type *type)
const uint8_t bytes[] = {
0x55, // 013bac70 /$ 55 push ebp ; jichi: function starts
0x8b,0xec, // 013bac71 |. 8bec mov ebp,esp
0x6a,0xff // 013bac73 |. 6a ff push -0x1
0x8b, 0xec, // 013bac71 |. 8bec mov ebp,esp
0x6a, 0xff // 013bac73 |. 6a ff push -0x1
};
//enum { range = 0x300 }; // 0x013baf32 - 0x013bac70 = 706 = 0x2c2
//enum { range = 0x400 }; // 0x013baf32 - 0x013bac70 = 0x36a
enum { range = 0x500 }; // 0x00b6bcf8 - 0x00b6b880 = 0x478
// enum { range = 0x300 }; // 0x013baf32 - 0x013bac70 = 706 = 0x2c2
// enum { range = 0x400 }; // 0x013baf32 - 0x013bac70 = 0x36a
enum
{
range = 0x500
}; // 0x00b6bcf8 - 0x00b6b880 = 0x478
return MemDbg::findBytes(bytes, sizeof(bytes), addr - range, addr);
//if (!reladdr)
// if (!reladdr)
// //ConsoleOutput("Siglus2: pattern not found");
// return 0;
//addr += reladdr;
//return addr;
}
// addr += reladdr;
// 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]);
auto arg = (TextUnionW *)(type_ == Type1 ? s->ecx : s->stack[1]);
if (!arg || !arg->isValid())
return false;
write_string_overwrite(data,len,std::wstring(arg->getText(),arg->size));
write_string_overwrite(data, len, std::wstring(arg->getText(), arg->size));
return true;
}
void hookafter(hook_stack*s,void* data, size_t len){
auto arg = (TextUnionW *)(type_ == Type1 ? s->ecx :s->stack[1]);
}
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;
}
}
bool attach(ULONG startAddress, ULONG stopAddress) // attach scenario
{
}
}
bool attach(ULONG startAddress, ULONG stopAddress) // attach scenario
{
ULONG addr = Private::search(startAddress, stopAddress, &Private::type_);
ConsoleOutput("%p",addr);
ConsoleOutput("%p", addr);
if (!addr)
return false;
//return Private::oldHookFun = (Private::hook_fun_t)winhook::replace_fun(addr, (ULONG)Private::newHookFun);
// return Private::oldHookFun = (Private::hook_fun_t)winhook::replace_fun(addr, (ULONG)Private::newHookFun);
HookParam hp;
hp.address = addr ;
hp.type = EMBED_ABLE|CODEC_UTF16 ; // 0x41
hp.hook_before=Private::text_fun;
hp.hook_after=Private::hookafter;
hp.hook_font=F_GetGlyphOutlineW;
hp.address = addr;
hp.type = EMBED_ABLE | CODEC_UTF16; // 0x41
hp.hook_before = Private::text_fun;
hp.hook_after = Private::hookafter;
hp.hook_font = F_GetGlyphOutlineW;
return NewHook(hp, "EmbedSiglus");
}
}
}
}
namespace OtherHook {
namespace Private {
namespace OtherHook
{
namespace Private
{
TextUnionW *arg_,
argValue_;
bool hookBefore(hook_stack*s,void* data, size_t* len,uintptr_t*role)
bool hookBefore(hook_stack *s, void *data, size_t *len, uintptr_t *role)
{
static std::wstring text_;
auto arg = (TextUnionW *)s->stack[0];
@ -1788,31 +1816,35 @@ namespace Private {
*role = Engine::OtherRole;
ULONG split = s->stack[3];
if (split <= 0xffff || !Engine::isAddressReadable(split)) { // skip modifying scenario thread
//role = Engine::ScenarioRole;
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;
}
}
//auto sig = Engine::hashThreadSignature(role, split);
// auto sig = Engine::hashThreadSignature(role, split);
std::wstring oldText = std::wstring(text, arg->size);//,
write_string_overwrite(data,len,oldText);
std::wstring oldText = std::wstring(text, arg->size); //,
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;
static std::wstring text_;
auto newText=std::wstring((LPWSTR)data,len/2);
auto newText = std::wstring((LPWSTR)data, len / 2);
text_ = newText;
arg->setLongText(text_);
}
@ -1820,42 +1852,48 @@ namespace Private {
ULONG search(ULONG startAddress, ULONG stopAddress)
{
const uint8_t bytes[] = {
0xc7,0x47, 0x14, 0x07,0x00,0x00,0x00, // 0042cf20 c747 14 07000000 mov dword ptr ds:[edi+0x14],0x7
0xc7,0x47, 0x10, 0x00,0x00,0x00,0x00, // 0042cf27 c747 10 00000000 mov dword ptr ds:[edi+0x10],0x0
0x66,0x89,0x0f, // 0042cf2e 66:890f mov word ptr ds:[edi],cx
0x8b,0xcf, // 0042cf31 8bcf mov ecx,edi
0xc7, 0x47, 0x14, 0x07, 0x00, 0x00, 0x00, // 0042cf20 c747 14 07000000 mov dword ptr ds:[edi+0x14],0x7
0xc7, 0x47, 0x10, 0x00, 0x00, 0x00, 0x00, // 0042cf27 c747 10 00000000 mov dword ptr ds:[edi+0x10],0x0
0x66, 0x89, 0x0f, // 0042cf2e 66:890f mov word ptr ds:[edi],cx
0x8b, 0xcf, // 0042cf31 8bcf mov ecx,edi
0x50, // 0042cf33 50 push eax
0xe8 //XX4 // 0042cf34 e8 e725f6ff call .0038f520 ; jichi: hook here
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;
return addr + addr_offset;
}
} // namespace Private
} // namespace Private
bool attach(ULONG startAddress, ULONG stopAddress)
{
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
hp.hook_before=Private::hookBefore;
hp.hook_after=Private::hookafter2;
hp.hook_font=F_GetGlyphOutlineW;
hp.address = addr;
hp.type = EMBED_ABLE | CODEC_UTF16; // 0x41
hp.hook_before = Private::hookBefore;
hp.hook_after = Private::hookafter2;
hp.hook_font = F_GetGlyphOutlineW;
return NewHook(hp, "EmbedSiglus");
}
}
} // namespace OtherHook
bool Siglus::attach_function() {
bool Siglus::attach_function()
{
bool b3=ScenarioHook:: attach(processStartAddress, processStopAddress);
if(b3)OtherHook::attach(processStartAddress, processStopAddress);
bool b1= InsertSiglusHook();
bool b2=InsertSiglusHookZ();
return b1||b2||b3;
bool b3 = ScenarioHook::attach(processStartAddress, processStopAddress);
if (b3)
OtherHook::attach(processStartAddress, processStopAddress);
bool b1 = InsertSiglusHook();
bool b2 = InsertSiglusHookZ();
return b1 || b2 || b3;
}