具体来说,我们将通过image_import_descriptor数组来访问“.idata”段中引入
的dll的信息,然后通过image_thunk_data数组来针对一个被引入的dll访问该
dll中被引入的每个函数的信息,找到我们需要截获的函数的跳转地址,然后改
成我们自己的函数的地址……具体的做法在后面的关键代码中会有详细的讲解。
讲了这么多原理,现在让我们回到“鼠标屏幕取词”的专题上来。除了api函
数的截获,要实现“鼠标屏幕取词”,还需要做一些其它的工作,简单的说来,
可以把一个完整的取词过程归纳成以下几个步骤:
1. 安装鼠标钩子,通过钩子函数获得鼠标消息。
使用到的api函数:setwindowshookex
2. 得到鼠标的当前位置,向鼠标下的窗口发重画消息,让它调用系统函数重画
窗口。
使用到的api函数:windowfrompoint,screentoclient,invalidaterect
3. 截获对系统函数的调用,取得参数,也就是我们要取的词。
对于大多数的windows应用程序来说,如果要取词,我们需要截获的是
“gdi32.dll”中的“textouta”函数。
我们先仿照textouta函数写一个自己的mytextouta函数,如:
bool winapi mytextouta(hdc hdc, int nxstart, int nystart, lpcstr lpszstring,int cbstring)
{
// 这里进行输出lpszstring的处理
// 然后调用正版的textouta函数
}
把这个函数放在安装了钩子的动态连接库中,然后调用我们最后给出的
hookimportfunction函数来截获进程对textouta函数的调用,跳转到我们的
mytextouta函数,完成对输出字符串的捕捉。Hookimportfunction的用法:
hookfuncdesc hd;
proc porigfuns;
hd.szfunc="textouta";
hd.pproc=(proc)mytextouta;
hookimportfunction (afxgetinstancehandle(),"gdi32.dll",&hd,porigfuns);
下面给出了hookimportfunction的源代码,相信详尽的注释一定不会让您觉得理
解截获到底是怎么实现的很难,ok,let’s go:
///////////////////////////////////////////// begin ///////////////////////////////////////////////////////////////
#include <crtdbg.h>
// 这里定义了一个产生指针的宏
#define makeptr(cast, ptr, addvalue) (cast)((dword)(ptr)+(dword)(addvalue))
// 定义了hookfuncdesc结构,我们用这个结构作为参数传给hookimportfunction函数
typedef struct tag_hookfuncdesc
{
lpcstr szfunc; // the name of