您的位置:首页 > 其它

在入口函数Hook的分析

2009-02-10 11:20 162 查看
// DemoKing2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdio.h>
#include <windows.h>

// 保存原始的5个字节代码,注意一定要保证完整
BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90};
BYTE save_code[10] = {0x90, 0x90, 0x90, 0x90, 0x90};
// JMP 0xXXXXXXXX
BYTE hook_code[5] = { 0xe9, 0, 0, 0, 0 };
BYTE jmp_orig_code[5] = { 0xe9, 0, 0, 0, 0};

int func(int a,char *str);
int fake_func(int a,char *str);
void hook_func();
int jmp_back(int a,char *str);

int main(int argc, char **argv)
{
int ret;
hook_func();
ret = func(110,"pklang");
return ret;
}

int func(int a,char *str)
{

printf("I'm func(),I'm called! a:%d,str:%s/r/n",a,str);
return 0;
}

void hook_func()
{
DWORD dwOldProtect;

#ifdef _DEBUG
//Debug 模式时是用jmp跳转表,所以要算出真正的函数地址
#define  PATCH 6

DWORD fake_funcAddr=   (DWORD)fake_func+*(PDWORD)((DWORD)fake_func+1)+5;
DWORD funcAddr=         (DWORD)func+*(PDWORD)((DWORD)func+1)+5;
DWORD jmp_backAddr=    (DWORD)jmp_back+*(PDWORD)((DWORD)jmp_back+1)+5;
#else
#define  PATCH 8

DWORD fake_funcAddr=   (DWORD)fake_func;
DWORD funcAddr=         (DWORD)func;
DWORD jmp_backAddr=    (DWORD)jmp_back;
#endif

*((PDWORD)(hook_code+1) ) = (DWORD)fake_funcAddr - (DWORD)funcAddr - 5;

//save old code
//要看看入口地址前五个字节是否完整为汇编指令的,如果不是要补成完整指令
//比如fun函数在debug模式开头为
//	004010A0 >/> /55            push    ebp           //1个字节
//	004010A1  |.  8BEC          mov     ebp, esp      //2个字节
//	004010A3  |.  83EC 40       sub     esp, 40       //3个字节
//	004010A6  |.  53            push    ebx           //所以加起来至少要6个字节
//	004010A7  |.  56            push    esi
//而Release模式fun开头汇编为
//	00401020  /$  8B4424 08     mov     eax, dword ptr [esp+8]  //4个字节
//	00401024  |.  8B4C24 04     mov     ecx, dword ptr [esp+4]  //4个字节
//	00401028  |.  50            push    eax                     //所以加起来至少要8个字节
//	00401029  |.  51            push    ecx

memcpy(save_code,(LPVOID)funcAddr,PATCH);

// 修改原始入口
VirtualProtect((LPVOID)funcAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy((BYTE *)funcAddr, hook_code, 5);
VirtualProtect((LPVOID)funcAddr, 5, dwOldProtect, &dwOldProtect);

//设置原函数地址
*( (PDWORD)(jmp_orig_code+1) ) = (ULONG)funcAddr - (ULONG)jmp_backAddr -5;
VirtualProtect((LPVOID)jmp_backAddr, 15, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy((BYTE *)jmp_backAddr, save_code, PATCH);
memcpy((BYTE *)((DWORD)jmp_backAddr+PATCH), jmp_orig_code, 5);
VirtualProtect((LPVOID)jmp_backAddr, 15, dwOldProtect, &dwOldProtect);

}
//4011ba
__declspec(naked) int jmp_back(int a,char *str)
{
__asm
{
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
}

}

int fake_func(int a,char *str)
{
int ret;
printf("I'm fake_func(),I'm called! a:%d,str:%s/r/n",a,str);
ret = jmp_back(a,str);
return ret;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: