{ win9X,NT,w2k 中的系统日志钩子示例程序(Delphi 版) ----------------------------------------------------- windows下的日志钩子是一种很有用的HOOK类型,他不需要动态链接库*.DLL,就能实现 系统级的事件监控,它只能监视两种硬件的事件,即鼠标,键盘的操作,而不能监视其它 消息,被记录的消息可以用日志回放钩子将它还原,下面这个程序用Delphi设计,没有 用delphi的控件,只用了win32 api,所以通用于Delphi的任何版本,当然你也可以用c 来实现,有看不懂的可以写信给我,这是第一版,可能有BUG,大家发现了通知我一下,欢 迎大家和我一起来讨论HOOK技术: ----------------------------------------------------- First Created:njhhack 2001.6.14 (ver1.0) 电子信箱:[email protected] 主页:hotsky.363.net } Program Journal; //包含如下头文件 uses windows,messages,sysutils; {$r *.res} //使用资源文件 //定义一个新的结构类型 type TWin = record Msg:TMsg; wClass:TWndClass; hMain:integer; lr:trect; tem:TEVENTMSG; end; var Win:TWin; //结构变量 HHJournalRecordProc:integer; //日志钩子句柄 //将字符串str写到文件c:\key.txt中 procedure SaveInfo(str:string);stdcall; var f:textfile; fname:string; begin fname:='c:\key.txt'; assignfile(f,fname); if fileexists(fname)=false then rewrite(f) else append(f); writeln(f,str); closefile(f); end;
//将信息写到屏幕 procedure writestr; var hdc:integer; str:string; begin hdc:=getdc(win.hmain); RoundRect(hdc,10,10,240,140,12,8); with win.tem do begin str:=format('窗口句柄=%x',[hwnd]); textout(hdc,30,24*1,pchar(str),length(str)); str:=format('鼠标位置=(%d,%d)',[paraml,paramh]); textout(hdc,30,24*2,pchar(str),length(str)); str:=format('消息类型=%x',[message]); textout(hdc,30,24*3,pchar(str),length(str)); str:=format('时间=%d',[time div 1000]); textout(hdc,30,24*4,pchar(str),length(str)); end; releasedc(win.hmain,hdc); end; //日志钩子的回调函数 function JournalRecordProc(nCode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall; begin win.tem:=TEVENTMSG(PEVENTMSG(lParam)^); if nCode>=0 then begin with win.tem do begin with win.lr do begin left:=10; top:=10; right:=240; bottom:=140; end; InvalidateRect(win.hmain,@win.lr,false); if message=wm_lbuttondown then begin SaveInfo(format('窗口句柄=%x,鼠标位置=(%d,%d),消息类型=WM_LBUTTONDOWN,时间=%d',[hwnd,paraml,paramh,time div 1000])); end; end; end; Result:=CallNextHookEx(HHJournalRecordProc,nCode,wParam,lParam); //调用下一个钩子 end; //钩子设置和删除函数 procedure SetHook(fSet:boolean); begin if fSet=true then begin if HHJournalRecordProc=0 then HHJournalRecordProc:=SetWindowsHookEx(WH_JOURNALRECORD,@JournalRecordProc,hinstance,0); end else begin if HHJournalRecordProc<>0 then UnhookWindowsHookEx(HHJournalRecordProc); end; end; //主程序的回调函数 function WindowProc(hWnd,Msg,wParam,lParam:longint):LRESULT; stdcall; begin Result:=DefWindowProc(hWnd,Msg,wParam,lParam); case Msg of wm_paint:writestr; wm_destroy:begin SetHook(False);halt;end; end; end; //主程序的执行函数 procedure run;stdcall; begin win.wClass.hInstance:= hInstance; with win.wclass do begin hIcon:= LoadIcon(hInstance,'MAINICON'); hCursor:= LoadCursor(0,IDC_ARROW); hbrBackground:= COLOR_BTNFACE+1; Style:= CS_PARENTDC; lpfnWndProc:= @WindowProc; lpszClassName:='JournalRecordHook'; end; RegisterClass(win.wClass); win.hmain:=CreateWindow(win.wClass.lpszClassName,'系统日志钩子演示程序',WS_VISIBLE or WS_OVERLAPPEDWINDOW,10,10,260,180,0,0,hInstance,nil); SetHook(true); while(GetMessage(win.Msg,win.hmain,0,0))do begin TranslateMessage(win.Msg); DispatchMessage(win.Msg); end; end;