>为了卸载时能解除钩子,在Unit MESS 单元最后加上一句:
finalization
Un_API_hook;
当然,别忘了对MESS 做相应修改。编译好后别忘了存盘。新建Application TRY2 程序,主Form 的单元名称不妨叫TRYUnit2,在Form1 上添加三个Button,并声明:
procedure StartHook; stdcall; external 'TRYDLL.DLL';
procedure StopHook; stdcall; external 'TRYDLL.DLL';
三个Button 的OnClick 代码如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
StartHook;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MessageBoxA(Form1.Handle,'NO HOOK UP A','MessageBoxA',MB_OK);
MessageBoxW(Form1.Handle,'NO HOOK UP W','MessageBoxW',MB_OK);
MessageBox (Form1.Handle,'NO HOOK UP BOX','MessageBox',MB_OK);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
StopHook;
end;
编译好后运行吧。这次倒好,无论你怎样测试,都得不到钩上的信息。整理一下我们的工作吧:TRY2 运行 --> TryDLL 加载 --> 运行API_Hookup,为TryDLL 挂上MyBox。即使我们按下了Button1,其他的进程加载了TryDLL,也仅仅是运行API_Hookup,为TryDLL 挂上MyBox 而已,而其他的进程(包括TRY2 本身)并没有挂上MyBox。不信,你可以在TryDLL 中加上一个启动MyBox 的函数,测试一下。例如,你可以在T r y D L L 的S t o p H o o k 函数中的UnhookWindowsHookEx 语句前,加上一句:MessageBoxW(0,'MessageBoxW','这是测试DLL是否加载了MyBox',MB_OK);你可以看到弹出窗口中的信息是“成功挂上W!”而不是“MessageBoxW”。并且由于我们的TryDLL 加载时就启动了API_Hookup,卸载时才运行Un_API_Hook,所以不论你是否按下Button1 和Button3,并且不论你按下了几次,每次你按下Button3 都会得到“成功挂上W!”的信息。看来,真正的麻烦才刚刚开始。实际上,我们刚才的工作都是有用的。我们剩下的工作就是改进Unit APIHook 中的TrueFunctionAddress 函数而已。想不到吧?为了能让其他的进程挂上MyBox,我们必须了解一下PE文件的格式。
3.PE文件格式
分配表、页模式、虚拟内存、内存映射..够写一本书的了吧?我这儿只想简单地说两句。PE文件格式是Windows 9X以上版本和Windows NT操作系统中广泛采用的32 位可执行文件格式。与16 位的NE 格式不同的是,