mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-11-26 23:34:01 +08:00
muv
This commit is contained in:
parent
943f098682
commit
4a56a39d68
@ -1,221 +1,282 @@
|
||||
#include"RUGP.h"
|
||||
#include "RUGP.h"
|
||||
|
||||
namespace { // unnamed rUGP
|
||||
namespace
|
||||
{ // unnamed rUGP
|
||||
|
||||
/********************************************************************************************
|
||||
rUGP hook:
|
||||
Process name is rugp.exe. Used by AGE/GIGA games.
|
||||
/********************************************************************************************
|
||||
rUGP hook:
|
||||
Process name is rugp.exe. Used by AGE/GIGA games.
|
||||
|
||||
Font caching issue. Find call to GetGlyphOutlineA and keep stepping out functions.
|
||||
After several tries we comes to address in rvmm.dll and everything is catched.
|
||||
We see CALL [E*X+0x*] while EBP contains the character data.
|
||||
It's not as simple to reverse in rugp at run time as like reallive since rugp dosen't set
|
||||
up stack frame. In other words EBP is used for other purpose. We need to find alternative
|
||||
approaches.
|
||||
The way to the entry of that function gives us clue to find it. There is one CMP EBP,0x8140
|
||||
instruction in this function and that's enough! 0x8140 is the start of SHIFT-JIS
|
||||
characters. It's determining if ebp contains a SHIFT-JIS character. This function is not likely
|
||||
to be used in other ways. We simply search for this instruction and place hook around.
|
||||
********************************************************************************************/
|
||||
void SpecialHookRUGP1(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len)
|
||||
{
|
||||
//CC_UNUSED(split);
|
||||
DWORD *_stack = (DWORD *)stack->base;
|
||||
DWORD i, val;
|
||||
for (i = 0; i < 4; i++) {
|
||||
val = *_stack++;
|
||||
if ((val >> 16) == 0)
|
||||
break;
|
||||
|
||||
}
|
||||
if (i < 4) {
|
||||
hp->offset = i << 2;
|
||||
*data = val;
|
||||
*len = 2;
|
||||
hp->text_fun = nullptr;
|
||||
//hp->type &= ~EXTERN_HOOK;
|
||||
}
|
||||
else
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
// jichi 10/1/2013: Change return type to bool
|
||||
bool InsertRUGP1Hook()
|
||||
{
|
||||
DWORD low;
|
||||
if (!Util::CheckFile(L"rvmm.dll")) {
|
||||
ConsoleOutput("rUGP: rvmm.dll does not exist");
|
||||
return false;
|
||||
}
|
||||
//WCHAR str[0x40];
|
||||
LPVOID ch = (LPVOID)0x8140;
|
||||
enum { range = 0x20000 };
|
||||
low = (DWORD)GetModuleHandleW(L"rvmm.dll");
|
||||
DWORD t = SearchPattern(low + range, processStopAddress, &ch, 4) + range;
|
||||
BYTE *s = (BYTE *)(low + t);
|
||||
//if (t) {
|
||||
if (t != range) { // jichi 10/1/2013: Changed to compare with 0x20000
|
||||
if (*(s - 2) != 0x81)
|
||||
return false;
|
||||
if (DWORD i = SafeFindEnclosingAlignedFunction((DWORD)s, 0x200)) {
|
||||
HookParam hp;
|
||||
hp.address = i;
|
||||
hp.text_fun = SpecialHookRUGP1;
|
||||
hp.type = CODEC_ANSI_BE|USING_CHAR;
|
||||
ConsoleOutput("INSERT rUGP#1");
|
||||
return NewHook(hp, "rUGP");
|
||||
Font caching issue. Find call to GetGlyphOutlineA and keep stepping out functions.
|
||||
After several tries we comes to address in rvmm.dll and everything is catched.
|
||||
We see CALL [E*X+0x*] while EBP contains the character data.
|
||||
It's not as simple to reverse in rugp at run time as like reallive since rugp dosen't set
|
||||
up stack frame. In other words EBP is used for other purpose. We need to find alternative
|
||||
approaches.
|
||||
The way to the entry of that function gives us clue to find it. There is one CMP EBP,0x8140
|
||||
instruction in this function and that's enough! 0x8140 is the start of SHIFT-JIS
|
||||
characters. It's determining if ebp contains a SHIFT-JIS character. This function is not likely
|
||||
to be used in other ways. We simply search for this instruction and place hook around.
|
||||
********************************************************************************************/
|
||||
void SpecialHookRUGP1(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
||||
{
|
||||
// CC_UNUSED(split);
|
||||
DWORD *_stack = (DWORD *)stack->base;
|
||||
DWORD i, val;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
val = *_stack++;
|
||||
if ((val >> 16) == 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
t = SearchPattern(low, range, &s, 4);
|
||||
if (!t) {
|
||||
ConsoleOutput("rUGP: pattern not found");
|
||||
//ConsoleOutput("Can't find characteristic instruction.");
|
||||
if (i < 4)
|
||||
{
|
||||
hp->offset = i << 2;
|
||||
*data = val;
|
||||
*len = 2;
|
||||
hp->text_fun = nullptr;
|
||||
// hp->type &= ~EXTERN_HOOK;
|
||||
}
|
||||
else
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
// jichi 10/1/2013: Change return type to bool
|
||||
bool InsertRUGP1Hook()
|
||||
{
|
||||
DWORD low;
|
||||
if (!Util::CheckFile(L"rvmm.dll"))
|
||||
{
|
||||
ConsoleOutput("rUGP: rvmm.dll does not exist");
|
||||
return false;
|
||||
}
|
||||
|
||||
s = (BYTE *)(low + t);
|
||||
for (int i = 0; i < 0x200; i++, s--)
|
||||
if (s[0] == 0x90
|
||||
&& *(DWORD *)(s - 3) == 0x90909090) {
|
||||
t = low+ t - i + 1;
|
||||
//swprintf(str, L"HookAddr 0x%.8x", t);
|
||||
//ConsoleOutput(str);
|
||||
// WCHAR str[0x40];
|
||||
LPVOID ch = (LPVOID)0x8140;
|
||||
enum
|
||||
{
|
||||
range = 0x20000
|
||||
};
|
||||
low = (DWORD)GetModuleHandleW(L"rvmm.dll");
|
||||
DWORD t = SearchPattern(low + range, processStopAddress, &ch, 4) + range;
|
||||
BYTE *s = (BYTE *)(low + t);
|
||||
// if (t) {
|
||||
if (t != range)
|
||||
{ // jichi 10/1/2013: Changed to compare with 0x20000
|
||||
if (*(s - 2) != 0x81)
|
||||
return false;
|
||||
if (DWORD i = SafeFindEnclosingAlignedFunction((DWORD)s, 0x200))
|
||||
{
|
||||
HookParam hp;
|
||||
hp.address = t;
|
||||
hp.offset=get_stack(1);
|
||||
hp.type = CODEC_ANSI_BE;
|
||||
ConsoleOutput("INSERT rUGP#2");
|
||||
hp.address = i;
|
||||
hp.text_fun = SpecialHookRUGP1;
|
||||
hp.type = CODEC_ANSI_BE | USING_CHAR;
|
||||
ConsoleOutput("INSERT rUGP#1");
|
||||
return NewHook(hp, "rUGP");
|
||||
}
|
||||
}
|
||||
ConsoleOutput("rUGP: failed");
|
||||
return false;
|
||||
//rt:
|
||||
//ConsoleOutput("Unknown rUGP engine.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t = SearchPattern(low, range, &s, 4);
|
||||
if (!t)
|
||||
{
|
||||
ConsoleOutput("rUGP: pattern not found");
|
||||
// ConsoleOutput("Can't find characteristic instruction.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/** rUGP2 10/11/2014 jichi
|
||||
*
|
||||
* Sample game: マブラヴ オルタネイヂ<EFBFBD>ヴ ト<EFBFBD>タル・イクリプス
|
||||
* The existing rUGP#1/#2 cannot be identified.
|
||||
* H-codes:
|
||||
* - /HAN-4@1E51D:VM60.DLL
|
||||
* - addr: 124189 = 0x1e51d
|
||||
* - length_offset: 1
|
||||
* - module: 3037492083 = 0xb50c7373
|
||||
* - off: 4294967288 = 0xfffffff8 = -8
|
||||
* - type: 1092 = 0x444
|
||||
* - /HAN-4@1001E51D ( alternative)
|
||||
* - addr: 268559645 = 0x1001e51d
|
||||
* - length_offset: 1
|
||||
* - type: 1028 = 0x404
|
||||
*
|
||||
* This function is very long.
|
||||
* 1001e4b2 ^e9 c0fcffff jmp _18.1001e177
|
||||
* 1001e4b7 8b45 14 mov eax,dword ptr ss:[ebp+0x14]
|
||||
* 1001e4ba c745 08 08000000 mov dword ptr ss:[ebp+0x8],0x8
|
||||
* 1001e4c1 85c0 test eax,eax
|
||||
* 1001e4c3 74 3c je short _18.1001e501
|
||||
* 1001e4c5 8378 04 00 cmp dword ptr ds:[eax+0x4],0x0
|
||||
* 1001e4c9 7f 36 jg short _18.1001e501
|
||||
* 1001e4cb 7c 05 jl short _18.1001e4d2
|
||||
* 1001e4cd 8338 00 cmp dword ptr ds:[eax],0x0
|
||||
* 1001e4d0 73 2f jnb short _18.1001e501
|
||||
* 1001e4d2 8b4d f0 mov ecx,dword ptr ss:[ebp-0x10]
|
||||
* 1001e4d5 8b91 38a20000 mov edx,dword ptr ds:[ecx+0xa238]
|
||||
* 1001e4db 8910 mov dword ptr ds:[eax],edx
|
||||
* 1001e4dd 8b89 3ca20000 mov ecx,dword ptr ds:[ecx+0xa23c]
|
||||
* 1001e4e3 8948 04 mov dword ptr ds:[eax+0x4],ecx
|
||||
* 1001e4e6 eb 19 jmp short _18.1001e501
|
||||
* 1001e4e8 c745 08 09000000 mov dword ptr ss:[ebp+0x8],0x9
|
||||
* 1001e4ef eb 10 jmp short _18.1001e501
|
||||
* 1001e4f1 c745 08 16000000 mov dword ptr ss:[ebp+0x8],0x16
|
||||
* 1001e4f8 eb 07 jmp short _18.1001e501
|
||||
* 1001e4fa c745 08 1f000000 mov dword ptr ss:[ebp+0x8],0x1f
|
||||
* 1001e501 8b45 08 mov eax,dword ptr ss:[ebp+0x8]
|
||||
* 1001e504 8ad0 mov dl,al
|
||||
* 1001e506 80f2 20 xor dl,0x20
|
||||
* 1001e509 80c2 5f add dl,0x5f
|
||||
* 1001e50c 80fa 3b cmp dl,0x3b
|
||||
* 1001e50f 0f87 80010000 ja _18.1001e695
|
||||
* 1001e515 0fb60e movzx ecx,byte ptr ds:[esi]
|
||||
* 1001e518 c1e0 08 shl eax,0x8
|
||||
* 1001e51b 0bc1 or eax,ecx
|
||||
* 1001e51d b9 01000000 mov ecx,0x1 ; jichi: hook here
|
||||
* 1001e522 03f1 add esi,ecx
|
||||
* 1001e524 8945 08 mov dword ptr ss:[ebp+0x8],eax
|
||||
* 1001e527 8975 0c mov dword ptr ss:[ebp+0xc],esi
|
||||
* 1001e52a 3d 79810000 cmp eax,0x8179
|
||||
* 1001e52f 0f85 9d000000 jnz _18.1001e5d2
|
||||
* 1001e535 8b4d f0 mov ecx,dword ptr ss:[ebp-0x10]
|
||||
* 1001e538 56 push esi
|
||||
* 1001e539 8d55 d0 lea edx,dword ptr ss:[ebp-0x30]
|
||||
* 1001e53c 52 push edx
|
||||
* 1001e53d e8 0e0bffff call _18.1000f050
|
||||
* 1001e542 8d4d d0 lea ecx,dword ptr ss:[ebp-0x30]
|
||||
* 1001e545 c745 fc 07000000 mov dword ptr ss:[ebp-0x4],0x7
|
||||
* 1001e54c ff15 500a0e10 call dword ptr ds:[0x100e0a50] ; _19.6a712fa9
|
||||
* 1001e552 84c0 test al,al
|
||||
* 1001e554 75 67 jnz short _18.1001e5bd
|
||||
* 1001e556 8b75 f0 mov esi,dword ptr ss:[ebp-0x10]
|
||||
* 1001e559 8d45 d0 lea eax,dword ptr ss:[ebp-0x30]
|
||||
* 1001e55c 50 push eax
|
||||
* 1001e55d 8bce mov ecx,esi
|
||||
* 1001e55f c745 e4 01000000 mov dword ptr ss:[ebp-0x1c],0x1
|
||||
* 1001e566 c745 e0 00000000 mov dword ptr ss:[ebp-0x20],0x0
|
||||
* 1001e56d e8 5e80ffff call _18.100165d0
|
||||
* 1001e572 0fb7f8 movzx edi,ax
|
||||
* 1001e575 57 push edi
|
||||
* 1001e576 8bce mov ecx,esi
|
||||
* 1001e578 e8 c380ffff call _18.10016640
|
||||
* 1001e57d 85c0 test eax,eax
|
||||
* 1001e57f 74 0d je short _18.1001e58e
|
||||
* 1001e581 f640 38 02 test byte ptr ds:[eax+0x38],0x2
|
||||
* 1001e585 74 07 je short _18.1001e58e
|
||||
* 1001e587 c745 e0 01000000 mov dword ptr ss:[ebp-0x20],0x1
|
||||
* 1001e58e 837d bc 10 cmp dword ptr ss:[ebp-0x44],0x10
|
||||
* 1001e592 74 29 je short _18.1001e5bd
|
||||
* 1001e594 8b43 28 mov eax,dword ptr ds:[ebx+0x28]
|
||||
* 1001e597 85c0 test eax,eax
|
||||
*/
|
||||
bool InsertRUGP2Hook()
|
||||
{
|
||||
s = (BYTE *)(low + t);
|
||||
for (int i = 0; i < 0x200; i++, s--)
|
||||
if (s[0] == 0x90 && *(DWORD *)(s - 3) == 0x90909090)
|
||||
{
|
||||
t = low + t - i + 1;
|
||||
// swprintf(str, L"HookAddr 0x%.8x", t);
|
||||
// ConsoleOutput(str);
|
||||
HookParam hp;
|
||||
hp.address = t;
|
||||
hp.offset = get_stack(1);
|
||||
hp.type = CODEC_ANSI_BE;
|
||||
ConsoleOutput("INSERT rUGP#2");
|
||||
return NewHook(hp, "rUGP");
|
||||
}
|
||||
}
|
||||
ConsoleOutput("rUGP: failed");
|
||||
return false;
|
||||
// rt:
|
||||
// ConsoleOutput("Unknown rUGP engine.");
|
||||
}
|
||||
|
||||
/** rUGP2 10/11/2014 jichi
|
||||
*
|
||||
* Sample game: マブラヴ オルタネイヂ<EFBFBD>ヴ ト<EFBFBD>タル・イクリプス
|
||||
* The existing rUGP#1/#2 cannot be identified.
|
||||
* H-codes:
|
||||
* - /HAN-4@1E51D:VM60.DLL
|
||||
* - addr: 124189 = 0x1e51d
|
||||
* - length_offset: 1
|
||||
* - module: 3037492083 = 0xb50c7373
|
||||
* - off: 4294967288 = 0xfffffff8 = -8
|
||||
* - type: 1092 = 0x444
|
||||
* - /HAN-4@1001E51D ( alternative)
|
||||
* - addr: 268559645 = 0x1001e51d
|
||||
* - length_offset: 1
|
||||
* - type: 1028 = 0x404
|
||||
*
|
||||
* This function is very long.
|
||||
* 1001e4b2 ^e9 c0fcffff jmp _18.1001e177
|
||||
* 1001e4b7 8b45 14 mov eax,dword ptr ss:[ebp+0x14]
|
||||
* 1001e4ba c745 08 08000000 mov dword ptr ss:[ebp+0x8],0x8
|
||||
* 1001e4c1 85c0 test eax,eax
|
||||
* 1001e4c3 74 3c je short _18.1001e501
|
||||
* 1001e4c5 8378 04 00 cmp dword ptr ds:[eax+0x4],0x0
|
||||
* 1001e4c9 7f 36 jg short _18.1001e501
|
||||
* 1001e4cb 7c 05 jl short _18.1001e4d2
|
||||
* 1001e4cd 8338 00 cmp dword ptr ds:[eax],0x0
|
||||
* 1001e4d0 73 2f jnb short _18.1001e501
|
||||
* 1001e4d2 8b4d f0 mov ecx,dword ptr ss:[ebp-0x10]
|
||||
* 1001e4d5 8b91 38a20000 mov edx,dword ptr ds:[ecx+0xa238]
|
||||
* 1001e4db 8910 mov dword ptr ds:[eax],edx
|
||||
* 1001e4dd 8b89 3ca20000 mov ecx,dword ptr ds:[ecx+0xa23c]
|
||||
* 1001e4e3 8948 04 mov dword ptr ds:[eax+0x4],ecx
|
||||
* 1001e4e6 eb 19 jmp short _18.1001e501
|
||||
* 1001e4e8 c745 08 09000000 mov dword ptr ss:[ebp+0x8],0x9
|
||||
* 1001e4ef eb 10 jmp short _18.1001e501
|
||||
* 1001e4f1 c745 08 16000000 mov dword ptr ss:[ebp+0x8],0x16
|
||||
* 1001e4f8 eb 07 jmp short _18.1001e501
|
||||
* 1001e4fa c745 08 1f000000 mov dword ptr ss:[ebp+0x8],0x1f
|
||||
* 1001e501 8b45 08 mov eax,dword ptr ss:[ebp+0x8]
|
||||
* 1001e504 8ad0 mov dl,al
|
||||
* 1001e506 80f2 20 xor dl,0x20
|
||||
* 1001e509 80c2 5f add dl,0x5f
|
||||
* 1001e50c 80fa 3b cmp dl,0x3b
|
||||
* 1001e50f 0f87 80010000 ja _18.1001e695
|
||||
* 1001e515 0fb60e movzx ecx,byte ptr ds:[esi]
|
||||
* 1001e518 c1e0 08 shl eax,0x8
|
||||
* 1001e51b 0bc1 or eax,ecx
|
||||
* 1001e51d b9 01000000 mov ecx,0x1 ; jichi: hook here
|
||||
* 1001e522 03f1 add esi,ecx
|
||||
* 1001e524 8945 08 mov dword ptr ss:[ebp+0x8],eax
|
||||
* 1001e527 8975 0c mov dword ptr ss:[ebp+0xc],esi
|
||||
* 1001e52a 3d 79810000 cmp eax,0x8179
|
||||
* 1001e52f 0f85 9d000000 jnz _18.1001e5d2
|
||||
* 1001e535 8b4d f0 mov ecx,dword ptr ss:[ebp-0x10]
|
||||
* 1001e538 56 push esi
|
||||
* 1001e539 8d55 d0 lea edx,dword ptr ss:[ebp-0x30]
|
||||
* 1001e53c 52 push edx
|
||||
* 1001e53d e8 0e0bffff call _18.1000f050
|
||||
* 1001e542 8d4d d0 lea ecx,dword ptr ss:[ebp-0x30]
|
||||
* 1001e545 c745 fc 07000000 mov dword ptr ss:[ebp-0x4],0x7
|
||||
* 1001e54c ff15 500a0e10 call dword ptr ds:[0x100e0a50] ; _19.6a712fa9
|
||||
* 1001e552 84c0 test al,al
|
||||
* 1001e554 75 67 jnz short _18.1001e5bd
|
||||
* 1001e556 8b75 f0 mov esi,dword ptr ss:[ebp-0x10]
|
||||
* 1001e559 8d45 d0 lea eax,dword ptr ss:[ebp-0x30]
|
||||
* 1001e55c 50 push eax
|
||||
* 1001e55d 8bce mov ecx,esi
|
||||
* 1001e55f c745 e4 01000000 mov dword ptr ss:[ebp-0x1c],0x1
|
||||
* 1001e566 c745 e0 00000000 mov dword ptr ss:[ebp-0x20],0x0
|
||||
* 1001e56d e8 5e80ffff call _18.100165d0
|
||||
* 1001e572 0fb7f8 movzx edi,ax
|
||||
* 1001e575 57 push edi
|
||||
* 1001e576 8bce mov ecx,esi
|
||||
* 1001e578 e8 c380ffff call _18.10016640
|
||||
* 1001e57d 85c0 test eax,eax
|
||||
* 1001e57f 74 0d je short _18.1001e58e
|
||||
* 1001e581 f640 38 02 test byte ptr ds:[eax+0x38],0x2
|
||||
* 1001e585 74 07 je short _18.1001e58e
|
||||
* 1001e587 c745 e0 01000000 mov dword ptr ss:[ebp-0x20],0x1
|
||||
* 1001e58e 837d bc 10 cmp dword ptr ss:[ebp-0x44],0x10
|
||||
* 1001e592 74 29 je short _18.1001e5bd
|
||||
* 1001e594 8b43 28 mov eax,dword ptr ds:[ebx+0x28]
|
||||
* 1001e597 85c0 test eax,eax
|
||||
*/
|
||||
bool InsertRUGP2Hook()
|
||||
{
|
||||
auto module = GetModuleHandleW(L"vm60.dll");
|
||||
if (!module /*|| !SafeFillRange(L"vm60.dll", &low, &high)*/) {
|
||||
ConsoleOutput("rUGP2: vm60.dll does not exist");
|
||||
return false;
|
||||
}
|
||||
const BYTE bytes[] = {
|
||||
0x0f,0xb6,0x0e, // 1001e515 0fb60e movzx ecx,byte ptr ds:[esi]
|
||||
0xc1,0xe0, 0x08, // 1001e518 c1e0 08 shl eax,0x8
|
||||
0x0b,0xc1, // 1001e51b 0bc1 or eax,ecx
|
||||
0xb9, 0x01,0x00,0x00,0x00, // 1001e51d b9 01000000 mov ecx,0x1 ; jichi: hook here
|
||||
0x03,0xf1, // 1001e522 03f1 add esi,ecx
|
||||
0x89,0x45, 0x08, // 1001e524 8945 08 mov dword ptr ss:[ebp+0x8],eax
|
||||
0x89,0x75, 0x0c // 1001e527 8975 0c mov dword ptr ss:[ebp+0xc],esi
|
||||
};
|
||||
enum { addr_offset = 0x1001e51d - 0x1001e515 };
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), (DWORD)module, Util::QueryModuleLimits(module).second);
|
||||
//GROWL_DWORD(addr);
|
||||
if (!addr) {
|
||||
ConsoleOutput("rUGP2: pattern not found");
|
||||
return false;
|
||||
}
|
||||
if (!module /*|| !SafeFillRange(L"vm60.dll", &low, &high)*/)
|
||||
{
|
||||
ConsoleOutput("rUGP2: vm60.dll does not exist");
|
||||
return false;
|
||||
}
|
||||
const BYTE bytes[] = {
|
||||
0x0f, 0xb6, 0x0e, // 1001e515 0fb60e movzx ecx,byte ptr ds:[esi]
|
||||
0xc1, 0xe0, 0x08, // 1001e518 c1e0 08 shl eax,0x8
|
||||
0x0b, 0xc1, // 1001e51b 0bc1 or eax,ecx
|
||||
0xb9, 0x01, 0x00, 0x00, 0x00, // 1001e51d b9 01000000 mov ecx,0x1 ; jichi: hook here
|
||||
0x03, 0xf1, // 1001e522 03f1 add esi,ecx
|
||||
0x89, 0x45, 0x08, // 1001e524 8945 08 mov dword ptr ss:[ebp+0x8],eax
|
||||
0x89, 0x75, 0x0c // 1001e527 8975 0c mov dword ptr ss:[ebp+0xc],esi
|
||||
};
|
||||
enum
|
||||
{
|
||||
addr_offset = 0x1001e51d - 0x1001e515
|
||||
};
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), (DWORD)module, Util::QueryModuleLimits(module).second);
|
||||
// GROWL_DWORD(addr);
|
||||
if (!addr)
|
||||
{
|
||||
ConsoleOutput("rUGP2: pattern not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
HookParam hp;
|
||||
hp.address = addr + addr_offset;
|
||||
hp.offset=get_reg(regs::eax);
|
||||
hp.type = NO_CONTEXT|CODEC_ANSI_BE;
|
||||
ConsoleOutput("INSERT rUGP2");
|
||||
return NewHook(hp, "rUGP2");
|
||||
}
|
||||
HookParam hp;
|
||||
hp.address = addr + addr_offset;
|
||||
hp.offset = get_reg(regs::eax);
|
||||
hp.type = NO_CONTEXT | CODEC_ANSI_BE;
|
||||
ConsoleOutput("INSERT rUGP2");
|
||||
return NewHook(hp, "rUGP2");
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
bool InsertRUGPHook()
|
||||
{ return InsertRUGP1Hook() || InsertRUGP2Hook(); }
|
||||
namespace
|
||||
{
|
||||
// マブラヴ オルタネイティヴ クロニクルズ04
|
||||
bool h3()
|
||||
{
|
||||
|
||||
bool RUGP::attach_function() {
|
||||
|
||||
return InsertRUGPHook();
|
||||
auto low = GetModuleHandleW(L"rvmm.dll");
|
||||
if (!low)
|
||||
return false;
|
||||
auto [s, e] = Util::QueryModuleLimits(low);
|
||||
auto caller = findiatcallormov((DWORD)GetGlyphOutlineA, (DWORD)low, s, e);
|
||||
ConsoleOutput("%p", caller);
|
||||
if (!caller)
|
||||
return false;
|
||||
auto func = findfuncstart(caller, 0x200, true);
|
||||
if (!func)
|
||||
return false;
|
||||
// a2 == 33088
|
||||
BYTE sig[] = {0x81, XX, 0x40, 0x81, 0x00, 0x00};
|
||||
if (!MemDbg::findBytes(sig, sizeof(sig), func, caller))
|
||||
return false;
|
||||
auto refs = findxref_reverse_checkcallop(func, s, e, 0xe8);
|
||||
if (refs.size() == 1)
|
||||
{
|
||||
auto f2 = findfuncstart(refs[0], 0x100, true);
|
||||
if (f2)
|
||||
{
|
||||
HookParam hp;
|
||||
hp.address = f2;
|
||||
hp.offset = get_stack(2);
|
||||
hp.type = CODEC_ANSI_BE;
|
||||
return NewHook(hp, "rUGP3");
|
||||
}
|
||||
}
|
||||
HookParam hp;
|
||||
hp.address = func;
|
||||
hp.offset = get_stack(2);
|
||||
hp.split = get_stack(1);
|
||||
hp.type = NO_CONTEXT | CODEC_ANSI_BE | USING_SPLIT;
|
||||
return NewHook(hp, "rUGP3");
|
||||
}
|
||||
}
|
||||
bool InsertRUGPHook()
|
||||
{
|
||||
return InsertRUGP1Hook() || InsertRUGP2Hook();
|
||||
}
|
||||
|
||||
bool RUGP::attach_function()
|
||||
{
|
||||
|
||||
return InsertRUGPHook() || h3();
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
|
||||
|
||||
class RUGP:public ENGINE{
|
||||
public:
|
||||
RUGP(){
|
||||
|
||||
check_by=CHECK_BY::CUSTOM;
|
||||
check_by_target=[](){
|
||||
return (wcsstr(processName_lower,L"rugp") || Util::CheckFile(L"rugp.exe"));
|
||||
class RUGP : public ENGINE
|
||||
{
|
||||
public:
|
||||
RUGP()
|
||||
{
|
||||
|
||||
check_by = CHECK_BY::CUSTOM;
|
||||
check_by_target = []()
|
||||
{
|
||||
return (wcsstr(processName_lower, L"rugp") || Util::CheckFile(L"rugp.exe"));
|
||||
};
|
||||
};
|
||||
bool attach_function();
|
||||
bool attach_function();
|
||||
};
|
Loading…
Reference in New Issue
Block a user