问题遇到的现象和发生背景
问题相关代码,请勿粘贴截图
运行结果及报错内容
我的解答思路和尝试过的方法
我想要达到的结果
亲爱的朋友,你好。我按照您提供的代码,尝试3环InlineHook,我用的visual stuio 2010,弄了两天,也没弄出来。现贴上我的代码,请您有空的话,帮我看下。谢谢
#include <stdio.h>
#include <windows.h>
BYTE* ProcAddr = 0; //原函数地址
DWORD OldProtect = 0; //保存旧的内存保护
BYTE OldCmd[20] = {0}; //存储原函数头部原始指令 在最后面构造返回到原函数的指令
BYTE* HookProcAddr = 0; //钩子函数的地址
//函数指针 将数据作为指令执行
typedef void (POLDCMD)();
POLDCMD pOldCmd = (POLDCMD)(char)OldCmd;
//printf的格式
char *format = "%x";
DWORD add(DWORD a, DWORD b)
{
return a + b;
}
void __declspec(naked) HookProc()
{
//保存现场
__asm
{
pushad
pushfd
}
//获得参数1
printf("a = %d",5);
__asm
{
mov eax, esp
ADD eax, 0x28
push [eax]
push format
call printf//这里一直提示不对
//mov esp,ebp
ADD esp, 8
}
//获得参数2
//printf("\nb = ");
__asm
{
mov eax, esp
add eax, 0x2c
push [eax]
push format
call printf
add esp, 8
}
printf("\n");
//还原现场
__asm
{
popfd
popad
//执行原函数头部指令 并返回到原函数下一行继续执行
jmp pOldCmd
}
}
void InlineHook()
{
//获得需要挂钩的函数地址
ProcAddr = (BYTE*)add + 1;//为何要加1
ProcAddr += (DWORD)ProcAddr + 4;//为何要加4
//修改内存保护
VirtualProtect(ProcAddr, 9, PAGE_EXECUTE_READWRITE, &OldProtect);
//将被覆盖的指令复制到数组中
strncpy((char*)OldCmd, (char*)ProcAddr, 9);
//数组末尾添上跳转指令 用于返回到被挂钩的函数
OldCmd[9] = 0xE9;
(DWORD)&OldCmd[10] = (DWORD)(ProcAddr+9) - (DWORD)&OldCmd[9] - 5;
//获得钩子函数的地址
HookProcAddr = (BYTE*)HookProc + 1;
HookProcAddr += *(DWORD*)HookProcAddr + 4;
//修改原函数的头部 跳转到钩子函数
ProcAddr[0] = 0xE9;
*(DWORD*)&ProcAddr[1] = HookProcAddr - ProcAddr - 5;
//跳转指令只占五个字节 原函数头部三行指令占9个字节 因此将多余字节填充为nop
ProcAddr[5] = 0x90;
ProcAddr[6] = 0x90;
ProcAddr[7] = 0x90;
ProcAddr[8] = 0x90;
}
void UnInlineHook()
{
//判断函数是否被挂钩
if(ProcAddr[0] == 0xE9)
{
strncpy((char*)ProcAddr, (char*)OldCmd, 9);
}
}
int main()
{
DWORD sum;
//挂钩
InlineHook();
sum = add(1, 2);
printf("sum = %x\n", sum);
//脱钩
UnInlineHook();
sum = add(3, 4);
printf("sum = %x\n", sum);
return 0;
}