逆向工程学习录——Detour / Hook Functions

博客围绕游戏逆向展开,以HackMe.exe为例,介绍在游戏逆向中于执行函数处添加代码的方法。目标是hook扣血函数,将其改为double加血。通过Od定位扣血函数,把指令改为jmp [ourFunc]并在其中跳转回来,还说明了代码实现需覆写指令,最后运行游戏并注入dll实现跳转。

在游戏逆向中我们需要在某个执行函数的地方添加自己的代码。
案例:HackMe.exe

每按一次空格扣两滴血
目标:hook扣血函数,改为double加血
在这里插入图片描述
拉进Od后定位到扣血的函数如下图

00BB2740    55              push ebp
00BB2741    8BEC            mov ebp,esp
00BB2743    81EC CC000000   sub esp,0xCC
00BB2749    53              push ebx
00BB274A    56              push esi                                 ; HackMe.<ModuleEntryPoint>
00BB274B    57              push edi                                 ; HackMe.<ModuleEntryPoint>
00BB274C    51              push ecx                                 ; HackMe.<ModuleEntryPoint>
00BB274D    8DBD 34FFFFFF   lea edi,dword ptr ss:[ebp-0xCC]
00BB2753    B9 33000000     mov ecx,0x33
00BB2758    B8 CCCCCCCC     mov eax,0xCCCCCCCC
00BB275D    F3:AB           rep stos dword ptr es:[edi]
00BB275F    59              pop ecx                                  ; kernel32.771F6359
00BB2760    894D F8         mov dword ptr ss:[ebp-0x8],ecx           ; HackMe.<ModuleEntryPoint>
00BB2763    8B45 F8         mov eax,dword ptr ss:[ebp-0x8]
00BB2766    8B08            mov ecx,dword ptr ds:[eax]
00BB2768    2B4D 08         sub ecx,dword ptr ss:[ebp+0x8]
00BB276B    8B55 F8         mov edx,dword ptr ss:[ebp-0x8]
00BB276E    890A            mov dword ptr ds:[edx],ecx               ; HackMe.<ModuleEntryPoint>
00BB2770    8B45 F8         mov eax,dword ptr ss:[ebp-0x8]
00BB2773    8338 00         cmp dword ptr ds:[eax],0x0
00BB2776    7F 07           jg short HackMe.00BB277F
00BB2778    8B45 F8         mov eax,dword ptr ss:[ebp-0x8]
00BB277B    C640 08 01      mov byte ptr ds:[eax+0x8],0x1
00BB277F    5F              pop edi                                  ; kernel32.771F6359
00BB2780    5E              pop esi                                  ; kernel32.771F6359
00BB2781    5B              pop ebx                                  ; kernel32.771F6359
00BB2782    8BE5            mov esp,ebp
00BB2784    5D              pop ebp                                  ; kernel32.771F6359
00BB2785    C2 0400         retn 0x4

地址00BB2768 sub ecx,dword ptr ss:[ebp+0x8]
我们想要把该指令改为jmp [ourFunc]然后在ourFunc中在jmp回来。
在这里插入图片描述

代码实现

#include <Windows.h>

bool Hook(void* toHook, void* ourFunct, int len) {
	if (len < 5) {
		return false;
	}

	DWORD curProtection;
	VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &curProtection);

	memset(toHook, 0x90, len);

	DWORD relativeAddress = ((DWORD)ourFunct - (DWORD)toHook) - 5;

	*(BYTE*)toHook = 0xE9;//jmp
	*(DWORD*)((DWORD)toHook + 1) = relativeAddress;

	DWORD temp;
	VirtualProtect(toHook, len, curProtection, &temp);

	return true;
}

DWORD jmpBackAddy;
void __declspec(naked) ourFunct() {
	__asm {
		add ecx, ecx
		mov edx, [ebp - 8]
		jmp[jmpBackAddy]
	}
}

DWORD WINAPI MainThread(LPVOID param) {
	int hookLength = 6;
	DWORD hookAddress = 0xBB2768;
	jmpBackAddy = hookAddress + hookLength;

	Hook((void*)hookAddress, ourFunct, hookLength);

	while (true) {
		if (GetAsyncKeyState(VK_ESCAPE)) break;
		Sleep(50);
	}

	FreeLibraryAndExitThread((HMODULE)param, 0);

	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) {
	switch (dwReason) {
	case DLL_PROCESS_ATTACH:
		CreateThread(0, 0, MainThread, hModule, 0, 0);
		break;
	}

	return TRUE;
}

由于jmp指令最少占5字节,所以我们必须覆写连同目标指令下一条指令
在这里插入图片描述
连起来为6字节

运行HackMe 并注入dll
在这里插入图片描述
跳转成功
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值