介绍:HOOK API是指截获特定进程或系统对某个API函数的调用,使得API的执行流程转向指定的代码。Windows下的应用程序都建立在API函数至上,所以截获API是一项相当有用的技术,它使得用户有机会干预其它应用程序的程序流程。
最常用的一种挂钩API的方法是改变目标进程中调用API函数的代码,使得它们对API的调用变为对用户自定义函数的调用。
HOOK API和HOOK技术完全不同。尽管它们都是钩子。HOOK钩的是消息,它在系统将消息传递给应用程序之前截获它,然后进行操作、或修改消息、或停止消息的传递;而HOOK API截获的是应用程序对系统API的调用,它在应用程序对系统API的调用之前截获此调用动作,让其转而调用我们所定义的函数(内容可能是进行一些操作后再调用原系统API)。
关于HOOK技术,微软为我们提供了现成的API,有固定的使用步骤。
而对于HOOK API技术,微软并没有向我们提供类似的API,没有那么简洁的步骤可供我们参考,也许是因为微软并不希望我们用这样的手段编程,所以相对要麻烦一些。
以下为《windows核心编程》学习笔记:
windows编程中,有些时候必须要打破进程的界限。访问另一个进程的地址空间。这些情况包括:
1.当你想要为另一个进程创建的窗口建立子类时,即为此窗口指定新的窗口过程函数。
2.当你需要调试帮助时。
3.当你想要挂接其它进程时(HOOK API?)。
一旦你的DLL插入到另一个进程的地址空间,就可以对另一个进程为所欲为。
一、为另一个进程创建的窗口建立一个子类。
建立子类就能改变窗口的行为特性。若要建立子类,只需要调用SetWindowLongPtr函数,改变窗口的内存块中的窗口过程地址,指向一个新的(你自己的)WndProc。
当调用下面所示的SetWindowLongPtr函数,建立一个窗口的子类时,你告诉系统,发送到或者显示在hwnd设定的窗口中的所有消息都应该送往MySubclassProc,而不是送往窗口正常的窗口过程:
SetWindowLongPtr(hwnd,GWLP_WNDPROC,MySubclassProc);
换句话说,当系统需要将消息发送到指定窗口的WndProc时,要查看它的地址,然后直接调用WndProc。在这里,系统发现MySubclassProc函数的地址与窗口相关联,因此就直接调用MySubclassProc函数。
窗口函数被调用的过程是这样的:如,进程A正在运行,并且已经创建了一个窗口。文件User32.dll被映射到进程A的地址空间中。对User32.dll文件的映射是为了接收和发送在进程A中运行的任何线程创建的任何窗口中发送和显示的消息(USER32.DLL里含有DispatchMessage函数,函数为:
LONG DispatchMessage (CONST MSG *msg){
LONG lResult;
WNDPROC lpfnWndProc =
(WNDPROC)GetWindowLongPtr(msg.hwnd, GWLP_WNDPROC);
lResult = lpfnWndProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
return (lResult);
}
)。
当User32.dll的映像发现一个消息时,它首先要确定窗口的WndProc的地址,然后调用该地址,传递窗口的句柄、消息和wParam和lParam值。当WndProc处理该消息后,User32.dll便循环运行,并等待另一个窗口消息被处理。
若想在进程B中为进程A的线程所创建的窗口建立子类(即指定窗口过程函数),在进程B中就需要得到目标窗口的句柄,方法很多,如FindWindow。
但是,由于进程的边界问题,Microsoft决定不让SetWindowLongPtr改变另一个进程创建的窗口过程。不是SetWindowLongPtr不能为窗口指定窗口过程函数,而是由于进程的边界问题,使得这样不具有可操作性。如果能将子类过程(MySubclassProc)的代码放入进程A的地址空间,就可以方便地调用SetWindowLongPtr函数,将进程A的地址传递给MySubclassProc函数。将这个方法成为将DLL(含有MySubclassProc的代码)“插入”进程的地址空间。有若干种方法可以用来进行这项操作。
1.使用注册表来插入DLL
2.使用Windows挂钩来插入DLL
3.使用远程线程来插入DLL
分别来学习一下:
1.使用注册表来插入DLL
这种方式是在注册表中的 HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs关键字里保存要加载的dll文件名(或包含路径)