mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-11-24 22:35:36 +08:00
270 lines
13 KiB
C++
270 lines
13 KiB
C++
#include"Rejet.h"
|
||
|
||
namespace { // unnamed Rejet
|
||
/**
|
||
* jichi 12/22/2013: Rejet
|
||
* See (CaoNiMaGeBi): http://www.hongfire.com/forum/printthread.php?t=36807&pp=40&page=172
|
||
* See (CaoNiMaGeBi): http://tieba.baidu.com/p/2506179113
|
||
* Pattern: 2bce8bf8
|
||
* 2bce sub ecx,esi ; hook here
|
||
* 8bf8 mov eds,eax
|
||
* 8bd1 mov edx,ecx
|
||
*
|
||
* Examples:
|
||
* - Type1: ドットカレシ-We're 8bit Lovers!: /HBN-4*0@A5332:DotKareshi.exe
|
||
* length_offset: 1
|
||
* off: 0xfffffff8 (-0x8)
|
||
* type: 1096 (0x448)
|
||
*
|
||
* processStartAddress = 10e0000 (variant)
|
||
* hook_addr = processStartAddress + reladdr = 0xe55332
|
||
* 01185311 . FFF0 PUSH EAX ; beginning of a new function
|
||
* 01185313 . 0FC111 XADD DWORD PTR DS:[ECX],EDX
|
||
* 01185316 . 4A DEC EDX
|
||
* 01185317 . 85D2 TEST EDX,EDX
|
||
* 01185319 . 0F8F 45020000 JG DotKares.01185564
|
||
* 0118531F . 8B08 MOV ECX,DWORD PTR DS:[EAX]
|
||
* 01185321 . 8B11 MOV EDX,DWORD PTR DS:[ECX]
|
||
* 01185323 . 50 PUSH EAX
|
||
* 01185324 . 8B42 04 MOV EAX,DWORD PTR DS:[EDX+0x4]
|
||
* 01185327 . FFD0 CALL EAX
|
||
* 01185329 . E9 36020000 JMP DotKares.01185564
|
||
* 0118532E . 8B7424 20 MOV ESI,DWORD PTR SS:[ESP+0x20]
|
||
* 01185332 . E8 99A9FBFF CALL DotKares.0113FCD0 ; hook here
|
||
* 01185337 . 8BF0 MOV ESI,EAX
|
||
* 01185339 . 8D4C24 14 LEA ECX,DWORD PTR SS:[ESP+0x14]
|
||
* 0118533D . 3BF7 CMP ESI,EDI
|
||
* 0118533F . 0F84 1A020000 JE DotKares.0118555F
|
||
* 01185345 . 51 PUSH ECX ; /Arg2
|
||
* 01185346 . 68 E4FE5501 PUSH DotKares.0155FEE4 ; |Arg1 = 0155FEE4
|
||
* 0118534B . E8 1023F9FF CALL DotKares.01117660 ; \DotKares.00377660
|
||
* 01185350 . 83C4 08 ADD ESP,0x8
|
||
* 01185353 . 84C0 TEST AL,AL
|
||
*
|
||
* - Type2: ドットカレシ-We're 8bit Lovers! II: /HBN-8*0@A7AF9:dotkareshi.exe
|
||
* off: 4294967284 (0xfffffff4 = -0xc)
|
||
* length_offset: 1
|
||
* type: 1096 (0x448)
|
||
*
|
||
* processStartAddress: 0x12b0000
|
||
*
|
||
* 01357ad2 . fff0 push eax ; beginning of a new function
|
||
* 01357ad4 . 0fc111 xadd dword ptr ds:[ecx],edx
|
||
* 01357ad7 . 4a dec edx
|
||
* 01357ad8 . 85d2 test edx,edx
|
||
* 01357ada . 7f 0a jg short dotkares.01357ae6
|
||
* 01357adc . 8b08 mov ecx,dword ptr ds:[eax]
|
||
* 01357ade . 8b11 mov edx,dword ptr ds:[ecx]
|
||
* 01357ae0 . 50 push eax
|
||
* 01357ae1 . 8b42 04 mov eax,dword ptr ds:[edx+0x4]
|
||
* 01357ae4 . ffd0 call eax
|
||
* 01357ae6 > 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
|
||
* 01357aea . 33ff xor edi,edi
|
||
* 01357aec . 3979 f4 cmp dword ptr ds:[ecx-0xc],edi
|
||
* 01357aef . 0f84 1e020000 je dotkares.01357d13
|
||
* 01357af5 . 8b7424 20 mov esi,dword ptr ss:[esp+0x20]
|
||
* 01357af9 . e8 7283fbff call dotkares.0130fe70 ; jichi: hook here
|
||
* 01357afe . 8bf0 mov esi,eax
|
||
* 01357b00 . 3bf7 cmp esi,edi
|
||
* 01357b02 . 0f84 0b020000 je dotkares.01357d13
|
||
* 01357b08 . 8d5424 14 lea edx,dword ptr ss:[esp+0x14]
|
||
* 01357b0c . 52 push edx ; /arg2
|
||
* 01357b0d . 68 cc9f7501 push dotkares.01759fcc ; |arg1 = 01759fcc
|
||
* 01357b12 . e8 e9f9f8ff call dotkares.012e7500 ; \dotkares.012c7500
|
||
* 01357b17 . 83c4 08 add esp,0x8
|
||
* 01357b1a . 84c0 test al,al
|
||
* 01357b1c . 74 1d je short dotkares.01357b3b
|
||
* 01357b1e . 8d46 64 lea eax,dword ptr ds:[esi+0x64]
|
||
* 01357b21 . e8 bad0f8ff call dotkares.012e4be0
|
||
* 01357b26 . 68 28a17501 push dotkares.0175a128 ; /arg1 = 0175a128 ascii "<br>"
|
||
*
|
||
* - Type2: Tiny×MACHINEGUN: /HBN-8*0@4CEB8:TinyMachinegun.exe
|
||
* processStartAddress: 0x12f0000
|
||
* There are two possible places to hook
|
||
*
|
||
* 0133cea0 . fff0 push eax ; beginning of a new function
|
||
* 0133cea2 . 0fc111 xadd dword ptr ds:[ecx],edx
|
||
* 0133cea5 . 4a dec edx
|
||
* 0133cea6 . 85d2 test edx,edx
|
||
* 0133cea8 . 7f 0a jg short tinymach.0133ceb4
|
||
* 0133ceaa . 8b08 mov ecx,dword ptr ds:[eax]
|
||
* 0133ceac . 8b11 mov edx,dword ptr ds:[ecx]
|
||
* 0133ceae . 50 push eax
|
||
* 0133ceaf . 8b42 04 mov eax,dword ptr ds:[edx+0x4]
|
||
* 0133ceb2 . ffd0 call eax
|
||
* 0133ceb4 > 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
|
||
* 0133ceb8 . 33db xor ebx,ebx ; jichi: hook here
|
||
* 0133ceba . 3959 f4 cmp dword ptr ds:[ecx-0xc],ebx
|
||
* 0133cebd . 0f84 d4010000 je tinymach.0133d097
|
||
* 0133cec3 . 8b7424 20 mov esi,dword ptr ss:[esp+0x20]
|
||
* 0133cec7 . e8 f4f90100 call tinymach.0135c8c0 ; jichi: or hook here
|
||
* 0133cecc . 8bf0 mov esi,eax
|
||
* 0133cece . 3bf3 cmp esi,ebx
|
||
* 0133ced0 . 0f84 c1010000 je tinymach.0133d097
|
||
* 0133ced6 . 8d5424 14 lea edx,dword ptr ss:[esp+0x14]
|
||
* 0133ceda . 52 push edx ; /arg2
|
||
* 0133cedb . 68 44847d01 push tinymach.017d8444 ; |arg1 = 017d8444
|
||
* 0133cee0 . e8 eb5bfdff call tinymach.01312ad0 ; \tinymach.011b2ad0
|
||
*
|
||
* - Type 3: 剣が君: /HBN-8*0@B357D:KenGaKimi.exe
|
||
*
|
||
* 01113550 . fff0 push eax
|
||
* 01113552 . 0fc111 xadd dword ptr ds:[ecx],edx
|
||
* 01113555 . 4a dec edx
|
||
* 01113556 . 85d2 test edx,edx
|
||
* 01113558 . 7f 0a jg short kengakim.01113564
|
||
* 0111355a . 8b08 mov ecx,dword ptr ds:[eax]
|
||
* 0111355c . 8b11 mov edx,dword ptr ds:[ecx]
|
||
* 0111355e . 50 push eax
|
||
* 0111355f . 8b42 04 mov eax,dword ptr ds:[edx+0x4]
|
||
* 01113562 . ffd0 call eax
|
||
* 01113564 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
|
||
* 01113568 33ff xor edi,edi
|
||
* 0111356a 3979 f4 cmp dword ptr ds:[ecx-0xc],edi
|
||
* 0111356d 0f84 09020000 je kengakim.0111377c
|
||
* 01113573 8d5424 14 lea edx,dword ptr ss:[esp+0x14]
|
||
* 01113577 52 push edx
|
||
* 01113578 68 dc6a5401 push kengakim.01546adc
|
||
* 0111357d e8 3eaff6ff call kengakim.0107e4c0 ; hook here
|
||
*/
|
||
bool FindRejetHook(LPCVOID pattern, DWORD pattern_size, DWORD hook_off, DWORD hook_offset, LPCSTR hook_name = "Rejet")
|
||
{
|
||
// Offset to the function call from the beginning of the function
|
||
//enum { addr_offset = 0x21 }; // Type1: hex(0x01185332-0x01185311)
|
||
//const BYTE pattern[] = { // Type1: Function start
|
||
// 0xff,0xf0, // 01185311 . fff0 push eax ; beginning of a new function
|
||
// 0x0f,0xc1,0x11, // 01185313 . 0fc111 xadd dword ptr ds:[ecx],edx
|
||
// 0x4a, // 01185316 . 4a dec edx
|
||
// 0x85,0xd2, // 01185317 . 85d2 test edx,edx
|
||
// 0x0f,0x8f // 01185319 . 0f8f 45020000 jg DotKares.01185564
|
||
//};
|
||
//GROWL_DWORD(processStartAddress);
|
||
ULONG addr = processStartAddress; //- sizeof(pattern);
|
||
do {
|
||
//addr += sizeof(pattern); // ++ so that each time return diff address
|
||
ULONG range = min(processStopAddress - addr, MAX_REL_ADDR);
|
||
addr = MemDbg::findBytes(pattern, pattern_size, addr, addr + range);
|
||
if (!addr) {
|
||
//ITH_MSG(L"failed");
|
||
ConsoleOutput("Rejet: pattern not found");
|
||
return false;
|
||
}
|
||
|
||
addr += hook_off;
|
||
//GROWL_DWORD(addr);
|
||
//GROWL_DWORD(*(DWORD *)(addr-3));
|
||
//const BYTE hook_ins[] = {
|
||
// /*0x8b,*/0x74,0x24, 0x20, // mov esi,dword ptr ss:[esp+0x20]
|
||
// 0xe8 //??,??,??,??, 01357af9 e8 7283fbff call DotKares.0130fe70 ; jichi: hook here
|
||
//};
|
||
} while(0xe8202474 != *(DWORD *)(addr - 3));
|
||
|
||
ConsoleOutput("INSERT Rejet");
|
||
HookParam hp;
|
||
hp.address = addr; //- 0xf;
|
||
hp.type = NO_CONTEXT|DATA_INDIRECT|FIXING_SPLIT;
|
||
hp.offset = hook_offset;
|
||
|
||
return NewHook(hp, hook_name);
|
||
}
|
||
bool InsertRejetHook1() // This type of hook has varied hook address
|
||
{
|
||
const BYTE bytes[] = { // Type1: Function start
|
||
0xff,0xf0, // 01185311 . fff0 push eax ; beginning of a new function
|
||
0x0f,0xc1,0x11, // 01185313 . 0fc111 xadd dword ptr ds:[ecx],edx
|
||
0x4a, // 01185316 . 4a dec edx
|
||
0x85,0xd2, // 01185317 . 85d2 test edx,edx
|
||
0x0f,0x8f // 01185319 . 0f8f 45020000 jg DotKares.01185564
|
||
};
|
||
// Offset to the function call from the beginning of the function
|
||
enum { addr_offset = 0x21 }; // Type1: hex(0x01185332-0x01185311)
|
||
enum { hook_offset = -0x8 }; // hook parameter
|
||
return FindRejetHook(bytes, sizeof(bytes), addr_offset, hook_offset);
|
||
}
|
||
bool InsertRejetHook2() // This type of hook has static hook address
|
||
{
|
||
const BYTE bytes[] = { // Type2 Function start
|
||
0xff,0xf0, // 01357ad2 fff0 push eax
|
||
0x0f,0xc1,0x11, // 01357ad4 0fc111 xadd dword ptr ds:[ecx],edx
|
||
0x4a, // 01357ad7 4a dec edx
|
||
0x85,0xd2, // 01357ad8 85d2 test edx,edx
|
||
0x7f, 0x0a, // 01357ada 7f 0a jg short DotKares.01357ae6
|
||
0x8b,0x08, // 01357adc 8b08 mov ecx,dword ptr ds:[eax]
|
||
0x8b,0x11, // 01357ade 8b11 mov edx,dword ptr ds:[ecx]
|
||
0x50, // 01357ae0 50 push eax
|
||
0x8b,0x42, 0x04, // 01357ae1 8b42 04 mov eax,dword ptr ds:[edx+0x4]
|
||
0xff,0xd0, // 01357ae4 ffd0 call eax
|
||
0x8b,0x4c,0x24, 0x14 // 01357ae6 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
|
||
};
|
||
// Offset to the function call from the beginning of the function
|
||
enum { addr_offset = 0x27 }; // Type2: hex(0x0133CEC7-0x0133CEA0) = hex(0x01357af9-0x1357ad2)
|
||
enum { hook_offset = -0xc }; // hook parameter
|
||
return FindRejetHook(bytes, sizeof(bytes), addr_offset, hook_offset);
|
||
}
|
||
bool InsertRejetHook3() // jichi 12/28/2013: add for 剣が君
|
||
{
|
||
// The following pattern is the same as type2
|
||
const BYTE bytes[] = { // Type2 Function start
|
||
0xff,0xf0, // 01357ad2 fff0 push eax
|
||
0x0f,0xc1,0x11, // 01357ad4 0fc111 xadd dword ptr ds:[ecx],edx
|
||
0x4a, // 01357ad7 4a dec edx
|
||
0x85,0xd2, // 01357ad8 85d2 test edx,edx
|
||
0x7f, 0x0a, // 01357ada 7f 0a jg short DotKares.01357ae6
|
||
0x8b,0x08, // 01357adc 8b08 mov ecx,dword ptr ds:[eax]
|
||
0x8b,0x11, // 01357ade 8b11 mov edx,dword ptr ds:[ecx]
|
||
0x50, // 01357ae0 50 push eax
|
||
0x8b,0x42, 0x04, // 01357ae1 8b42 04 mov eax,dword ptr ds:[edx+0x4]
|
||
0xff,0xd0, // 01357ae4 ffd0 call eax
|
||
0x8b,0x4c,0x24, 0x14 // 01357ae6 8b4c24 14 mov ecx,dword ptr ss:[esp+0x14]
|
||
};
|
||
// Offset to the function call from the beginning of the function
|
||
//enum { addr_offset = 0x27 }; // Type2: hex(0x0133CEC7-0x0133CEA0) = hex(0x01357af9-0x1357ad2)
|
||
enum { hook_offset = -0xc }; // hook parameter
|
||
ULONG addr = processStartAddress; //- sizeof(bytes);
|
||
while (true) {
|
||
//addr += sizeof(bytes); // ++ so that each time return diff address
|
||
ULONG range = min(processStopAddress - addr, MAX_REL_ADDR);
|
||
addr = MemDbg::findBytes(bytes, sizeof(bytes), addr, addr + range);
|
||
if (!addr) {
|
||
//ITH_MSG(L"failed");
|
||
ConsoleOutput("Rejet: pattern not found");
|
||
return false;
|
||
}
|
||
addr += sizeof(bytes);
|
||
// Push and call at once, i.e. push (0x68) and call (0xe8)
|
||
// 01185345 52 push edx
|
||
// 01185346 . 68 e4fe5501 push dotkares.0155fee4 ; |arg1 = 0155fee4
|
||
// 0118534b . e8 1023f9ff call dotkares.01117660 ; \dotkares.00377660
|
||
enum { start = 0x10, stop = 0x50 };
|
||
// Different from FindRejetHook
|
||
DWORD i;
|
||
for (i = start; i < stop; i++)
|
||
if (*(WORD *)(addr + i - 1) == 0x6852 && *(BYTE *)(addr + i + 5) == 0xe8) // 0118534B-01185346
|
||
break;
|
||
if (i < stop) {
|
||
addr += i;
|
||
break;
|
||
}
|
||
} //while(0xe8202474 != *(DWORD *)(addr - 3));
|
||
|
||
//GROWL_DWORD(addr - processStartAddress); // = 0xb3578 for 剣が君
|
||
|
||
ConsoleOutput("INSERT Rejet");
|
||
// The same as type2
|
||
HookParam hp;
|
||
hp.address = addr; //- 0xf;
|
||
hp.type = NO_CONTEXT|DATA_INDIRECT|FIXING_SPLIT;
|
||
hp.offset = hook_offset;
|
||
|
||
return NewHook(hp, "Rejet");
|
||
}
|
||
} // unnamed Rejet
|
||
|
||
bool InsertRejetHook()
|
||
{ return InsertRejetHook2() || InsertRejetHook1() || InsertRejetHook3(); } // insert hook2 first, since 2's pattern seems to be more unique
|
||
|
||
|
||
bool Rejet::attach_function() {
|
||
|
||
return InsertRejetHook();
|
||
}
|