mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-11-25 06:45:36 +08:00
180 lines
6.3 KiB
C++
180 lines
6.3 KiB
C++
|
#include"Reallive.h"
|
||
|
|
||
|
|
||
|
/********************************************************************************************
|
||
|
Reallive hook:
|
||
|
Process name is reallive.exe or reallive*.exe.
|
||
|
|
||
|
Technique to find Reallive hook is quite different from 2 above.
|
||
|
Usually Reallive engine has a font caching issue. This time we wait
|
||
|
until the first call to GetGlyphOutlineA. Reallive engine usually set
|
||
|
up stack frames so we can just refer to EBP to find function entry.
|
||
|
|
||
|
********************************************************************************************/
|
||
|
/** jichi 5/13/2015
|
||
|
* RealLive does not work for 水着少女と媚薬アイス from 裸足少女
|
||
|
* 012da80f cc int3
|
||
|
* 012da810 55 push ebp ; jichi: change to hook here
|
||
|
* 012da811 8bec mov ebp,esp
|
||
|
* 012da813 83ec 10 sub esp,0x10 ; jichi: hook here by default
|
||
|
* 012da816 53 push ebx
|
||
|
* 012da817 56 push esi
|
||
|
* 012da818 57 push edi
|
||
|
* 012da819 8b7d 18 mov edi,dword ptr ss:[ebp+0x18]
|
||
|
* 012da81c 81ff 5c810000 cmp edi,0x815c
|
||
|
* 012da822 75 0a jnz short reallive.012da82e
|
||
|
* 012da824 c745 18 9f840000 mov dword ptr ss:[ebp+0x18],0x849f
|
||
|
* 012da82b 8b7d 18 mov edi,dword ptr ss:[ebp+0x18]
|
||
|
* 012da82e b8 9041e301 mov eax,reallive.01e34190
|
||
|
* 012da833 b9 18a49001 mov ecx,reallive.0190a418
|
||
|
* 012da838 e8 a38d0000 call reallive.012e35e0
|
||
|
* 012da83d 85c0 test eax,eax
|
||
|
* 012da83f 74 14 je short reallive.012da855
|
||
|
* 012da841 e8 6addffff call reallive.012d85b0
|
||
|
* 012da846 ba 9041e301 mov edx,reallive.01e34190
|
||
|
* 012da84b b8 18a49001 mov eax,reallive.0190a418
|
||
|
* 012da850 e8 ab7c0000 call reallive.012e2500
|
||
|
* 012da855 8d45 f0 lea eax,dword ptr ss:[ebp-0x10]
|
||
|
* 012da858 50 push eax
|
||
|
* 012da859 8d4d f4 lea ecx,dword ptr ss:[ebp-0xc]
|
||
|
* 012da85c 51 push ecx
|
||
|
* 012da85d 8d55 fc lea edx,dword ptr ss:[ebp-0x4]
|
||
|
* 012da860 52 push edx
|
||
|
* 012da861 8d45 f8 lea eax,dword ptr ss:[ebp-0x8]
|
||
|
* 012da864 50 push eax
|
||
|
* 012da865 8bc7 mov eax,edi
|
||
|
* 012da867 e8 54dfffff call reallive.012d87c0
|
||
|
* 012da86c 8bf0 mov esi,eax
|
||
|
* 012da86e 83c4 10 add esp,0x10
|
||
|
* 012da871 85f6 test esi,esi
|
||
|
* 012da873 75 4b jnz short reallive.012da8c0
|
||
|
* 012da875 8d4d f4 lea ecx,dword ptr ss:[ebp-0xc]
|
||
|
* 012da878 51 push ecx
|
||
|
* 012da879 57 push edi
|
||
|
* 012da87a 8d4d f0 lea ecx,dword ptr ss:[ebp-0x10]
|
||
|
* 012da87d e8 cef0ffff call reallive.012d9950
|
||
|
* 012da882 8bf0 mov esi,eax
|
||
|
* 012da884 83c4 08 add esp,0x8
|
||
|
* 012da887 85f6 test esi,esi
|
||
|
*/
|
||
|
static bool InsertRealliveDynamicHook(LPVOID addr, uintptr_t frame, uintptr_t stack)
|
||
|
{
|
||
|
if (addr != ::GetGlyphOutlineA)
|
||
|
return false;
|
||
|
// jichi 5/13/2015: Find the enclosing caller of GetGlyphOutlineA
|
||
|
if (DWORD i = frame) {
|
||
|
i = *(DWORD *)(i + 4);
|
||
|
for (DWORD j = i; j > i - 0x100; j--)
|
||
|
if (*(WORD *)j == 0xec83) { // jichi 7/26/2014: function starts
|
||
|
// 012da80f cc int3
|
||
|
// 012da810 55 push ebp ; jichi: change to hook here
|
||
|
// 012da811 8bec mov ebp,esp
|
||
|
// 012da813 83ec 10 sub esp,0x10 ; jichi: hook here by default
|
||
|
if (*(DWORD *)(j-3) == 0x83ec8b55)
|
||
|
j -= 3;
|
||
|
|
||
|
HookParam hp;
|
||
|
hp.address = j;
|
||
|
hp.offset=get_stack(5);
|
||
|
hp.split = get_reg(regs::esp);
|
||
|
hp.type = CODEC_ANSI_BE|USING_SPLIT;
|
||
|
//GROWL_DWORD(hp.address);
|
||
|
|
||
|
//RegisterEngineType(ENGINE_REALLIVE);
|
||
|
ConsoleOutput("RealLive: disable GDI hooks");
|
||
|
|
||
|
return NewHook(hp, "RealLive");
|
||
|
}
|
||
|
}
|
||
|
return true; // jichi 12/25/2013: return true
|
||
|
}
|
||
|
void InsertRealliveHook()
|
||
|
{
|
||
|
//ConsoleOutput("Probably Reallive. Wait for text.");
|
||
|
ConsoleOutput("TRIGGER Reallive");
|
||
|
trigger_fun = InsertRealliveDynamicHook;
|
||
|
}
|
||
|
|
||
|
bool RlBabelFilter(LPVOID data, size_t *size, HookParam *)
|
||
|
{
|
||
|
auto text = reinterpret_cast<LPSTR>(data);
|
||
|
auto len = reinterpret_cast<size_t *>(size);
|
||
|
|
||
|
if (text[0] == '\x01') {
|
||
|
StringFilterBetween(text, len, "\x01", 1, "\x02", 1); // remove names
|
||
|
}
|
||
|
|
||
|
CharReplacer(text, len, '\x08', '"');
|
||
|
CharReplacer(text, len, '\x09', '\'');
|
||
|
CharReplacer(text, len, '\x0A', '\'');
|
||
|
CharFilter(text, len, '\x1F'); // remove color
|
||
|
StringReplacer(text, len, "\x89\x85", 2, "\x81\x63", 2); // "\x89\x85"-> shift-JIS"…"
|
||
|
StringReplacer(text, len, "\x89\x97", 2, "--", 2);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool InsertRlBabelHook() {
|
||
|
|
||
|
/*
|
||
|
* Sample games:
|
||
|
* https://vndb.org/r78318
|
||
|
*/
|
||
|
const BYTE bytes[] = {
|
||
|
0xCC, // int 3
|
||
|
0x55, // push ebp <- hook here
|
||
|
0x8B, 0xEC, // mov ebp,esp
|
||
|
0x83, 0xEC, 0x20, // sub esp,20
|
||
|
0xC7, 0x45, 0xFC, XX4 // mov [ebp-04],rlBabel.DLL+16804
|
||
|
};
|
||
|
|
||
|
HMODULE module = GetModuleHandleW(L"rlBabel.dll");
|
||
|
if (!module)
|
||
|
return false;
|
||
|
auto [minAddress, maxAddress] = Util::QueryModuleLimits(module);
|
||
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), minAddress, maxAddress);
|
||
|
if (!addr)
|
||
|
return false;
|
||
|
|
||
|
HookParam hp;
|
||
|
hp.address = addr + 1;
|
||
|
hp.offset=get_reg(regs::eax);
|
||
|
hp.type = USING_STRING;
|
||
|
hp.filter_fun = RlBabelFilter;
|
||
|
ConsoleOutput("INSERT RealLive Babel");
|
||
|
return NewHook(hp, "RealLive Babel");
|
||
|
}
|
||
|
bool Reallive::attach_function() {
|
||
|
InsertRealliveHook();
|
||
|
InsertRlBabelHook();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool avg3216d::attach_function(){
|
||
|
BYTE pattern1[]={
|
||
|
0x3c,0x81,XX2,
|
||
|
0x3c,0x9f,XX2,
|
||
|
0x3c,0xe0,XX2,
|
||
|
0x3c,0xfc,XX2,
|
||
|
};
|
||
|
BYTE pattern2[]={
|
||
|
0x8b,0x75,0x08,
|
||
|
0x8a,0x06,
|
||
|
0x3c,0x81,
|
||
|
0x75,XX,
|
||
|
0x80,0x7e,0x01,0x7a
|
||
|
};
|
||
|
auto addr=MemDbg::findBytes(pattern2,sizeof(pattern2),processStartAddress,processStopAddress);
|
||
|
if(addr==0)return false;
|
||
|
addr=MemDbg::findEnclosingAlignedFunction(addr);
|
||
|
if(addr==0)return false;
|
||
|
auto check=MemDbg::findBytes(pattern1,sizeof(pattern1),addr,addr+0x200);
|
||
|
if(check==0)return false;
|
||
|
HookParam hp;
|
||
|
hp.address = addr;
|
||
|
hp.offset=get_stack(1);
|
||
|
hp.type = NO_CONTEXT|DATA_INDIRECT;
|
||
|
//GROWL_DWORD(hp.address);
|
||
|
return NewHook(hp, "avg3216d");
|
||
|
}
|