赞
踩
对查找的Hook资料进行以下总结(部分来自转载以及抄录)
什么是hook
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
Hook 分类
系统消息Hook(微软官方提供的方法 Ring3)
SetWindowsHookEx
UnhookWindowsHookEx
CallNextHookEx
API Hook(非官方方法 Ring0/Ring3)
使用汇编代码编替换函数开始的汇编代码,使其跳转到我们的Hook函数中,非官方叫法:Inline hook
使用Hook函数地址替换调用函数地址(IAT hook/SSDT hook … …)
Hook API的原理,以及思路
系统的API加载到应用程序控件都有一个对应的地址,而我们可以通过修改windows API头部五个字节标识的标识来实现windows函数的跳转(具体这5个字节是做什么用的,找汇编大佬)。这样铜鼓修改的api地址,系统调用的时候便会跳转到我们准备的函数进行执行了,当然,调用完我们的函数以后还是要调用原本的函数以确保系统函数调用正常。
现在我们要知道我们要怎么Hook API,假设我们程序现在要调用一个MessageBox函数,那么我们把这个API Hook了,变为我们的API去执行,执行完我们的代码之后再去执行它的的函数.
其实相当于就是我们在这个API之前,跳转到我们的函数执行了,然后跳转之后,我们执行完毕之后,可以选择是否在跳转回去,但是这里注意,跳转回去则跳转到msg的return处位置即可.
eax可以给一个值,让它返回.利用这个技术,我们可以监控API,比如应用程序会调用loadLibrary,那我们把它Hook了,把Dll路径改成我们的,那加载的就是我们的dll了,当然 Hook的API很多,因为只要是Windows的API都能HOOK,因为JMP的时候占五个字节,而WindowsAPI也是头部弄了五个字节,猜想可能是Windows自己留作Hook的。
如何修改函数头部的5个字节,贴一下大佬的代码
BOOL init()//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令
{
hModule=LoadLibrary("user32.dll");
pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA");
if(pfMessageBoxA==NULL)
return false;
_asm
{
lea edi,OldMessageBoxACode
mov esi,pfMessageBoxA
cld
movsd
movsb
}
NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令
_asm
{
lea eax,MyMessageBoxA
mov ebx,pfMessageBoxA
sub eax,ebx
sub eax,5
mov dword ptr [NewMessageBoxACode+1],eax
}
dwIdNew=GetCurrentProcessId(); //得到所属进程的ID
dwIdOld=dwIdNew;
HookOn();//开始拦截
return(true);
}
另外,还需要定义我们自己的hook函数
int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType )//首先关闭拦截,然后才能调用被拦截的Api 函数
{
int nReturn=0;
HookOff();
nReturn=MessageBoxA(hWnd,"MessageBox已经被截获,呵呵!",lpCaption,uType);
HookOn();
return(nReturn);
}
进行hook操作的函数
void HookOn()
{
HANDLE hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写
WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性
bHook=true;
}
void HookOff()//将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA
{
HANDLE hProc;
dwIdOld=dwIdNew;
hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);
VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);
WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0);
VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);
bHook=false;
}
大体代码差不多就这些,对于hook API的代码,一般会封装到对应的DLL中去,要实现函数的hook,就需要目标进程中对该dll进行加载。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。