1、基本概念web
2、运行机制线程
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam); HookProc是自定义的名字。 1) 参数是Hook代 码,Hook子程使用这个参数来肯定任务。 2)nCode 这个参数的值依赖于Hook类型,每一种Hook都 有本身的Hook代码特征字符集。 3)wParam和lParam参数的值依赖于nCode,可是它们的典型值 是包含了关于发送或者接收消息的信息。
2、 钩子的安装与释放:
使用API函数SetWindowsHookEx()把一个应用程序定义的钩子回调函数安装到钩子链表中的开头。当指定类 型的Hook监视的事件发生时,系统就调用与这个Hook关联的Hook链的开头的Hook子 程。每个Hook链中的Hook子程都决定是否把这个事件传递到下一个Hook子程。
Hook子程传递事件到下一个Hook子程须要调用API函数CallNextHookEx()。
HHOOK SetWindowsHookEx(intidHook, // 钩子的类型,即它处理的消息类型 钩子回调函数地址, HOOKPROC lpfn, // // 即当钩到了指定类型消息后回调这个函数。 系统钩子则为DLL的 实例句柄, // 线程钩子乃为NULL。 HINSTANCE hMod, // 系统钩子则为 零,线程钩子为指定线程ID。 函数成功则返回钩子的句柄,失败返回NULL。 DWORD dwThreadId); //
发送给(线 程钩子是指定的线程,系统钩子则是所有线程)线程的消息被钩子 回调函数先处理。
在钩子回调函数中完成对消息的处理后,若是想要该消息继续传 递,那么它必须调用另一个SDK中的API函数CallNextHookEx来传递它,以执行钩子链表所指的下一个钩子回调函数。这个函数成功时返回钩子链中 下一个钩子过程的返回值,返回值的类型依赖于钩子的类型。这个函数的原型以下:
LRESULT CallNextHookEx(HHOOKhhk, // SetWindowsHookEx()函数返回的钩子句柄。 int nCode, // 传给钩子过程的事件代码。 WPARAM wParam, // 分别是传给钩子回调函数的参数值, LPARAM lParam); // 其具体含义与钩子类型有关。
钩子函数也能够经过直接返回TRUE来丢弃该消息,并阻止该消息的传递,其余安装了钩子的应用程序将不 会接收到钩子的通知并且还有可能产生不正确的结果。
钩子在使用完以后须要用UnHookWindowsHookEx()卸载,不然会形成麻烦。
BOOL
函数成功返回TRUE, 不然返回FALSE。
3、一些运行机制:
在Win16环境中,DLL的 全局数据对每一个载入它的进程来讲都是相同的;
而在Win32环境中,状况却发生了变化,DLL函数中的代码所建立的任何对象与变量都归调用它的进程全部。当进程在载入DLL时,操做系统自动把DLL映射到该进程的私有空间,也就是进程的虚拟地址空间,并且也复制该DLL的全局变量的一份拷贝到该进程空间。也就是说每一个进程所拥有相同的DLL全局变量,它们的名称相同,但其值却并不必定是相同的,并且是互不 干涉的。
所以,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是经过存储器映射文件技术实现的。 也能够把这些须要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,不然编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
#pragma data_seg预处理指令用于设置共享数据段。例如:
//
#pragma comment(linker, "/section:MyData,rws") #pragma data_seg("MyData") int g_iProNum = -1;#pragma data_seg()
全部对这些数据的操做都针对同一个实例的,而不是在每一个进程 的地址空间中都有一份。
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个 动态库映射到这个进程的虚拟地址空间里(如下简称"地址空间")。这使得DLL成 为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。