請高手出來總結一下HOOK,DLL方面的問題?

yezhiyuan1303 2003-09-30 05:13:05
最近搞這方面的問題,看了一些文章,不是很明白,特別是全局鉤子,DLL數據段共享及內存共享等問題,論壇上有很多這樣的提問,有結驗的寫出來吧,相信有很多人會受益的?請高手們指點!!!!!!
...全文
39 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
cfzxd 2003-10-30
  • 打赏
  • 举报
回复
zihan(子寒):问你一个太低级的问题:回调函数应该放在哪个地方?(button1,button2,还是...)
hb_wxy 2003-10-15
  • 打赏
  • 举报
回复
mark
ccrun.com 2003-10-09
  • 打赏
  • 举报
回复
搞的不太多。虚心学习ing。
jiangchun_xn 2003-10-09
  • 打赏
  • 举报
回复
去google搜比这快。

最好是看msdn,上面讲得很清楚的,比东拼西凑要系统得多。

飞翔的老虎 2003-10-09
  • 打赏
  • 举报
回复
呵呵。没有写这些东东的耐心了:(
yjy1001 2003-10-07
  • 打赏
  • 举报
回复
来学习的
up一下
netyou 2003-10-05
  • 打赏
  • 举报
回复
如果我想通过程序拦截另外一个程序的消息来处理一些事情,但我只知道另外一个程序定义的消息和这个程序的进程句柄,而且这个消息不是用SendMessage发送的,请问如何实现!谢谢
yezhiyuan1303 2003-10-05
  • 打赏
  • 举报
回复
還有高手是不是在休假?怎麼沒有很多人回貼呀,
我說的那兩個問題還是沒有人來講.
zihan 2003-10-03
  • 打赏
  • 举报
回复
来自葵花宝典
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 & KeyPressMask)==KeyPressMask;
bool bCapital=(iCapital & 1)==1;
bool bNumLock=(iNumLock & 1)==1;
if (vKey >=48 && vKey< =57)
// 数字0-9
if (!bShift) fprintf(stream,"%c",vKey);
if (vKey >=65 && 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 && vKey< =105) // 小键盘0-9
if (bNumLock) fprintf(stream,"%c",vKey-96+48);
if (vKey>=186 && 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 && wParam<=123)
// 功能键 [F1]-[F12]
if (vKey >=8 && 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)也同样可以实现,但是用日志钩子却比键盘钩子要方便许多。首先,如果要捕捉其他应用程序的按键,即做成全局钩子,键盘钩子一定要单独放在动态链接库中,而日志钩子却不必;其次,在键盘钩子函数得到的键盘按键之前,系统已经处理过这些输入了,如果系统把这些按键屏蔽掉,键盘钩子就无法检测到它们,例如,当输入屏幕保护程序密码时,键盘钩子无法检测到用户输入了那些字符,而日志钩子却可以检测到。
zihan 2003-10-02
  • 打赏
  • 举报
回复
钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。钩子分为线程专用钩子和全局钩子,线程专用钩子只监视指定的线程,要监视系统中的所有线程,必须用到全局钩子。对于全局钩子,钩子函数必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。在WINDOWS中,日志钩子是个很特别的钩子,它只有全局钩子一种,是键盘鼠标等输入设备的消息在系统消息队列被取出时发生的,而且系统中只能存在一个这样的日志钩子,更重要是,它不必用在动态链接库中,这样可以省却了为安装一个全局钩子而建立一个动态链接库的麻烦。利用日志钩子,我们可以监视各种输入事件.
stwfa 2003-10-02
  • 打赏
  • 举报
回复
正在学习阶段,有什么好的心得,我们交流交流,我得Email:stwfa@163.net
LongWayToGo 2003-10-02
  • 打赏
  • 举报
回复
如何截获日记钩子啊,在*。EXE里面可以直接截获吗,是什么类型,help a!!!!!!!!!!!
appletreestudio 2003-10-01
  • 打赏
  • 举报
回复
Up
yezhiyuan1303 2003-10-01
  • 打赏
  • 举报
回复
学习
Behard 2003-09-30
  • 打赏
  • 举报
回复
我是来听课的
NowCan 2003-09-30
  • 打赏
  • 举报
回复
怎么没人接着说啊?
NowCan 2003-09-30
  • 打赏
  • 举报
回复
简单说一下吧。
1、全局钩子:一般是指能够钩到系统中所有窗口的消息的钩子,即使窗口不属于安装钩子的进程也能钩到。
2、为什么全局钩子必须用DLL形式:这是Windows设计的原因,我们没有办法。WindowsNT为每个进程虚拟了独立的运行空间,互相之间通常不能访问(要访问还是可以的,不过有点不符合WindowsNT的设计初衷),所以要获取其他进程的消息,只能把钩子代码放到那些进程中去,这就用到了DLL。(当然你可能会说,为什么不把安装钩子的exe文件加载过去?理论上也是可以的,但Windows不是这样做的,可能认为太费资源吧,呵呵。)
3、为什么要数据段共享:这个问题简单的解释如下。Windows在加载DLL的时候也是为每个进程加载一个副本,相互独立,即使是其中的全局变量(指C语言中的全局变量的含义)也是互不相干的。这就有一个问题,在钩子函数中一般是需要调用CallNextHook传递消息的,而这个函数需要钩子句柄,对于安装钩子的进程来说钩子句柄可以轻易得到,但对于其他进程中的DLL来说,这个句柄如何得到?(别忘了全局变量也互不相干)在比如,有时我们在钩到特定消息后要给安装钩子的进程发消息通知,一般来说会用PostMessage或SendMessage,对于其他的进程中的DLL来说,这个窗口句柄如何得到?因此需要共享数据段,处于共享数据段中的变量对整个系统共享,因此所有进程中的DLL里共享数据段中的变量值都是一样的,这样就能解决上述问题。

以上纯属个人理解,请各位专家指点。
zihan 2003-09-30
  • 打赏
  • 举报
回复
找季头,他这方面很牛的.不过自己多做做这方面的例子也就会了,

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧