刚接触hook,比着葫芦画瓢,出现问题了
大部分代码引用自 Ring3下Inline Hook MessageBox(演示) http://bbs.pediy.com/showthread.php?t=69666
经我测试该文作者的代码也存在同样问题
下面是我的代码:
BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90};//存放原始的指令
BYTE hook_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到MyMessageBoxA的指令
BYTE jmp_org_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到原起始地址后5字节的指令
int _stdcall MyMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
int MyFunc();
void Hook();
int jmp_back();
ULONG OldFuncAddr;
ULONG MyFuncAddr;
ULONG jmp_backAddr;
int main()
{
int rt = MessageBoxA(NULL, "Hello World1", "Title", MB_OK);
Hook();
rt = MessageBoxA(NULL, "Hello World2", "Title", MB_OK);
system("pause");
return 0;
}
void Hook()
{
DWORD dwOldProtect;
OldFuncAddr = (ULONG)MessageBoxA;
//MyMessageBoxA函数相对EIP的偏移量
MyFuncAddr = *(ULONG*)((BYTE *)MyMessageBoxA+1);
//当前指令地址+本条指令的长度+偏移
MyFuncAddr = *(ULONG *)((BYTE *)MyMessageBoxA+1) + (ULONG)MyMessageBoxA + 5;
// jmp_backAddr = jmp_back的实际地址
jmp_backAddr = *(ULONG *)((BYTE *)jmp_back+1) + (ULONG)jmp_back + 5;
//修改内存为PAGE_EXECUTE_READWRITE
VirtualProtect((LPVOID)jmp_backAddr, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect);
VirtualProtect((LPVOID)OldFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
//计算跳转地址
//hook函数离原函数的距离
//hook函数的地址 - 原函数的地址 - JMP指令长度 = 偏移量
*((ULONG*)(hook_code+1)) = (ULONG)MyFuncAddr - (ULONG)OldFuncAddr - 5;
memcpy(orig_code,(BYTE *)OldFuncAddr, 5);
memcpy((BYTE*)OldFuncAddr, hook_code, 5);
//计算返回地址
*((ULONG*)(jmp_org_code+1)) = (ULONG)OldFuncAddr - (ULONG)jmp_backAddr - 5;
//还原数据
memcpy((BYTE *)jmp_backAddr, orig_code, 5);
//返回地址
memcpy((BYTE *)jmp_backAddr + 5, jmp_org_code, 5);
}
__declspec(naked) int jmp_back()
{
__asm
{
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
}
}
//MyMessageBoxA:在函数执行前进行自己的处理
__declspec(naked) int _stdcall MyMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
printf("MyMessageBoxA is called\r\n");
MyFunc();////可以加入函数过程
__asm
{
//跳回MessageBoxA入口点
jmp jmp_back;
}
}
int MyFunc()
{
printf("Hello World\r\n");
return 1;
}
以上代码在win7+vs2010编译运行,报错:vaule of ESP was not properly saved across a function call。请大家帮我看看问题出在哪
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!