mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-10-22 23:18:16 +08:00
...
This commit is contained in:
parent
a5986fe7dd
commit
44ad71eb81
@ -109,8 +109,8 @@
|
|||||||
* 0012ed64 00951d88 ascii "2015/01/18"
|
* 0012ed64 00951d88 ascii "2015/01/18"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace { // unnamed
|
namespace
|
||||||
|
{ // unnamed
|
||||||
|
|
||||||
void SpecialHookWillPlus(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
void SpecialHookWillPlus(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
||||||
{
|
{
|
||||||
@ -118,14 +118,16 @@ void SpecialHookWillPlus(hook_stack* stack, HookParam *hp, uintptr_t *data, uin
|
|||||||
// if (detect_offset)
|
// if (detect_offset)
|
||||||
// return;
|
// return;
|
||||||
DWORD i, l;
|
DWORD i, l;
|
||||||
union {
|
union
|
||||||
|
{
|
||||||
DWORD retn;
|
DWORD retn;
|
||||||
WORD *pw;
|
WORD *pw;
|
||||||
BYTE *pb;
|
BYTE *pb;
|
||||||
};
|
};
|
||||||
retn = stack->retaddr; // jichi 1/18/2015: dynamically find function return address
|
retn = stack->retaddr; // jichi 1/18/2015: dynamically find function return address
|
||||||
i = 0;
|
i = 0;
|
||||||
while (*pw != 0xc483) { // add esp, $
|
while (*pw != 0xc483)
|
||||||
|
{ // add esp, $
|
||||||
l = ::disasm(pb);
|
l = ::disasm(pb);
|
||||||
if (++i == 5)
|
if (++i == 5)
|
||||||
// ConsoleOutput("Fail to detect offset.");
|
// ConsoleOutput("Fail to detect offset.");
|
||||||
@ -133,7 +135,8 @@ void SpecialHookWillPlus(hook_stack* stack, HookParam *hp, uintptr_t *data, uin
|
|||||||
retn += l;
|
retn += l;
|
||||||
}
|
}
|
||||||
// jichi 2/11/2015: Check baddaddr which might crash the game on Windows XP.
|
// jichi 2/11/2015: Check baddaddr which might crash the game on Windows XP.
|
||||||
if (*pw == 0xc483 && !::IsBadReadPtr((LPCVOID)(pb + 2), 1) && !::IsBadReadPtr((LPCVOID)(*(pb + 2) - 8), 1)) {
|
if (*pw == 0xc483 && !::IsBadReadPtr((LPCVOID)(pb + 2), 1) && !::IsBadReadPtr((LPCVOID)(*(pb + 2) - 8), 1))
|
||||||
|
{
|
||||||
ConsoleOutput("WillPlus1 pattern found");
|
ConsoleOutput("WillPlus1 pattern found");
|
||||||
// jichi 1/18/2015:
|
// jichi 1/18/2015:
|
||||||
// By studying [honeybee] RE:BIRTHDAY SONG, it seems the scenario text is at fixed address
|
// By studying [honeybee] RE:BIRTHDAY SONG, it seems the scenario text is at fixed address
|
||||||
@ -147,8 +150,9 @@ void SpecialHookWillPlus(hook_stack* stack, HookParam *hp, uintptr_t *data, uin
|
|||||||
*data = (DWORD)str;
|
*data = (DWORD)str;
|
||||||
*len = ::strlen(str);
|
*len = ::strlen(str);
|
||||||
*split = 0; // 8/3/2014 jichi: use return address as split
|
*split = 0; // 8/3/2014 jichi: use return address as split
|
||||||
|
}
|
||||||
} else { // jichi 1/19/2015: Try willplus2
|
else
|
||||||
|
{ // jichi 1/19/2015: Try willplus2
|
||||||
ConsoleOutput("WillPlus1 pattern not found, try WillPlus2 instead");
|
ConsoleOutput("WillPlus1 pattern not found, try WillPlus2 instead");
|
||||||
hp->offset = 4 * 8; // arg8, address of text
|
hp->offset = 4 * 8; // arg8, address of text
|
||||||
hp->type = USING_STRING | NO_CONTEXT | USING_SPLIT; // merge different scenario threads
|
hp->type = USING_STRING | NO_CONTEXT | USING_SPLIT; // merge different scenario threads
|
||||||
@ -166,9 +170,13 @@ void SpecialHookWillPlus(hook_stack* stack, HookParam *hp, uintptr_t *data, uin
|
|||||||
bool InsertOldWillPlusHook()
|
bool InsertOldWillPlusHook()
|
||||||
{
|
{
|
||||||
//__debugbreak();
|
//__debugbreak();
|
||||||
enum { sub_esp = 0xec81 }; // jichi: caller pattern: sub esp = 0x81,0xec byte
|
enum
|
||||||
|
{
|
||||||
|
sub_esp = 0xec81
|
||||||
|
}; // jichi: caller pattern: sub esp = 0x81,0xec byte
|
||||||
ULONG addr = MemDbg::findCallerAddress((ULONG)::GetGlyphOutlineA, sub_esp, processStartAddress, processStopAddress);
|
ULONG addr = MemDbg::findCallerAddress((ULONG)::GetGlyphOutlineA, sub_esp, processStartAddress, processStopAddress);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
|
{
|
||||||
ConsoleOutput("WillPlus: function call not found");
|
ConsoleOutput("WillPlus: function call not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -185,8 +193,10 @@ const char *_willplus_trim_a(const char *text, size_t *size)
|
|||||||
{
|
{
|
||||||
int textSize = ::strlen(text);
|
int textSize = ::strlen(text);
|
||||||
int prefix = 0;
|
int prefix = 0;
|
||||||
if (text[0] == '%') {
|
if (text[0] == '%')
|
||||||
while (prefix < textSize - 1 && text[prefix] == '%' && ::isupper(text[prefix+1])) {
|
{
|
||||||
|
while (prefix < textSize - 1 && text[prefix] == '%' && ::isupper(text[prefix + 1]))
|
||||||
|
{
|
||||||
prefix += 2;
|
prefix += 2;
|
||||||
while (::isupper(text[prefix]))
|
while (::isupper(text[prefix]))
|
||||||
prefix++;
|
prefix++;
|
||||||
@ -194,7 +204,8 @@ const char *_willplus_trim_a(const char *text, size_t *size)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
int pos = textSize;
|
int pos = textSize;
|
||||||
for (int i = textSize - 1; i >= prefix; i--) {
|
for (int i = textSize - 1; i >= prefix; i--)
|
||||||
|
{
|
||||||
char ch = text[i];
|
char ch = text[i];
|
||||||
if (::isupper(ch))
|
if (::isupper(ch))
|
||||||
;
|
;
|
||||||
@ -214,8 +225,10 @@ const wchar_t *_willplus_trim_w(const wchar_t *text, size_t *size)
|
|||||||
{
|
{
|
||||||
int textSize = ::wcslen(text);
|
int textSize = ::wcslen(text);
|
||||||
int prefix = 0;
|
int prefix = 0;
|
||||||
if (text[0] == '%') {
|
if (text[0] == '%')
|
||||||
while (prefix < textSize - 1 && text[prefix] == '%' && ::isupper(text[prefix+1])) {
|
{
|
||||||
|
while (prefix < textSize - 1 && text[prefix] == '%' && ::isupper(text[prefix + 1]))
|
||||||
|
{
|
||||||
prefix += 2;
|
prefix += 2;
|
||||||
while (::isupper(text[prefix]))
|
while (::isupper(text[prefix]))
|
||||||
prefix++;
|
prefix++;
|
||||||
@ -223,7 +236,8 @@ const wchar_t *_willplus_trim_w(const wchar_t *text, size_t *size)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
int pos = textSize;
|
int pos = textSize;
|
||||||
for (int i = textSize - 1; i >= prefix; i--) {
|
for (int i = textSize - 1; i >= prefix; i--)
|
||||||
|
{
|
||||||
wchar_t ch = text[i];
|
wchar_t ch = text[i];
|
||||||
if (::isupper(ch))
|
if (::isupper(ch))
|
||||||
;
|
;
|
||||||
@ -253,7 +267,8 @@ void SpecialHookWillPlusA(hook_stack* stack, HookParam *hp, uintptr_t *data, ui
|
|||||||
*data = (DWORD)text;
|
*data = (DWORD)text;
|
||||||
*split = FIXED_SPLIT_VALUE << index;
|
*split = FIXED_SPLIT_VALUE << index;
|
||||||
}
|
}
|
||||||
bool WillPlus_extra_filter(void* data, size_t* size, HookParam*) {
|
bool WillPlus_extra_filter(void *data, size_t *size, HookParam *)
|
||||||
|
{
|
||||||
|
|
||||||
auto text = reinterpret_cast<LPWSTR>(data);
|
auto text = reinterpret_cast<LPWSTR>(data);
|
||||||
StringFilter(text, size, L"%XS", 5); // remove %XS followed by 2 chars
|
StringFilter(text, size, L"%XS", 5); // remove %XS followed by 2 chars
|
||||||
@ -278,7 +293,8 @@ bool InsertWillPlusAHook()
|
|||||||
const BYTE bytes2[] = {0x8B, 0x00, 0xFF, 0x76, 0xFC, 0x8B, 0xCF, 0x50};
|
const BYTE bytes2[] = {0x8B, 0x00, 0xFF, 0x76, 0xFC, 0x8B, 0xCF, 0x50};
|
||||||
ULONG range2 = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
ULONG range2 = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||||
ULONG addr2 = MemDbg::findBytes(bytes2, sizeof(bytes2), processStartAddress, processStartAddress + range2);
|
ULONG addr2 = MemDbg::findBytes(bytes2, sizeof(bytes2), processStartAddress, processStartAddress + range2);
|
||||||
if (addr2) {
|
if (addr2)
|
||||||
|
{
|
||||||
HookParam myhp;
|
HookParam myhp;
|
||||||
myhp.address = addr2 + 2;
|
myhp.address = addr2 + 2;
|
||||||
|
|
||||||
@ -296,7 +312,8 @@ bool InsertWillPlusAHook()
|
|||||||
0x81, 0xec, 0x14, 0x08, 0x00, 0x00 // 0042B5E0 81EC 14080000 SUB ESP,0x814 ; jichi: text in eax, name in eax - 1024, able to copy
|
0x81, 0xec, 0x14, 0x08, 0x00, 0x00 // 0042B5E0 81EC 14080000 SUB ESP,0x814 ; jichi: text in eax, name in eax - 1024, able to copy
|
||||||
};
|
};
|
||||||
DWORD addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
DWORD addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
|
{
|
||||||
ConsoleOutput("WillPlusA: pattern not found");
|
ConsoleOutput("WillPlusA: pattern not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -322,14 +339,16 @@ void SpecialHookWillPlusW(hook_stack* stack, HookParam *hp, uintptr_t *data, ui
|
|||||||
|
|
||||||
bool InsertWillPlusWHook()
|
bool InsertWillPlusWHook()
|
||||||
{
|
{
|
||||||
const BYTE bytes1[] = { // scenario
|
const BYTE bytes1[] = {
|
||||||
|
// scenario
|
||||||
0x83, 0xc0, 0x20, // 00452b02 83c0 20 add eax,0x20 ; jichi: hook before here, text in ecx
|
0x83, 0xc0, 0x20, // 00452b02 83c0 20 add eax,0x20 ; jichi: hook before here, text in ecx
|
||||||
0x33, 0xd2, // 00452b05 33d2 xor edx,edx
|
0x33, 0xd2, // 00452b05 33d2 xor edx,edx
|
||||||
0x8b, 0xc1, // 00452b07 8bc1 mov eax,ecx
|
0x8b, 0xc1, // 00452b07 8bc1 mov eax,ecx
|
||||||
0xc7, 0x84, 0x24, 0xe0, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00 // 00452b09 c78424 e0010000 07000000 mov dword ptr ss:[esp+0x1e0],0x7
|
0xc7, 0x84, 0x24, 0xe0, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00 // 00452b09 c78424 e0010000 07000000 mov dword ptr ss:[esp+0x1e0],0x7
|
||||||
// 00452b14 c78424 dc010000 00000000 mov dword ptr ss:[esp+0x1dc],0x0
|
// 00452b14 c78424 dc010000 00000000 mov dword ptr ss:[esp+0x1dc],0x0
|
||||||
};
|
};
|
||||||
const BYTE bytes2[] = { // name
|
const BYTE bytes2[] = {
|
||||||
|
// name
|
||||||
0x33, 0xdb, // 00453521 33db xor ebx,ebx ; jichi: hook here, text in ecx
|
0x33, 0xdb, // 00453521 33db xor ebx,ebx ; jichi: hook here, text in ecx
|
||||||
0x33, 0xd2, // 00453523 33d2 xor edx,edx
|
0x33, 0xd2, // 00453523 33d2 xor edx,edx
|
||||||
0x8b, 0xc1, // 00453525 8bc1 mov eax,ecx
|
0x8b, 0xc1, // 00453525 8bc1 mov eax,ecx
|
||||||
@ -339,9 +358,11 @@ bool InsertWillPlusWHook()
|
|||||||
const BYTE *bytes[] = {bytes1, bytes2};
|
const BYTE *bytes[] = {bytes1, bytes2};
|
||||||
const size_t sizes[] = {sizeof(bytes1), sizeof(bytes2)};
|
const size_t sizes[] = {sizeof(bytes1), sizeof(bytes2)};
|
||||||
auto succ = false;
|
auto succ = false;
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
DWORD addr = MemDbg::findBytes(bytes[i], sizes[i], processStartAddress, processStopAddress);
|
DWORD addr = MemDbg::findBytes(bytes[i], sizes[i], processStartAddress, processStopAddress);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
|
{
|
||||||
ConsoleOutput("WillPlusW: pattern not found");
|
ConsoleOutput("WillPlusW: pattern not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -450,7 +471,8 @@ static bool InsertNewWillPlusHook()
|
|||||||
|
|
||||||
BYTE byte = *(BYTE *)(addr + 1);
|
BYTE byte = *(BYTE *)(addr + 1);
|
||||||
regs offset = regs::invalid;
|
regs offset = regs::invalid;
|
||||||
switch (byte) {
|
switch (byte)
|
||||||
|
{
|
||||||
case 0xf9:
|
case 0xf9:
|
||||||
offset = regs::ecx;
|
offset = regs::ecx;
|
||||||
break;
|
break;
|
||||||
@ -473,7 +495,8 @@ static bool InsertNewWillPlusHook()
|
|||||||
offset = regs::edi;
|
offset = regs::edi;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
if (offset!=regs::invalid) {
|
if (offset != regs::invalid)
|
||||||
|
{
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr + 8;
|
hp.address = addr + 8;
|
||||||
hp.type = CODEC_UTF16;
|
hp.type = CODEC_UTF16;
|
||||||
@ -481,7 +504,8 @@ static bool InsertNewWillPlusHook()
|
|||||||
found |= NewHook(hp, "WillPlus3");
|
found |= NewHook(hp, "WillPlus3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) ConsoleOutput("WillPlus: failed to find instructions");
|
if (!found)
|
||||||
|
ConsoleOutput("WillPlus: failed to find instructions");
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,9 +517,12 @@ bool InsertWillPlusHook()
|
|||||||
ok = InsertWillPlusWHook() || InsertNewWillPlusHook() || InsertWillPlusAHook() || ok;
|
ok = InsertWillPlusWHook() || InsertNewWillPlusHook() || InsertWillPlusAHook() || ok;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
namespace will3{
|
namespace will3
|
||||||
|
{
|
||||||
|
|
||||||
int kp = 0;int lf=0;int lc=0;
|
int kp = 0;
|
||||||
|
int lf = 0;
|
||||||
|
int lc = 0;
|
||||||
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)
|
||||||
{
|
{
|
||||||
// DOUT(QString::fromUtf16((LPWSTR)s->stack[6]));//"MS UI Gothic"
|
// DOUT(QString::fromUtf16((LPWSTR)s->stack[6]));//"MS UI Gothic"
|
||||||
@ -507,17 +534,21 @@ bool hookBefore(hook_stack*s,void* data, size_t* len,uintptr_t*role)
|
|||||||
auto split = s->stack[0]; // retaddr
|
auto split = s->stack[0]; // retaddr
|
||||||
|
|
||||||
std::wstring str = ((LPWSTR)s->stack[7]);
|
std::wstring str = ((LPWSTR)s->stack[7]);
|
||||||
kp=0;lf=0;
|
kp = 0;
|
||||||
if (endWith(str,L"%K%P")){
|
lf = 0;
|
||||||
|
if (endWith(str, L"%K%P"))
|
||||||
|
{
|
||||||
kp = 1;
|
kp = 1;
|
||||||
|
|
||||||
str = str.substr(0, str.size() - 4);
|
str = str.substr(0, str.size() - 4);
|
||||||
}
|
}
|
||||||
if(startWith(str,L"%LF")){
|
if (startWith(str, L"%LF"))
|
||||||
|
{
|
||||||
lf = 1;
|
lf = 1;
|
||||||
str = str.substr(3);
|
str = str.substr(3);
|
||||||
}
|
}
|
||||||
if(startWith(str,L"%LC")){
|
if (startWith(str, L"%LC"))
|
||||||
|
{
|
||||||
lc = 1;
|
lc = 1;
|
||||||
str = str.substr(3);
|
str = str.substr(3);
|
||||||
}
|
}
|
||||||
@ -530,35 +561,41 @@ bool hookBefore(hook_stack*s,void* data, size_t* len,uintptr_t*role)
|
|||||||
write_string_overwrite(data, len, str);
|
write_string_overwrite(data, len, str);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
void hookafter(hook_stack*s,void* data, size_t len){
|
void hookafter(hook_stack *s, void *data, size_t len)
|
||||||
|
{
|
||||||
auto data_ = std::wstring((wchar_t *)data, len / 2); // EngineController::instance()->dispatchTextWSTD(innner, Engine::ScenarioRole, 0);
|
auto data_ = std::wstring((wchar_t *)data, len / 2); // EngineController::instance()->dispatchTextWSTD(innner, Engine::ScenarioRole, 0);
|
||||||
if (kp) {
|
if (kp)
|
||||||
|
{
|
||||||
data_.append(L"%K%P");
|
data_.append(L"%K%P");
|
||||||
}
|
}
|
||||||
if(lf){
|
if (lf)
|
||||||
|
{
|
||||||
data_ = L"%LF" + data_;
|
data_ = L"%LF" + data_;
|
||||||
}if(lc){
|
}
|
||||||
|
if (lc)
|
||||||
|
{
|
||||||
data_ = L"%LC" + data_;
|
data_ = L"%LC" + data_;
|
||||||
}
|
}
|
||||||
s->stack[7] = (ULONG)(data_.c_str());
|
s->stack[7] = (ULONG)(data_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool InsertWillPlus4Hook() {
|
bool InsertWillPlus4Hook()
|
||||||
|
{
|
||||||
// 星の乙女と六華の姉妹
|
// 星の乙女と六華の姉妹
|
||||||
const BYTE bytes[] = {
|
const BYTE bytes[] = {
|
||||||
0xc7, 0x45, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
0xc7, 0x45, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x33, 0xc9,
|
0x33, 0xc9,
|
||||||
0xc7,0x47,0x78,0x00,0x00,0x00,0x00
|
0xc7, 0x47, 0x78, 0x00, 0x00, 0x00, 0x00};
|
||||||
};
|
|
||||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||||
|
|
||||||
if (addr == 0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
addr = MemDbg::findEnclosingFunctionBeforeDword(0x83dc8b53, addr, MemDbg::MaximumFunctionSize, 1);
|
addr = MemDbg::findEnclosingFunctionBeforeDword(0x83dc8b53, addr, MemDbg::MaximumFunctionSize, 1);
|
||||||
|
|
||||||
if (addr == 0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
hp.offset = get_stack(7);
|
hp.offset = get_stack(7);
|
||||||
@ -569,15 +606,15 @@ bool InsertWillPlus4Hook() {
|
|||||||
hp.hook_after = will3::hookafter;
|
hp.hook_after = will3::hookafter;
|
||||||
return NewHook(hp, "EmbedWillplus3");
|
return NewHook(hp, "EmbedWillplus3");
|
||||||
}
|
}
|
||||||
bool InsertWillPlus5Hook() {
|
bool InsertWillPlus5Hook()
|
||||||
|
{
|
||||||
// ensemble 29th Project『乙女の剣と秘めごとコンチェルト』オフィシャルサイト 体验版
|
// ensemble 29th Project『乙女の剣と秘めごとコンチェルト』オフィシャルサイト 体验版
|
||||||
|
|
||||||
const BYTE bytes[] = {
|
const BYTE bytes[] = {
|
||||||
0x3d, XX2, 0x00, 0x00,
|
0x3d, XX2, 0x00, 0x00,
|
||||||
0x72, XX,
|
0x72, XX,
|
||||||
0x3d, XX2, 0x00, 0x00,
|
0x3d, XX2, 0x00, 0x00,
|
||||||
0x77
|
0x77};
|
||||||
};
|
|
||||||
/*if (v26 >= 0xE63E)
|
/*if (v26 >= 0xE63E)
|
||||||
{
|
{
|
||||||
if (v26 <= 0xE757)*/
|
if (v26 <= 0xE757)*/
|
||||||
@ -589,7 +626,8 @@ bool InsertWillPlus5Hook() {
|
|||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress);
|
auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress);
|
||||||
for (auto addr : addrs) {
|
for (auto addr : addrs)
|
||||||
|
{
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
hp.offset = get_reg(regs::eax);
|
hp.offset = get_reg(regs::eax);
|
||||||
@ -599,7 +637,8 @@ bool InsertWillPlus5Hook() {
|
|||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
bool insertwillplus6(){
|
bool insertwillplus6()
|
||||||
|
{
|
||||||
|
|
||||||
/* 0x00492870
|
/* 0x00492870
|
||||||
0: 50 push eax
|
0: 50 push eax
|
||||||
@ -636,11 +675,11 @@ f: 6a 01 push 0x1
|
|||||||
0x8b, 0xd6,
|
0x8b, 0xd6,
|
||||||
0xe8, XX4,
|
0xe8, XX4,
|
||||||
0x83, 0xf8,
|
0x83, 0xf8,
|
||||||
0xff,0x75,0xdc
|
0xff, 0x75, 0xdc};
|
||||||
};
|
|
||||||
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||||
|
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
addr += sizeof(bytes);
|
addr += sizeof(bytes);
|
||||||
ConsoleOutput("%p %p %p", addr, processStartAddress, processStopAddress);
|
ConsoleOutput("%p %p %p", addr, processStartAddress, processStopAddress);
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
@ -650,7 +689,8 @@ f: 6a 01 push 0x1
|
|||||||
ConsoleOutput("INSERT WillPlus6");
|
ConsoleOutput("INSERT WillPlus6");
|
||||||
return NewHook(hp, "WillPlus6");
|
return NewHook(hp, "WillPlus6");
|
||||||
}
|
}
|
||||||
bool willX(){
|
bool willX()
|
||||||
|
{
|
||||||
// 世界でいちばんNGな恋
|
// 世界でいちばんNGな恋
|
||||||
// .text:0040EAE9 81 FE 94 81 00 00 cmp esi, 8194h
|
// .text:0040EAE9 81 FE 94 81 00 00 cmp esi, 8194h
|
||||||
// .text:0040EAEF 74 2C jz short loc_40EB1D
|
// .text:0040EAEF 74 2C jz short loc_40EB1D
|
||||||
@ -680,11 +720,11 @@ bool willX(){
|
|||||||
0x74, XX,
|
0x74, XX,
|
||||||
0x81, 0xFE, 0x59, 0x81, 0x00, 0x00,
|
0x81, 0xFE, 0x59, 0x81, 0x00, 0x00,
|
||||||
0x74, XX,
|
0x74, XX,
|
||||||
0x81,0xFE,0x96,0x81,0x00,0x00
|
0x81, 0xFE, 0x96, 0x81, 0x00, 0x00};
|
||||||
};
|
|
||||||
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||||
|
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
auto succ = false;
|
auto succ = false;
|
||||||
{
|
{
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
@ -707,12 +747,8 @@ bool willX(){
|
|||||||
return succ;
|
return succ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{ // unnamed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace { // unnamed
|
|
||||||
|
|
||||||
// Sample prefix: %LF
|
// Sample prefix: %LF
|
||||||
// Sample suffix: %L%P%W
|
// Sample suffix: %L%P%W
|
||||||
@ -720,21 +756,25 @@ template <typename strT>
|
|||||||
strT trim(strT text, int *size)
|
strT trim(strT text, int *size)
|
||||||
{
|
{
|
||||||
int length = *size;
|
int length = *size;
|
||||||
if (text[0] == '%') { // handle prefix
|
if (text[0] == '%')
|
||||||
|
{ // handle prefix
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
while (pos < length - 1 && text[pos] == '%' && ::isupper(text[pos+1])) {
|
while (pos < length - 1 && text[pos] == '%' && ::isupper(text[pos + 1]))
|
||||||
|
{
|
||||||
pos += 2;
|
pos += 2;
|
||||||
while (::isupper(text[pos]))
|
while (::isupper(text[pos]))
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
if (pos) {
|
if (pos)
|
||||||
|
{
|
||||||
length -= pos;
|
length -= pos;
|
||||||
text += pos;
|
text += pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // handle suffix
|
{ // handle suffix
|
||||||
int pos = length;
|
int pos = length;
|
||||||
for (int i = length - 1; i >= 0; i--) {
|
for (int i = length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
if (::isupper(text[i]))
|
if (::isupper(text[i]))
|
||||||
;
|
;
|
||||||
else if (text[i] == '%' && ::isupper(text[i + 1]))
|
else if (text[i] == '%' && ::isupper(text[i + 1]))
|
||||||
@ -747,7 +787,8 @@ strT trim(strT text, int *size)
|
|||||||
*size = length;
|
*size = length;
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
struct textinfo{
|
struct textinfo
|
||||||
|
{
|
||||||
std::wstring text_;
|
std::wstring text_;
|
||||||
int stackIndex_;
|
int stackIndex_;
|
||||||
int role_;
|
int role_;
|
||||||
@ -762,7 +803,10 @@ namespace TextHookW
|
|||||||
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)
|
||||||
{
|
{
|
||||||
auto info = savetyperef.at(idx);
|
auto info = savetyperef.at(idx);
|
||||||
enum { sig = 0 };
|
enum
|
||||||
|
{
|
||||||
|
sig = 0
|
||||||
|
};
|
||||||
auto text = (LPCWSTR)s->stack[info->stackIndex_];
|
auto text = (LPCWSTR)s->stack[info->stackIndex_];
|
||||||
if (!text || !*text)
|
if (!text || !*text)
|
||||||
return false;
|
return false;
|
||||||
@ -776,10 +820,14 @@ namespace TextHookW
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template <int idx>
|
template <int idx>
|
||||||
void hookafter(hook_stack*s,void* data, size_t len){
|
void hookafter(hook_stack *s, void *data, size_t len)
|
||||||
|
{
|
||||||
auto newText = std::wstring((LPWSTR)data, len / 2);
|
auto newText = std::wstring((LPWSTR)data, len / 2);
|
||||||
auto info = savetyperef.at(idx);
|
auto info = savetyperef.at(idx);
|
||||||
enum { sig = 0 };
|
enum
|
||||||
|
{
|
||||||
|
sig = 0
|
||||||
|
};
|
||||||
auto text = (LPCWSTR)s->stack[info->stackIndex_];
|
auto text = (LPCWSTR)s->stack[info->stackIndex_];
|
||||||
if (!text || !*text)
|
if (!text || !*text)
|
||||||
return;
|
return;
|
||||||
@ -805,7 +853,8 @@ namespace TextHookW
|
|||||||
bool attach(const uint8_t *pattern, size_t patternSize, ULONG startAddress, ULONG stopAddress, int hookStackIndex, int role = Engine::UnknownRole)
|
bool attach(const uint8_t *pattern, size_t patternSize, ULONG startAddress, ULONG stopAddress, int hookStackIndex, int role = Engine::UnknownRole)
|
||||||
{
|
{
|
||||||
ULONG addr = MemDbg::findBytes(pattern, patternSize, startAddress, stopAddress);
|
ULONG addr = MemDbg::findBytes(pattern, patternSize, startAddress, stopAddress);
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
auto _tinfo = new textinfo{};
|
auto _tinfo = new textinfo{};
|
||||||
@ -958,7 +1007,6 @@ bool attachScenarioHookW2(ULONG startAddress, ULONG stopAddress)
|
|||||||
};
|
};
|
||||||
int edi = get_reg(regs::edi) / 4;
|
int edi = get_reg(regs::edi) / 4;
|
||||||
return TextHookW::attach<2>(bytes, sizeof(bytes), startAddress, stopAddress, edi, Engine::ScenarioRole);
|
return TextHookW::attach<2>(bytes, sizeof(bytes), startAddress, stopAddress, edi, Engine::ScenarioRole);
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Sample game: なついろレシピ
|
* Sample game: なついろレシピ
|
||||||
@ -1028,7 +1076,6 @@ bool attachNameHookW(ULONG startAddress, ULONG stopAddress)
|
|||||||
|
|
||||||
int ecx = get_reg(regs::ecx) / 4;
|
int ecx = get_reg(regs::ecx) / 4;
|
||||||
return TextHookW::attach<3>(bytes, sizeof(bytes), startAddress, stopAddress, ecx, Engine::NameRole);
|
return TextHookW::attach<3>(bytes, sizeof(bytes), startAddress, stopAddress, ecx, Engine::NameRole);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1096,12 +1143,13 @@ bool attachOtherHookW(ULONG startAddress, ULONG stopAddress)
|
|||||||
|
|
||||||
int edx = get_reg(regs::edx) / 4;
|
int edx = get_reg(regs::edx) / 4;
|
||||||
return TextHookW::attach<4>(bytes, sizeof(bytes), startAddress, stopAddress, edx, Engine::OtherRole);
|
return TextHookW::attach<4>(bytes, sizeof(bytes), startAddress, stopAddress, edx, Engine::OtherRole);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace PatchA {
|
namespace PatchA
|
||||||
|
{
|
||||||
|
|
||||||
namespace Private {
|
namespace Private
|
||||||
|
{
|
||||||
// The second argument is always 0 and not used
|
// The second argument is always 0 and not used
|
||||||
bool isLeadByteChar(int ch, int)
|
bool isLeadByteChar(int ch, int)
|
||||||
{
|
{
|
||||||
@ -1181,7 +1229,8 @@ bool csmemcpy(void *dst, const void *src, size_t size)
|
|||||||
ulong replace_near_call(ulong addr, ulong val)
|
ulong replace_near_call(ulong addr, ulong val)
|
||||||
{
|
{
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
switch (::disasm((LPCVOID)addr)) {
|
switch (::disasm((LPCVOID)addr))
|
||||||
|
{
|
||||||
case 5: // near call / short jmp: relative address
|
case 5: // near call / short jmp: relative address
|
||||||
ret = *(DWORD *)(addr + 1) + (addr + 5);
|
ret = *(DWORD *)(addr + 1) + (addr + 5);
|
||||||
val -= addr + 5;
|
val -= addr + 5;
|
||||||
@ -1195,7 +1244,8 @@ ulong replace_near_call(ulong addr, ulong val)
|
|||||||
*(DWORD *)(data + 1) = val - (addr + 5);
|
*(DWORD *)(data + 1) = val - (addr + 5);
|
||||||
return csmemcpy((LPVOID)addr, data, sizeof(data)) ? ret : 0;
|
return csmemcpy((LPVOID)addr, data, sizeof(data)) ? ret : 0;
|
||||||
}
|
}
|
||||||
default: return 0;
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ULONG patchEncoding(ULONG startAddress, ULONG stopAddress)
|
ULONG patchEncoding(ULONG startAddress, ULONG stopAddress)
|
||||||
@ -1205,7 +1255,10 @@ ULONG patchEncoding(ULONG startAddress, ULONG stopAddress)
|
|||||||
0xff, 0x75, 0x08, // 00487fe1 ff75 08 push dword ptr ss:[ebp+0x8]
|
0xff, 0x75, 0x08, // 00487fe1 ff75 08 push dword ptr ss:[ebp+0x8]
|
||||||
0xe8, 0xaa, 0xff, 0xff, 0xff // 00487fe4 e8 aaffffff call .00487f93 ; jichi: called here
|
0xe8, 0xaa, 0xff, 0xff, 0xff // 00487fe4 e8 aaffffff call .00487f93 ; jichi: called here
|
||||||
};
|
};
|
||||||
enum { addr_offset = 5 };
|
enum
|
||||||
|
{
|
||||||
|
addr_offset = 5
|
||||||
|
};
|
||||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
|
||||||
|
|
||||||
return addr; //&& replace_near_call(addr + addr_offset, (ULONG)Private::isLeadByteChar);
|
return addr; //&& replace_near_call(addr + addr_offset, (ULONG)Private::isLeadByteChar);
|
||||||
@ -1213,9 +1266,11 @@ ULONG patchEncoding(ULONG startAddress, ULONG stopAddress)
|
|||||||
|
|
||||||
} // namespace PatchA
|
} // namespace PatchA
|
||||||
|
|
||||||
namespace ScenarioHookA {
|
namespace ScenarioHookA
|
||||||
|
{
|
||||||
|
|
||||||
namespace Private {
|
namespace Private
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
void dispatch(LPSTR text, int role)
|
void dispatch(LPSTR text, int role)
|
||||||
{
|
{
|
||||||
@ -1244,7 +1299,10 @@ namespace Private {
|
|||||||
// dispatch(text - 1024, Engine::NameRole);
|
// dispatch(text - 1024, Engine::NameRole);
|
||||||
// dispatch(text, Engine::ScenarioRole);
|
// dispatch(text, Engine::ScenarioRole);
|
||||||
|
|
||||||
enum { sig = 0 };
|
enum
|
||||||
|
{
|
||||||
|
sig = 0
|
||||||
|
};
|
||||||
if (!Engine::isAddressWritable(text) || !*text) // isAddressWritable is not needed for correct games
|
if (!Engine::isAddressWritable(text) || !*text) // isAddressWritable is not needed for correct games
|
||||||
return false;
|
return false;
|
||||||
int size = ::strlen(text),
|
int size = ::strlen(text),
|
||||||
@ -1263,7 +1321,8 @@ namespace Private {
|
|||||||
::strcpy(text, newData.c_str());
|
::strcpy(text, newData.c_str());
|
||||||
return true;*/
|
return true;*/
|
||||||
}
|
}
|
||||||
void hookafter(hook_stack*s,void* data, size_t len){
|
void hookafter(hook_stack *s, void *data, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
auto newData = std::string((char *)data, len);
|
auto newData = std::string((char *)data, len);
|
||||||
auto text = (LPSTR)s->eax;
|
auto text = (LPSTR)s->eax;
|
||||||
@ -1510,7 +1569,8 @@ bool attach(ULONG startAddress, ULONG stopAddress)
|
|||||||
0x81, 0xec, 0x14, 0x08, 0x00, 0x00 // 0042B5E0 81EC 14080000 SUB ESP,0x814 ; jichi: text in eax, name in eax - 1024, able to copy
|
0x81, 0xec, 0x14, 0x08, 0x00, 0x00 // 0042B5E0 81EC 14080000 SUB ESP,0x814 ; jichi: text in eax, name in eax - 1024, able to copy
|
||||||
};
|
};
|
||||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), startAddress, stopAddress);
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
|
|
||||||
@ -1521,12 +1581,13 @@ bool attach(ULONG startAddress, ULONG stopAddress)
|
|||||||
hp.hook_font = F_GetGlyphOutlineA | F_TextOutA;
|
hp.hook_font = F_GetGlyphOutlineA | F_TextOutA;
|
||||||
static ULONG paddr = (PatchA::patchEncoding(startAddress, stopAddress));
|
static ULONG paddr = (PatchA::patchEncoding(startAddress, stopAddress));
|
||||||
ConsoleOutput("%p", paddr);
|
ConsoleOutput("%p", paddr);
|
||||||
if(paddr){
|
if (paddr)
|
||||||
|
{
|
||||||
hp.type |= EMBED_DYNA_SJIS;
|
hp.type |= EMBED_DYNA_SJIS;
|
||||||
hp.hook_font = F_GetGlyphOutlineA | F_TextOutA;
|
hp.hook_font = F_GetGlyphOutlineA | F_TextOutA;
|
||||||
patch_fun=[](){
|
patch_fun = []()
|
||||||
|
{
|
||||||
PatchA::replace_near_call(paddr + 5, (ULONG)PatchA::Private::isLeadByteChar);
|
PatchA::replace_near_call(paddr + 5, (ULONG)PatchA::Private::isLeadByteChar);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return NewHook(hp, "EmbedWillplusA");
|
return NewHook(hp, "EmbedWillplusA");
|
||||||
@ -1534,9 +1595,11 @@ bool attach(ULONG startAddress, ULONG stopAddress)
|
|||||||
|
|
||||||
} // namespace ScenarioHookA
|
} // namespace ScenarioHookA
|
||||||
|
|
||||||
namespace OtherHookA {
|
namespace OtherHookA
|
||||||
|
{
|
||||||
|
|
||||||
namespace Private {
|
namespace Private
|
||||||
|
{
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -1563,7 +1626,8 @@ namespace Private {
|
|||||||
bool attach(ULONG startAddress, ULONG stopAddress)
|
bool attach(ULONG startAddress, ULONG stopAddress)
|
||||||
{
|
{
|
||||||
ULONG addr = MemDbg::findCallerAddressAfterInt3((ULONG)::GetGlyphOutlineA, startAddress, stopAddress);
|
ULONG addr = MemDbg::findCallerAddressAfterInt3((ULONG)::GetGlyphOutlineA, startAddress, stopAddress);
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
hp.hook_before = Private::hookBefore;
|
hp.hook_before = Private::hookBefore;
|
||||||
@ -1577,21 +1641,23 @@ bool attach(ULONG startAddress, ULONG stopAddress)
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** Public class */
|
/** Public class */
|
||||||
namespace WillPlusEngine{
|
namespace WillPlusEngine
|
||||||
|
{
|
||||||
bool attach()
|
bool attach()
|
||||||
{
|
{
|
||||||
ULONG startAddress = processStartAddress, stopAddress = processStopAddress;
|
ULONG startAddress = processStartAddress, stopAddress = processStopAddress;
|
||||||
|
|
||||||
|
if (::attachScenarioHookW1(startAddress, stopAddress) || ::attachScenarioHookW2(startAddress, stopAddress))
|
||||||
if (::attachScenarioHookW1(startAddress, stopAddress) || ::attachScenarioHookW2(startAddress, stopAddress)) {
|
{
|
||||||
|
|
||||||
(::attachNameHookW(startAddress, stopAddress));
|
(::attachNameHookW(startAddress, stopAddress));
|
||||||
|
|
||||||
(::attachOtherHookW(startAddress, stopAddress));
|
(::attachOtherHookW(startAddress, stopAddress));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
} else if (ScenarioHookA::attach(startAddress, stopAddress)) { // try widechar pattern first, which is more unique
|
else if (ScenarioHookA::attach(startAddress, stopAddress))
|
||||||
|
{ // try widechar pattern first, which is more unique
|
||||||
|
|
||||||
(OtherHookA::attach(startAddress, stopAddress));
|
(OtherHookA::attach(startAddress, stopAddress));
|
||||||
// HijackManager::instance()->attachFunction((ULONG)::GetGlyphOutlineA);
|
// HijackManager::instance()->attachFunction((ULONG)::GetGlyphOutlineA);
|
||||||
@ -1603,7 +1669,8 @@ bool attach()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace{
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
static bool InsertWillPlus4()
|
static bool InsertWillPlus4()
|
||||||
{
|
{
|
||||||
@ -1620,7 +1687,8 @@ static bool InsertWillPlus4()
|
|||||||
};
|
};
|
||||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
|
{
|
||||||
ConsoleOutput("WillPlus4: pattern not found");
|
ConsoleOutput("WillPlus4: pattern not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1651,7 +1719,8 @@ static bool InsertWillPlus5()
|
|||||||
};
|
};
|
||||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
|
{
|
||||||
ConsoleOutput("WillPlus5: pattern not found");
|
ConsoleOutput("WillPlus5: pattern not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1669,7 +1738,8 @@ static bool InsertWillPlus5()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _xxx(){
|
bool _xxx()
|
||||||
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
ok = InsertWillPlus4() || ok;
|
ok = InsertWillPlus4() || ok;
|
||||||
ok = InsertWillPlus5() || ok;
|
ok = InsertWillPlus5() || ok;
|
||||||
@ -1677,7 +1747,8 @@ bool ok=false;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WillPlus::attach_function() {
|
bool WillPlus::attach_function()
|
||||||
|
{
|
||||||
bool succ = WillPlusEngine::attach();
|
bool succ = WillPlusEngine::attach();
|
||||||
succ |= InsertWillPlusHook();
|
succ |= InsertWillPlusHook();
|
||||||
succ |= InsertWillPlus4Hook();
|
succ |= InsertWillPlus4Hook();
|
||||||
@ -1689,17 +1760,19 @@ bool WillPlus::attach_function() {
|
|||||||
return succ;
|
return succ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Willold::attach_function()
|
||||||
|
{
|
||||||
bool Willold::attach_function() {
|
|
||||||
// https://vndb.org/v17755
|
// https://vndb.org/v17755
|
||||||
// 凌辱鬼
|
// 凌辱鬼
|
||||||
auto addr = MemDbg::findLongJumpAddress((ULONG)TextOutA, processStartAddress, processStopAddress);
|
auto addr = MemDbg::findLongJumpAddress((ULONG)TextOutA, processStartAddress, processStopAddress);
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
addr = MemDbg::findNearCallAddress(addr, processStartAddress, processStopAddress);
|
addr = MemDbg::findNearCallAddress(addr, processStartAddress, processStopAddress);
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
addr = findfuncstart(addr, 0x200);
|
addr = findfuncstart(addr, 0x200);
|
||||||
if(addr==0)return false;
|
if (addr == 0)
|
||||||
|
return false;
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
hp.type = USING_CHAR | CODEC_ANSI_BE;
|
hp.type = USING_CHAR | CODEC_ANSI_BE;
|
||||||
|
Loading…
Reference in New Issue
Block a user