A、InLine HOOK 原理分析
B、InLine HOOK 代码编写
C、InLine HOOK 代码测试
课时:33
在 021_绕过驱动保护 已经讲过一次 in line hook
_declspec(naked)
#pragma pack(1)
//前5字节
77D507EA > 8BFF MOV EDI,EDI
77D507EC /. 55 PUSH EBP
77D507ED |. 8BEC MOV EBP,ESP
My_MessageBoxA地址 401020
============================================
笔记:
在21课时讲过内联HOOK,本课再继续深入讲解.用VC6新建代码inlineHook_test控制台程序,新建一个MessageBoxA,然后用另一个函数my_MessageBox进行参数与原函数相同.我们在OD里看一下这MessageBoxA函数,将前面几个字节改成JMP XXXXXX,先找到我们自己的函数地址是00401020,然后修改代码跳到这里.在OD中修改了代码之后出现了两次的HOOK成功,应该是有两个地方调用了代码.又修改后打印自己的地址信息,信息正确但是报错,我们需要加上恢复函数头部的代码,但是还是出错了,再加上一条_declspec(naked)生成干脆的汇编
// inlineHook_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "hook_test.h"
#include <windows.h>
_declspec(naked) int My_MessageBox
(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
)
{
__asm //恢复函数头部
{ mov bx,bx //特征码定位
PUSH EBP
MOV EBP,ESP
}
printf("Hook Ok %x,%s,%s,%x \n",hWnd,lpText,lpCaption,uType);
__asm
{
jmp oldMessageBoxA+5 //HOOK后又跳回
}
__asm pop ebp //堆栈平衡
__asm retn 0x10 //堆栈平衡
}
int main(int argc, char* argv[])
{
// printf("Hello World!\n");
MessageBoxA(NULL,"Hook Test Contect","hook",MB_OK);
printf("End Process \n");
getchar();
return 0;
}
已经成功了,原理清楚后再用一下之前已经写好的hook_test.h
#include <windows.h>
typedef int (__stdcall *MessageBox_type)(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
) ;
MessageBox_type old_MessageBoxA;
#pragma pack(1)
typedef struct _JMPCODE
{
BYTE jmp;
DWORD addr;
}JMPCODE,*PJMPCODE;
_declspec(naked)
VOID __stdcall my_MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
)
{
// old_MessageBoxA(hWnd,"Hook ok",lpCaption,uType);
__asm
{
PUSH EBP
MOV EBP,ESP
}
printf("取得参数%x,%s,%s,%x\n",hWnd,lpText,lpCaption,uType);
__asm
{
mov ebx,old_MessageBoxA
add ebx,5
jmp ebx
}
printf("hook Error\n");
}
VOID InLine_HookMessageBoxA()
{ JMPCODE jcode;
//取得MessageBoxA函数当前地址
HMODULE h=LoadLibraryA("user32.dll");
old_MessageBoxA=(MessageBox_type)(GetProcAddress(h,"MessageBoxA"));
//替换jmp指令
jcode.jmp=0xe9;
jcode.addr=(DWORD)(&my_MessageBox)-(DWORD)(&MessageBoxA)-5;//目的地址-当前地址-5 //跳到my
old_MessageBoxA=&MessageBoxA;
WriteProcessMemory(GetCurrentProcess(),&MessageBoxA,&jcode,sizeof(JMPCODE),NULL);
CloseHandle(h);
}
int main(int argc, char* argv[])
{
printf("Hello World!\n");
InLine_HookMessageBoxA();
MessageBoxA(NULL,"333","222",MB_OK);
return 0;
}
代码过程:通过LoadLibrarA(“user32.dll”);来取得原有MessageBoxA函数地址,然后写入我们的HOOK代码, 通过公式计算执行到我们自己的函数处,执行完后再恢复原有函数.最后在OD里详细的看清HOOK流程.这种内联HOOK用于保护/盗密等,应用比较广泛. |