library HOOK;uses
  SysUtils,
  windows,
  Messages;var
  DLLHook: HHOOK;
  Bol: Boolean = False;
  processhandle:Thandle;
  BaseAddress: Pointer;function GetMsgProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
var
 pcs:TMSG;
 H:HWND;
begin
 pcs:=TMSG(PMSG(lParam)^);
 if nCode>=0 then
 begin
 if pcs.message=wm_SHOWWINDOW then
  h:= FindWindow(nil,'ApiHook.pas - 记事本');
  h:= FindWindowEx(h,0,'edit',nil);
  SendMessage(h,WM_SETTEXT,255,Integer(PChar('全局钩子')));
 end;
 Result:=CallNextHookEx(0,nCode,wParam,lParam);
end;{ 状态挂钩 }
function InstallHook(MainHandle: HWND): Boolean; stdcall;
begin
  DLLHook := SetWindowsHookEx(WH_CALLWNDPROC, @GETMSGProc, Hinstance, 0);
  Result := DLLHook <> 0;
end;
procedure inhook;stdcall;
var
 DLLModule: THandle;
begin
  ProcessHandle := GetCurrentProcess;
  DLLModule := LoadLibrary('kernel32.dll');
  { 系统函数入口点地址 }
  BaseAddress := GetProcAddress(DLLModule, 'GetMsgProc');
  INSTALLHOOK(PROCESSHANDLE);end;
{ 卸载挂钩 }
procedure UnHook; stdcall;
begin
  UnhookWindowsHookEx(DLLHook);
//其实这里压根就没用... 
end;procedure MyDLLHandler(Reason: Integer);
begin
 case Reason of
   DLL_PROCESS_ATTACH: inhook;
   DLL_PROCESS_DETACH: UnHook;
 end;
end;

解决方案 »

  1.   

    Hook和UnHook不要同一进程空间.你这是跨进程的hook,  hook是在GetMsgProc函数中,即是回调函数中,它保存API入口地址的地方在目标进程中,
    你必须在目标进程的进程空间内完成卸载操作.而你写的unhook是在自己的进程空间中了,所以没有用.
      

  2.   

    关键地方是:将hook和unhook都在回调函数中做.比如:/*用于WH_GETMESSAGE的Hook Procedure*/
    LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam, LPARAM lParam) {
     if (nCode == HC_ACTION) {
         MSG *msg = (MSG *)lParam;
         if (msg->message == WM_CHAR) {
          if (msg->wParam == 'h') HookApi();     // !!!
          if (msg->wParam == 'u') UnHookApi();   // !!!
         }
     }
        return CallNextHookEx(hHook,nCode,wParam,lParam);
    }
    代码出自这篇文章 :[跨进程hook api].建议你看看
    http://www.qqread.com/vc/j258283.html
      

  3.   

    你这个肯定是键盘钩子... 我的代码直接就钩了,怎么可能在里面调INHOOK UNHOOK
      

  4.   

    http://www.xgdown.com/article/238/42394_5.htm  超级好的东西... 找他真不容易啊...