编程语言:C/C++
编译环境:Visual Studio 2008
核心方法::通过内联汇编,构造类对象独享的函数(委托),完成了类成员函数到普通全局函数的转化,并在Windows Hook(钩子)编程中得到成功的实践。
关键字:C++,委托,内联汇编,Hook,成员函数
引文:
前段时间曾编写了一个自认为很完善的.NET平台上的Hook(钩子)动态链接库(DLL),并进一步完成了GUI界面,但是在部署时却发现的其局限性,很多用户都没有安装.NET平台,其平台的最小安装(.NET 2.0)也需要21M,如果使用NOMO(2.0)免安装发布的话也需要小10M(而且使用NOMO在自动运行和兼容性上也有待商榷)。
因此,我下定决心,准备彻底和托管代码决裂,回归C/C++,再次实现上述功能,然而真正编写时才发现,经典的C++果然不是盖的,昔日被C的各种调试不通过折磨的记忆还未消退,今日又在开始时陷入苦战,正如前人所说,C++这种强类型语言,喜欢在繁琐的符号和语法上做文章。如果处理不好这些,大概做不了大项目,还是去.NET或Java的快乐平台逍遥去吧~微微感慨,赶快进入正题。
正文:
本文的目的是研究类成员函数与普通函数之区别,以及不同调用方式之间的区别,进而通过内联汇编语句模仿特定的调用,从而完成通过普通函数指针调用类成员函数的功能。因此主要部分为研究和尝试的过程,如希望直接查看Hook编程的结果,可直接查看尾部代码。
使用过Windows Hook编程的同志们都知道,在程序中是通过如下语句来加载钩子,卸载钩子。
C/C++ Code:
- HHOOK SetWindowsHookEx( //加载钩子
- int idHook,
- HOOKPROC lpfn, //钩子函数的指针
- HINSTANCE hMod,
- DWORD dwThreadId
- );
- BOOL UnhookWindowsHookEx( //卸载钩子
- HHOOK hhk
- );
其中最重要的就是HOOKPROC lpfn这个函数指针,查看此函数的形式,为:
C/C++ Code:
- LRESULT CALLBACK HookProcess( //钩子函数
- int nCode,
- WPARAM wParam,
- LPARAM lParam
- );
//其中CALLBACK 的定义为 #define CALLBACK __stdcall
其中,值得注意的是,这个钩子函数需要是一个普通__stdcall调用的C函数,而在C++中可以理解为某个全局函数(非类成员函数,全局访问)或者是一个类的静态函数(static,全局访问)。
让我们再观察一个类成员函数和全局函数的区别,我建立了一个简单的演示代码,如下代码:
C/C++ Code:
- #include
-
- LRESULT CALLBACK HookProcess1( // HookProcess1是一个全局函数
- int nCode,
- WPARAM wParam,
- LPARAM lParam){ return NULL;}
-
- class WinHook
- {
- public:
- int value; //定义一个成员变量,以便于测试访问
- LRESULT CALLBACK HookProcess2(// HookProcess2是一个类的成员函数
- int nCode,
- WPARAM wParam, LPARAM lParam) {
- this->value++; //检查成员变量的访问性
- return NULL;
- }
- };
-
- int main(){
- //定义一个函数指针HookProcess,它可以成功作为参数传递给SetWindowsHookEx
- LRESULT (CALLBACK * HookProcess)
- (int nCode, WPARAM wParam, LPARAM lParam);
- //试图将HookProcess指向HookProcess1
- HookProcess = HookProcess1; //赋值成功,这个指针能够指向全局函数
- HookProcess (0,0,0);//尝试调用之.
- //试图将HookProcess指向HookProcess2
- WinHook *myHook = new WinHook();
- HookProcess = myHook->HookProcess2; //编译失败,提示类型不能转化
- //此句将在之后修改
- HookProcess (0,0,0);//尝试调用之.
- return 0;
- }
查看错误代码,终于发现类的成员函数和普通的全局函数是不一样的,
// error C2440:
//“=”: 无法从“LRESULT (__stdcall WinHook::* )(int,WPARAM,LPARAM)”转换为“LRESULT (__stdcall *)(int,WPARAM,LPARAM)”
关键问题就在于“WinHook::”的区别,可以看到,无论如何,一个类的成员函数(非静态)是不能与普通的C全局函数转化的。这点在后面再详细的说明。
然而,当我们使用C++编程的时候,往往不希望使用全局函数;如果使用类的静态函数,那么一个类只能实现一个钩子,且不能利用C++中类的继承,多态等特性,从实质上沦落为普通C编程。
在网上查找了很多方法,发现可以通过内联汇编语句强制将指针转化,如下:
C/C++ Code:
- //修改上述main中代码,将类成员函数指针强制转化为一般函数指针
- WinHook *myHook = new WinHook();
- //HookProcess = myHook->HookProcess2;
- __asm //NEW: 内联汇编语句
- {
- push eax
- lea eax, WinHook::HookProcess2
- mov HookProcess, eax
- pop eax
- }
- HookProcess (0,0,0);//尝试调用之.
然而在使用这种方法时,却发现了问题,即在底层调用WinHook 的HookProcess2中,其中的this指针为0,因此所有this相关的操作均不可行(即不能访问本对象的其他成员)。此外,在HookProcess2结束后,底层也发现了堆栈不平衡而导致的错误。
继续阅读网上的文章,如
(成员函数指针与高性能的C++委托)
http://www.cnblogs.com/jans2002/archive/2006/10/13/528160.html
(普通函数指针变量可以保存成员函数地址吗?)
http://topic.csdn.net/u/20100905/21/0bfacc26-cdd5-463b-8724-98c626e2b3dc.html
(使非MFC窗口程序的窗口回调过程成为C++类的成员函数)
http://www.systhinker.com/html/90/n-1990.html
等等
我终于理解的类成员函数与普通函数的区别,那就是this指针,当一个类的成员函数被调用时,如:
C/C++ Code:
- WinHook *myHook = new WinHook();
- HookProcess = myHook->HookProcess2(…);
此时,当HookProcess2的参数被传送之后,myHook的地址也被传送在CPU寄存器中(或堆栈中,这要看传调用方式的不同,在之后说明),并在之后在HookProcess2函数中赋值给this,使得类成员函数能够知道调用的是哪个类的对象。
为了测试这一点,我们可以在强制转化了HookProcess2指针之后,在HookProcess2中修复this指针,看函数的this功能是否正常。如下代码:
C/C++ Code:
- class WinHook //修改WinHook类的函数HookProcess2
- {
- public:
- int value; //定义一个成员变量,以便于测试访问
- LRESULT CALLBACK HookProcess2(// HookProcess2是一个类的成员函数
- int nCode,
- WPARAM wParam, LPARAM lParam) {
- //假设主函数中的myHook指针指向0x003d3450,修复this指针
- __asm //内联汇编语句
- {
- push eax //保护eax
- mov eax, 0x003d3450
- mov this, eax //设置本类的this指针(__asm不检查访问性)
- pop eax //还原eax
- }
- //此时查看this指针,就能够发现this正常工作
- this->value++;
- return NULL;
- }
- };
注:虽然this指针能够运行成功,但是函数结束会产生如下错误:
这是由于__stdcall的this传送方式是堆栈,强制访问HookProcess2却未将this压栈会导致堆栈不平衡。因此,将CALLBACK这个修饰符注销掉,即:
C/C++ Code:
- class WinHook //进一步修改WinHook类的函数HookProcess2
- {
- public:
- int value; //定义一个成员变量,以便于测试访问
- LRESULT /*CALLBACK*/ HookProcess2(// HookProcess2是一个类的成员函数
- int nCode,
- WPARAM wParam, LPARAM lParam) {
- //假设主函数中的myHook指针指向0x003d3450,修复this指针
- __asm //内联汇编语句
- {
- push eax //保护eax
- mov eax, 0x003d3450
- mov this, eax //设置本类的this指针(__asm不检查访问性)
- pop eax //还原eax
- }
- //此时查看this指针,就能够发现this正常工作
- this->value++;
- return NULL;
- }
- };
此时,发现整个函数能够顺利运行。(注意,在实际测试时,需要在main中加断点检查myHook的地址,并动态的修改mov eax, 0x003d3450的数值。否则不能测试通过)
这是因为,注销掉CALLBACK的修饰符(即__stdcall)之后,函数采用默认的__thiscall调用方式,此时,this指针是通过CUP寄存器的ecx传送,此时就不会产生堆栈不平衡的错误了。
进一步的,我们遇到的新的问题,尽管能够成功模拟一个类成员函数的调用,修复了this指针,但是对于SetWindowsHookEx来说,每个类的所有成员是共享一个函数空间的。即如下图所示。
因此,如果使用HookProcess2的程序入口(内存首地址)作为SetWindowsHookEx的参数传入,在引发钩子事件的时候就不能够区分到底引发了哪个类的HookProcess2函数,即不能设定this指针。
为了解决这个问题,我们需要生成一个动态的函数入口,这个入口是每个对象独享的,因此不同的对象将引发不同的函数,这就能够区分类的不同对象。根据其他语言对它的描述,我们将这个函数入口暂称为委托(Delegate)。
在实际上,我们是通过定义一个成员变量(如byte类型的数组,可便于的赋值)来实现这个委托的,其中实际上保存了一段机器码,这段机器码(根据汇编语法)可以动态的设定this指针,并实现到真正函数首地址的跳转。这个委托的示意过程如下:
下面说明这个委托的声明和设定代码:
C/C++ Code:
- class WinHook //进一步修改WinHook类的函数HookProcess2
- {
- public:
- byte DelegateThisCall[10]; //定义委托
- WinHook(void){
- //初始化委托
- byte * DelegatePoint = DelegateThisCall;
- DelegateThisCall[0] = 0xb9; //0-4:__asm mov ecx, this
- DelegateThisCall[5] = 0xe9; //5-9:__asm jmp, CoreHookProcess
- __asm
- {
- push eax //保护eax
- push ebx //保护ebx
- mov eax, this //取得this地址
- mov ebx, DelegatePoint //获取DelegateThisCall地址
- mov dword ptr [ebx+1], eax //this 地址, 双字(DWORD)
- }
- //计算jmp地址参考:http://zhidao.baidu.com/question/105950930.html
- __asm
- {
- lea eax, HookProcess2 //取得HookProcess2地址
- mov ebx, DelegatePoint //获取jmp地址= DelegatePoint + 5
- add ebx, 5
- add ebx, 5 //JMP地址=目标地址-(本句地址+本句指令字节数)
- sub eax, ebx //JMP地址= HookProcess2 – [(DelegatePoint+5) + 5]
- mov dword ptr [ebx-4], eax //HookProcess2地址, 双字(DWORD)
- pop ebx //还原ebx
- pop eax //还原eax
- }
- }
- int value; //定义一个成员变量,以便于测试访问
- LRESULT /*CALLBACK*/ HookProcess2(// HookProcess2是一个类的成员函数
- int nCode,
- WPARAM wParam, LPARAM lParam) {
- //查看this指针,就能够发现this正常工作
- this->value++;
- return NULL;
- }
- };
进一步的,修改主函数:
C/C++ Code:
- int main(){
- //定义一个函数指针HookProcess,它可以成功作为参数传递给SetWindowsHookEx
- LRESULT (CALLBACK * HookProcess)
- (int nCode, WPARAM wParam, LPARAM lParam);
- //将HookProcess指向HookProcess2
- WinHook *myHook = new WinHook();
- //HookProcess = myHook->HookProcess2; //赋值失败,提示类型不能转化
- byte * DelegatePoint = myHook->DelegateThisCall; //获取委托首地址
- __asm //内联汇编语句
- {
- push eax
- mov eax, DelegatePoint
- mov HookProcess, eax //强制将委托的地址赋值给函数指针
- pop eax
- }
- HookProcess (0,0,0);//尝试调用之. 调用成功
- return 0;
- }
以上,就成功的完成了类成员函数的钩子过程,通过一个委托,完成了此功能。
最后,为了演示上述方法在建立Windows Hook编程上的使用,特给出编写的动态链接库的实现WinHook功能的BaseHook类的代码,此类完成了成员函数的Hook加载卸载等管理,用户通过继承此类,并重写HookProcess函数(如下),便可完成所有Hook功能。
C/C++ Code:
- //BaseHook 类的虚函数,当Hook事件发生时会调用此函数。
- //用户通过继承并重写此函数完成Hook功能
- virtual LRESULT /*CALLBACK*/ HookProcess
- (int nCode, WPARAM wParam, LPARAM lParam);
源码部分:
C/C++ Code: BaseHook.h
- /********************************************************* {COPYRIGHT-TOP} *
- * RealZYC Confidential
- * OCO Source Materials
- *
- * (C) Copyright RealZYC Corp. 2011 All Rights Reserved.
- *
- * The source code for this program is not published or otherwise
- * divested of its trade secrets, irrespective of what has been
- * deposited with the China Copyright Office.
- ********************************************************** {COPYRIGHT-END} */
- #pragma once
- #include
- /***************************************
- *The basic defination of windows hook
- ****************************************/
- class BaseHook
- {
- /***************************************
- * Enum
- ****************************************/
- #pragma region Enum
- public:
- /***************************************
- *The available types of windows hook
- ****************************************/
- enum HookTypes: int
- {
- //Message filter hook - WH_MSGFILTER = -1
- MsgFilter = -1,
- //Journal record hook - WH_JOURNALRECORD = 0
- JournalRecord = 0,
- //Journal playback hook - WH_JOURNALPLAYBACK = 1
- JournalPlayback = 1,
- //Keyboard hook - WH_KEYBOARD = 2
- Keyboard = 2,
- //Get message hook - WH_GETMESSAGE = 3
- GetMessage = 3,
- //Call wnd proc hook - WH_CALLWNDPROC = 4
- CallWndProc = 4,
- //CBT hook - WH_CBT = 5
- CBT = 5,
- //System message filter hook - WH_SYSMSGFILTER = 6
- SysMsgFilter = 6,
- //Mouse hook - WH_MOUSE = 7
- Mouse = 7,
- //Hardware hook - WH_HARDWARE = 8
- Hardware = 8,
- //Debug hook - WH_DEBUG = 9
- Debug = 9,
- //Shell hook - WH_SHELL = 10
- Shell = 10,
- //Fore ground idle hook - WH_FOREGROUNDIDLE = 11
- ForeGroundIdle = 11,
- //Call wnd proc ret hook - WH_CALLWNDPROCRET = 12
- CallWndProcRet = 12,
- //Keyboard low level hook - WH_KEYBOARD_LL = 13
- KeyboardLL = 13,
- //Mouse low level hook - WH_MOUSE_LL = 14
- MouseLL = 14
- };
- #pragma endregion
- /***************************************
- * Value
- ****************************************/
- #pragma region Value
- protected:
- //The hook type
- HookTypes int_HookType;
- //The hook object thread id, give 0 for all thread
- DWORD dword_ThreadId;
- //The hook id, give 0 for not set
- HHOOK point_HookID;
- //Dll entrance
- static HINSTANCE hangle_HinstDLL;
- protected:
- //The this call delegate for CoreHookProcess
- byte DelegateThisCall[10];
- #pragma endregion
- /***************************************
- * New
- ****************************************/
- #pragma region New
- public:
- /***************************************
- '''
- ''' Initial function
- '''
- ''' The hook type
- ''' The hook object thread id, give 0 for all thread
- ****************************************/
- BaseHook(HookTypes HookType, DWORD ThreadId);
- //Dispose function
- ~BaseHook(void);
- #pragma endregion
- /***************************************
- * Property
- ****************************************/
- #pragma region Property
- public:
- //Set / get the hook type
- inline HookTypes GetHookType();
- inline void SetHookType(HookTypes HookType);
- //Set / get the hook object thread id, give 0 for all thread
- inline DWORD GetThreadId();
- inline void SetThreadId(DWORD ThreadId);
- //Set / get whether the hook is running
- bool GetEnabled();
- void SetEnabled(bool Enabled);
- //Set / get dll hinst
- static HINSTANCE GetHinstDll();
- static void SetHinstDll(HINSTANCE HinstDLL);
- #pragma endregion
- /***************************************
- * Sub / Function
- ****************************************/
- #pragma region Sub / Function
- protected:
- /***************************************
- ///
- /// The defination of core hook process
- ///
- ///Specifies the hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information
- ///Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- ///Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- ///The nCode, use 0 to pass the information to next hook, others to ignore the current information
- ///Use for SetWindowsHookEx
- ****************************************/
- LRESULT /*CALLBACK*/ CoreHookProcess(int nCode, WPARAM wParam, LPARAM lParam);
- public:
- /***************************************
- ///
- /// Set the hook data
- ///
- /// The hook type
- /// The hook object thread id, give 0 for all thread
- /// Restart the hook after the hook data changed
- ****************************************/
- void SetHook(HookTypes HookType, DWORD ThreadId);
- /***************************************
- ///
- /// Start the hook
- ///
- /// Check the Enabled for operation result
- ****************************************/
- void Start();
- /***************************************
- ///
- /// Stop the hook
- ///
- /// Check the Enabled for operation result
- ****************************************/
- void Stop();
- /***************************************
- ///
- /// The user defined hook process
- ///
- /// Specifies the hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information
- /// Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- /// Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- /// The nCode, use 0 to pass the information to next hook, others to ignore the current information
- /// Use for CoreHookProcess
- ****************************************/
- virtual LRESULT /*CALLBACK*/ HookProcess(int nCode, WPARAM wParam, LPARAM lParam);
- #pragma endregion
- };
C/C++ Code: BaseHook.cpp
- /********************************************************* {COPYRIGHT-TOP} *
- * RealZYC Confidential
- * OCO Source Materials
- *
- * (C) Copyright RealZYC Corp. 2011 All Rights Reserved.
- *
- * The source code for this program is not published or otherwise
- * divested of its trade secrets, irrespective of what has been
- * deposited with the China Copyright Office.
- ********************************************************** {COPYRIGHT-END} */
- #include "BaseHook.h"
- /***************************************
- *class BaseHook
- ****************************************/
- /***************************************
- * Static
- ****************************************/
- #pragma region Static
- HINSTANCE BaseHook::hangle_HinstDLL = NULL;
- #pragma endregion
- /***************************************
- * Property
- ****************************************/
- #pragma region Property
- //Set / get the hook type
- BaseHook::HookTypes BaseHook::GetHookType(){return int_HookType;}
- void BaseHook::SetHookType(HookTypes HookType){int_HookType = HookType;}
- //Set / get the hook object thread id, give 0 for all thread
- DWORD BaseHook::GetThreadId(){return dword_ThreadId;}
- void BaseHook::SetThreadId(DWORD ThreadId){dword_ThreadId = ThreadId;}
- //Set / get whether the hook is running
- bool BaseHook::GetEnabled(){return ( point_HookID != NULL );}
- void BaseHook::SetEnabled(bool Enabled)
- {
- if(Enabled != GetEnabled())
- {
- if(Enabled)Start();
- else Stop();
- }
- }
- //Set / get dll hinst
- HINSTANCE BaseHook::GetHinstDll()
- {
- try
- {
- return (hangle_HinstDLL != NULL)? hangle_HinstDLL:
- GetModuleHandle((LPCTSTR)"WinHook");
- }
- catch(...)
- {
- return NULL;
- }
- }
- void BaseHook::SetHinstDll(HINSTANCE HinstDLL){hangle_HinstDLL = HinstDLL;}
- #pragma endregion
- /***************************************
- * New
- ****************************************/
- #pragma region New
- /***************************************
- ///
- /// Initial function
- ///
- /// The hook type
- /// The hook object thread id, give 0 for all thread
- ****************************************/
- BaseHook::BaseHook(BaseHook::HookTypes HookType, DWORD ThreadId)
- {
- point_HookID = NULL;
-
- //******************************************//
- //初始化委托
- byte * DelegatePoint = DelegateThisCall;
- DelegateThisCall[0] = 0xb9; //__asm mov ecx, this
- DelegateThisCall[5] = 0xe9; //__asm jmp, CoreHookProcess
- __asm
- {
- push eax //保护eax
- push ebx //保护ebx
- mov eax, this //取得this地址
- mov ebx, DelegatePoint //获取DelegateThisCall地址
- mov dword ptr [ebx+1], eax //this 地址, 双字(DWORD)
- }
- __asm //计算jmp地址参考:http://zhidao.baidu.com/question/105950930.html
- {
- lea eax, CoreHookProcess //取得CoreHookProcess地址
- mov ebx, DelegatePoint //获取jmp地址= DelegatePoint + 5
- add ebx, 5
- add ebx, 5
- sub eax, ebx //JMP地址=目标地址-(本句地址+本句指令字节数)
- mov dword ptr [ebx-4], eax //CoreHookProcess 地址, 双字(DWORD)
- pop ebx //还原ebx
- pop eax //还原eax
- }
- //******************************************//
- SetHook(HookType, ThreadId);
- }
- //Dispose function
- BaseHook::~BaseHook(void)
- {
- SetEnabled(false);
- }
- #pragma endregion
- /***************************************
- * Sub / Function
- ****************************************/
- #pragma region Sub / Function
- /***************************************
- ///
- /// The defination of core hook process
- ///
- ///Specifies the hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information
- ///Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- ///Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- ///The nCode, use 0 to pass the information to next hook, others to ignore the current information
- ///Use for SetWindowsHookEx
- ****************************************/
- LRESULT /*CALLBACK*/ BaseHook::CoreHookProcess(int nCode, WPARAM wParam, LPARAM lParam)
- {
- //调用模式:如果使用__stdcall (即加入CALLBACK关键字),
- // 那么this指针是通过push this来传送的, 非法调用时会产生堆栈的不平衡, 会在函数返回时出错
- // 如果使用__thiscall,那么this指针是通过ecx来来传送的, 不会产生堆栈变化, 测试成功
- //参考自:http://wenku.baidu.com/view/ad102ccf05087632311212ad.html
- LRESULT Result = this->HookProcess(nCode, wParam, lParam); //此时访问时, 由于设置了this指针,成功运行
- if(Result == NULL)
- Result = CallNextHookEx(point_HookID, nCode, wParam, lParam);
- return Result; //由于注释掉CALLBACK,不会产生堆栈不平衡的问题,函数返回后无报错
- }
- /***************************************
- ///
- /// Set the hook data
- ///
- /// The hook type
- /// The hook object thread id, give 0 for all thread
- /// Restart the hook after the hook data changed
- ****************************************/
- void BaseHook::SetHook(BaseHook::HookTypes HookType, DWORD ThreadId)
- {
- int_HookType = HookType;
- dword_ThreadId = ThreadId;
- }
- /***************************************
- ///
- /// Start the hook
- ///
- /// Check the Enabled for operation result
- ****************************************/
- void BaseHook::Start()
- {
- try
- {
- if(GetEnabled())SetEnabled(false);
- HINSTANCE hMod = NULL;
- if(GetThreadId() == 0)
- {
- hMod = GetHinstDll();
- }
- else
- {
- if(GetCurrentThreadId() == GetThreadId())
- {
- hMod = NULL;
- }
- else hMod = GetHinstDll();
- }
- //===============================================================
- //将类成员函数指针转化为一般函数指针
- LRESULT (CALLBACK * PCoreHookProcess)(int nCode, WPARAM wParam, LPARAM lParam);
- byte * DelegatePoint = DelegateThisCall;
- __asm //内联汇编语句
- {
- push eax //保护eax
- mov eax, DelegatePoint
- mov PCoreHookProcess, eax //将委托地址强制转化给PCoreHookProcess
- pop eax //还原eax
- }
- //===============================================================
- point_HookID = SetWindowsHookEx(GetHookType(),
- PCoreHookProcess,
- hMod,
- GetThreadId());
- }
- catch(...)
- {
- point_HookID = NULL;
- }
- }
- /***************************************
- ///
- /// Stop the hook
- ///
- /// Check the Enabled for operation result
- ****************************************/
- void BaseHook::Stop()
- {
- try
- {
- UnhookWindowsHookEx(point_HookID);
- }
- catch(...)
- {
- }
- point_HookID = NULL;
- }
- /***************************************
- ///
- /// The user defined hook process
- ///
- /// Specifies the hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information
- /// Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- /// Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain
- /// The nCode, use 0 to pass the information to next hook, others to ignore the current information
- /// Use for CoreHookProcess
- ****************************************/
- LRESULT /*CALLBACK*/ BaseHook::HookProcess(int nCode, WPARAM wParam, LPARAM lParam)
- {
- return NULL;
- }
- #pragma endregion