|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
前几天突然心血来潮想写个全局钩子的小程序,期间遇到个一直无法解决的问题,就是程序设置钩子没问题,一旦解除钩子就会导致其它运行的程序奔溃。
短短几行代码,左改右改,该查的资料都查了,就是没有解决,中途时不时的想放弃不弄了,但是本着不找到问题原因不放弃的原则,最后终于找到问题所在。
费话不多说,本文目的是分享经验,没有技术含量,看到最后你才知道什么叫惊不惊喜意不意外。
主要代码:
dll
- // 传递消息
- function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
- begin
- Result := CallNextHookEx(hhk, nCode, wParam, lParam);
- end;
- // 开始HOOK
- function StartHook(pid: DWORD):Boolean; stdcall;
- begin
- hhk := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, HInstance, 0);
- Result := hhk<>0;
- end;
- // 结束HOOK
- function EndHook:Boolean; stdcall;
- begin
- Result := UnhookWindowsHookEx(hhk);
- if Result then hhk := 0;
- end;
复制代码
症状:
运行的程序 一 一 奔溃,explorer.exe也不例外。
主要过程:
过程1:在项目中把所有无关的代码删除,只保留了设置钩子和取消钩子的代码
- // 传递消息
- function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
- begin
- Result := CallNextHookEx(hhk, nCode, wParam, lParam);
- end;
- // 开始HOOK
- function StartHook(pid: DWORD):Boolean; stdcall;
- begin
- hhk := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, HInstance, 0);
- Result := hhk<>0;
- end;
- // 结束HOOK
- function EndHook:Boolean; stdcall;
- begin
- Result := UnhookWindowsHookEx(hhk);
- if Result then hhk := 0;
- end;
复制代码 结果:设置钩子没问题,一旦解除钩子就会导致其它运行的程序奔溃。
过程2:另外新建项目把相关代码边复制边测试以便查找问题。
结果是把所有代码都移过去后发现程序运行正常了(解除钩子不会导致其它程序崩溃)。
心里想问题到底在哪里呀?这也不至于啊,就这样算了吧反正是正常了,再想想还是要找到问题,要是以后又遇到那不是又得折腾。
问题在这里:
经过2个项目代码进行排查,终于找到这该死的问题。
有问题的dll代码:
- library MyHookdll;
- uses
- SysUtils,
- Classes,
- Windows, Vcl.Dialogs;
- var
- hhk: HHOOK = 0;
- // 传递消息
- function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
- begin
- Result := CallNextHookEx(hhk, nCode, wParam, lParam);
- end;
- // 开始HOOK
- function StartHook(pid: DWORD):Boolean; stdcall;
- begin
- hhk := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, HInstance, 0);
- Result := hhk<>0;
- end;
- // 结束HOOK
- function EndHook:Boolean; stdcall;
- begin
- Result := UnhookWindowsHookEx(hhk);
- if Result then hhk := 0;
- end;
- exports
- StartHook, EndHook;
- begin
- end.
复制代码
dll正常代码:
- library MyHookdll;
- uses
- SysUtils,
- Classes,
- Windows;
- var
- hhk: HHOOK = 0;
- // 传递消息
- function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
- begin
- Result := CallNextHookEx(hhk, nCode, wParam, lParam);
- end;
- // 开始HOOK
- function StartHook(pid: DWORD):Boolean; stdcall;
- begin
- hhk := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, HInstance, 0);
- Result := hhk<>0;
- end;
- // 结束HOOK
- function EndHook:Boolean; stdcall;
- begin
- Result := UnhookWindowsHookEx(hhk);
- if Result then hhk := 0;
- end;
- exports
- StartHook, EndHook;
- begin
- end.
复制代码
对比2处代码,仅仅是引用了Vcl.Dialogs组件库便导致程序产生了致命的问题。
就问你们惊不惊喜意不意外。 |
评分
-
查看全部评分
|