I am trying to learn how to do a JMP hook properly.
I want to change the operation of some ASM.
Code:
warrock:004F73C4 ; ---------------------------------------------------------------------------
warrock:004F73C4
warrock:004F73C4 loc_4F73C4: ; CODE XREF: sub_4F70A8+311j
warrock:004F73C4 8B 46 14 mov eax, [esi+14h]
warrock:004F73C7 83 C0 46 add eax, 46h
warrock:004F73CA 68 28 11 8E 00 push offset aCc02 ; "CC02"
warrock:004F73CF 50 push eax
warrock:004F73D0 FF D7 call edi ; msvcr90_stricmp
warrock:004F73D2 59 pop ecx
warrock:004F73D3 59 pop ecx
warrock:004F73D4 85 C0 test eax, eax
warrock:004F73D6 75 22 jnz short loc_4F73FA
warrock:004F73D8 8B 83 68 01 00 00 mov eax, [ebx+168h]
warrock:004F73DE C6 83 66 01 00 00 01 mov byte ptr [ebx+166h], 1
warrock:004F73E5 83 F8 02 cmp eax, 2
warrock:004F73E8 74 36 jz short loc_4F7420
warrock:004F73EA 85 C0 test eax, eax
warrock:004F73EC 75 4C jnz short loc_4F743A
warrock:004F73EE C7 83 68 01 00 00 01 00 00 00 mov dword ptr [ebx+168h], 1
warrock:004F73F8 EB 40 jmp short loc_4F743A
My asm:
Code:
mov edi, 8C14F8h
push 8E1120h
push eax
call edi
pop ecx
pop ecx
test eax, eax
jnz 8C14F8h
mov byte ptr[ebx + 34154h], 0
jmp[ajnz2]
mov eax, CALLBACK
jmp eax
And my C++
Code:
#include <windows.h>
#include <stdio.h>
using namespace std;
void DoHook(DWORD* Address, DWORD* Hook){ //LEECHED
/*
This time it's not as easy as in part 1 where we could just replace one pointer to point at our hook.
Here we need to replace 5 bytes with our jump code, E9 ** ** ** ** (where ** = offset bytes)
Luckily can just place them at the start of the Sleep() function so that we're sure they get executed
To do that we first need to change the memory protection so that we can write to it (we can't by default)
*/
DWORD OldProt; // -5 is there because the offset bytes of the jump instruction are relative to the address of the jump instruction, so the 5 bytes (length of the jump instruction) must be subtracted
DWORD HookOffset = (DWORD)Hook-(DWORD)Address-5; // calculate the offset bytes and store the result into hookoffset
VirtualProtect((void*) Address, 40, 0x40, &OldProt); // change the memory protection and give us write access.
char* CharPointer = (char*) Address; // sizeof(char) == 1, 0E9h == 1, we need a char for the size
*CharPointer = '\xE9'; // *CharPointer(Sleep()) now equals E9h (the jump opcode)
// we now need to place the operands
CharPointer++; // the size problem again, incrementing Address (Address++) would result in the pointer advancing 4 bytes
Address = (DWORD*)CharPointer; // Advance the pointer with 1 byte to where the offset bytes need to come
*Address = HookOffset; // the correct offset
VirtualProtect((void*) Address, 40, 0x40, &OldProt); // change the memory protection back to the old values (it doesn't really matter if we do this or not, but it's just proper)
return;// the hook is set!
}
DWORD* CALLBACK = (DWORD*)0x4F743A;
__declspec(naked) void jmp(){
__asm{
mov edi, 8C14F8h
push 8E1120h
push eax
call edi
pop ecx
pop ecx
test eax, eax
jnz 8C14F8h
mov byte ptr[ebx + 34154h], 1
jmp[ajnz2]
mov eax, CALLBACK
jmp eax
}
}
void SearchPatterns(void)
{
while (true){
if (GetAsyncKeyState(VK_CONTROL) & 1){
DWORD* AddressOf = (DWORD*)0x4F73A7;
DoHook(AddressOf, (DWORD*)&jmp);
}
}
}
BOOL WINAPI DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)SearchPatterns, NULL, NULL, NULL);
}
return TRUE;
}
And i crash after the JMP hook..
An example of this would be nice ^_^