Lesson20 Hook与数据编程

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

通过安装Hook过程,可以用来屏蔽消息队列中某些消息

The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.

 

Syntax

 

HHOOK SetWindowsHookEx(

int idHook,

HOOKPROC lpfn,

HINSTANCE hMod,

DWORD dwThreadId   //为零表示和所有安装的线程相关

);

 

一、下面我们来创建一个屏蔽鼠标过程的hook:

1.创建基于MFC的一个InnerHook工程项目

2.BOOL CInnerHookerDlg::OnInitDialog()中添加hook

SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());

要获得当前线程句柄,使用函数DWORD GetCurrentThreadId(void);

3.实现鼠标过程MouseProc为:

 

LRESULT CALLBACK MouseProc(

 

 

int nCode,

WPARAM wParam,

LPARAM lParam

)

{

return 1; //返回值为一表示屏蔽鼠标过程

}

 

二、如果要屏蔽键盘消息,可以添加如下代码

1.CPP文件中添加一个变量:HHOOK g_hKeyBoard;

2.CInnerHookerDlg::OnInitDialog()中添加hook

g_hKeyBoard=SetWindowsHookEx(WH_KEYBOARD,KeyBoardProc,NULL,GetCurrentThreadId());

 

3.实现键盘过程keybroadProc为(只屏蔽空格键):

 

4.下边添加代码使程序在F2键按下后退出。

要关闭窗口,首先要获得窗口的句柄,先声明一个全局变量Hwnd g_hWnd

OnInitDialog()中把窗口句柄传给它:

g_hWnd=m_hWnd;

接下来为键盘钩子过程添加代码:

 

这时我们只能屏蔽主线程的键盘消息,如果要屏蔽所有消息,就得把代码放到动态链接库中实现。

三、屏蔽所有线程的消息

首先要创建一个动态链接库

1.新建一个Win32 Dynamic-Link Library项目工程Hook

 得到动态链接库模块的句柄有两种方式:

     方法1DllMain函数方式:

 

HMODULEHINSTANCE可以通用

     方法2GetModuleHandle函数方式

SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);

 

这样我们所安装的钩子过程就和运行在同一个桌面上的所有进程相关了

2.编写MouseProc()

 

3.之后新建一个模块文件Hook.def,添加代码:

LIBRARY Hook

EXPORTS

SetHook @2   //@2用来指定序号。

4.编译生成dll文件

 

接下来新建一个工程,用来测试刚才的DLL

    首先安装一个鼠标Hook屏蔽所有的鼠标消息。

1.新建一个基于MFC对话框的项目工程HookTest

2.BOOL CHookTestDlg::OnInitDialog()前声明SetHook函数

_declspec(dllimport) void SetHook();

3.Setting对话框的Link选项卡的,添加库文件:..\Hook\Debug\Hook.lib

4.OnInitDialog()中调用 SetHook();

5.将生成好的动态链接库拷贝到测试程序项目工程目录下面。

 

调试运行,你会发现你的鼠标坏了,所有的鼠标操作都被屏蔽了。

 

 

    然后安装一个键盘Hook,我们可以按照刚才所做键盘Hook的过程在动态链接库中也做一个Hook

    这是需要给SetHook带上参数HWND hwnd.

    在测试程序中要把函数也带上参数,并给SetHook传入窗口句柄 SetHook(m_hWnd)

 

 

    接着,让程序窗口始终在其他窗口之前,而且将它最大化,从而使用户不能切换到窗口。

可以使用SetWindowPos函数

BOOL SetWindowPos(

HWND hWndInsertAfter,

int X,

int Y,

int cx,

int cy,

UINT uFlags

);

A window can be moved to the top of the Z-order either by setting the pWndInsertAfter parameter to &wndTopMost and ensuring that the SWP_NOZORDER flag is not set or by setting a window’s Z-order so that it is above any existing topmost windows. When a nontopmost window is made topmost, its owned windows are also made topmost. Its owners are not changed.

 

得到窗口的大小,可以使用函数GetSystemMetrics

int GetSystemMetrics(int nIndex);

代码:

int cxScreen,cyScreen;

cxScreen=GetSystemMetrics(SM_CXSCREEN);

cyScreen=GetSystemMetrics(SM_CYSCREEN);

SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);

 

SetHook(m_hWnd);

因为第一个参数设置为&wndTopMost,这时程序始终处于顶层窗口,

不管怎样切换窗口,我们的窗口显示在最前面。

 

 

 

四、如何实现在切换到其他线程时,也能响应F2退出程序

在程序中,我们屏蔽了鼠标和键盘,但是我们留下了一个退出程序的后门(F2)。

前面讲过动态链接库共享性的原理,多个进程可以共享同一份代码与数据页,

按道理切换到其它线程之后,按下F2应该也可以退出程序才对,

但是发现当切换到其他程序后,再按F2 程序不会退出,

这是因为系统的页面拷贝机制,如果系统发现被某线程要修改某个数据页面,

它就会先拷贝一份页面数据,再对新的页面数据进行修改,

其它没有更新数据的线程继续使用旧的页面数据。

比如:SetHook(HWND hwnd)中将形参传递给了一个全局变量g_hWnd

,那么调用SetHook的线程将使用新的存放了hwnd的数据页面,

而其它的线程继续使用旧的数据页面,所以在其它线程成为活动窗口的时候,

按下F2时,因为没有g_hWnd没有传递到hwnd窗口,所以按下F2没有反应。

 

我们可以通过创建一个新的节,将全局变量放到这个节当中,然后将这个节设置为一个共享的节,

这样全局变量就可以在多个线程间共享,从而使切换到其他线程时也能按下F2退出程序。

要显示动态链接库的节,可以使用命令行: dumpbin -headers Hook.dll

 

如何创建一个新的节?

如果确实想在其他程序窗口下关闭我们的程序窗口,可以把共享窗口句柄,使系统不再进行页面拷贝,方法是使用下面语句把窗口句柄设为共享:

 

#pragma data_seg("MySec")//MySec是新创建的节的名字(不能超过8个字节)

HWND g_hWnd=NULL; //新变量必须初始化,否则没有新建节的信息

#pragma data_seg()   //以上为新建节

 

新创建的节共享以后才有效,共享节有两种方法:

1.#pragma comment(linker,"/section:MySec,RWS") //设置节的属性,读,写,共享

2.也可以把#pragma comment(linker,"/section:MySec,RWS")省略。

Hook.def中添加如下代码:

SEGMENTS

MySec read write shared

也能对节的属性进行设置

 

SetWindowsHookEx函数的第一个参数设为WH_GETMESSAGE,能够破解密码。

使用Hook时要小心。

 

1.Hook简介:作用是拦截某些消息,关键函数是SetWindowsHookEX()

2.示例程序:

1.新建一基于对话框工程,InnerHook,此过程的钩子是只拦截本进程的。

2.OnInitDialog()中添加代码:

   g_hWnd=m_hWnd;

g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());设置了鼠标钩子

g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,NULL,GetCurrentThreadId());设置了键盘钩子

3.完成钩子函数的编写:

HHOOK g_hKeyboard=NULL;

HHOOK g_hMouse;

HWND g_hWnd=NULL;LRESULT CALLBACK MouseProc(

   int nCode,      // hook code

   WPARAM wParam, // message identifier

   LPARAM lParam   // mouse coordinates

)

{

return 1;

}LRESULT CALLBACK KeyboardProc(

   int code,       // hook code

   WPARAM wParam, // virtual-key code

   LPARAM lParam   // keystroke-message information

)

{

//if(VK_SPACE==wParam || VK_RETURN==wParam)如果是空格键

/*if(VK_F4==wParam && (1==(lParam>>29 & 1)))拦截ALT+F4按键!

   return 1;

else

   return CallNextHookEx(g_hKeyboard,code,wParam,lParam);*/

if(VK_F2==wParam)F2时程序可以退出,这是留的后门。否则程序无法关闭,只能用任务管理器来关闭它了。

{

   ::SendMessage(g_hWnd,WM_CLOSE,0,0);

   UnhookWindowsHookEx(g_hKeyboard);当程序退出时最好将钩子移除。

   UnhookWindowsHookEx(g_hMouse);

}

return 1;

}

3.编写一个屏屏蔽所有进程和所有线程的钩子程序。耸闭飧龉匙颖匦氚沧霸贒LL中,然后被某个程序调用才行。

1.新建一个DLL工程名为Hook

2.增加Hook.cpp

3.代码如下:

#include <windows.h>包含头文件HHOOK g_hMouse=NULL;

HHOOK g_hKeyboard=NULL;#pragma data_seg("MySec")新建了一个节,用于将下 面的这个变量设为全局共享。

HWND g_hWnd=NULL;这个变量是全局共享的。

#pragma data_seg()//#pragma comment(linker,"/section:MySec,RWS")

/*HINSTANCE g_hInst;BOOL WINAPI DllMain(

   HINSTANCE hinstDLL, // handle to the DLL module

   DWORD fdwReason,     // reason for calling function

   LPVOID lpvReserved   // reserved

)

{

g_hInst=hinstDLL;

}*/LRESULT CALLBACK MouseProc(

   int nCode,      // hook code

   WPARAM wParam, // message identifier

   LPARAM lParam   // mouse coordinates

)

{

return 1;拦截了鼠标消息。

}LRESULT CALLBACK KeyboardProc(

   int code,       // hook code

   WPARAM wParam, // virtual-key code

   LPARAM lParam   // keystroke-message information

)

{

if(VK_F2==wParam)如果是F2键,则退出。

{

   SendMessage(g_hWnd,WM_CLOSE,0,0);

   UnhookWindowsHookEx(g_hMouse);当退出时将钩子卸掉。

   UnhookWindowsHookEx(g_hKeyboard);

}

return 1;

}void SetHook(HWND hwnd)此函数设置了钩子。

{

g_hWnd=hwnd;注意这种传递调用它的进程的句柄的方法,比较巧妙!

g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);

g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("Hook"),0);

}Hook.DEF的代码如下:

LIBRARY Hook

EXPORTS

SetHook @2

SEGMENTS

MySec READ WRITE SHARED 也可以设置节的属性。

    4.新建一个工程调用此钩子函数。工程名为HookTest,基于对话框的。在OnInitDialog()中调用SetHook(),要事先声明_declspec(dllimport) void SetHook(HWND hwnd);

      然后在Project->Setting->Link->加入..\Hook\Debug\Hook.lib,并将Hook.Dll拷贝到当前目录。

int cxScreen,cyScreen;

cxScreen=GetSystemMetrics(SM_CXSCREEN);

cyScreen=GetSystemMetrics(SM_CYSCREEN);

SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);将窗口保持在最前面。

SetHook(m_hWnd);

    5.DLL的调试方法,设置断点,然后运行时断点时,step into即可。

4.数据库编程

1.ODBCADO简介:ADO可以认为是建立在ODBC上的。

   ADO的三个核心对象

Connection对象

   Connection对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。 RecordsetCommand对象都有一个ActiveConnection属性,该属性用来引用Connection对象。

Command对象

   Command对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。

Recordset对象

   Recordset对象被用来获取数据。 Recordset对象存放查询的结果,这些结果由数据的行(称为记录)和列(称为字段)组成。每一列都存放在RecordsetFields集合中的一个Field对象中。

2.演示在VB中使用ADO的方法,方法比较简单,使用方便。另外在VB中演示了ConnectionCommandRecordset的方法,用这三种方法都可以执行SQL语句。

3.VC中利用ADO访问数据库。

    1.新建一个基于对话框的工程,名为ADO

    2.在对话框中放一ListBox和一个Button控件。

    3.在使用时须导入MSADO15.dll,方法是在StdAfx.h#import "D:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")

    至少于将EOF改名为rsEOF,是为了避免与文件中的EOF重名。然后编译程序,将产生的debug目录下的两个文件MSADO15.tlhMSADO15.tli加到工程中,其目的只是方便我们查看而已。并不是编译需要它。

    ADO也是COM组件,须初始化COM库方法是CoInitialize(NULL);使用完后须CoUninitialize();

    代码如下:

    void CAdoDlg::OnBtnQuery()

{

// TOD Add your control notification handler code here

CoInitialize(NULL);初始化

_ConnectionPtr pConn(__uuidof(Connection));产生connection智能指针

_RecordsetPtr pRst(__uuidof(Recordset));产生recordset智能指针

_CommandPtr pCmd(__uuidof(Command));产生command智能指针pConn->ConnectionString="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=pubs";数据库信息

pConn->Open("","","",adConnectUnspecified);打开数据库//pRst=pConn->Execute("select * from authors",NULL,adCmdText);用记录集查询数据

//pRst->Open("select * from authors",_variant_t((IDispatch*)pConn),

// adOpenDynamic,adLockOptimistic,adCmdText);

pCmd->put_ActiveConnection(_variant_t((IDispatch*)pConn));

pCmd->CommandText="select * from authors";用这种方法也可以查询数据

pRst=pCmd->Execute(NULL,NULL,adCmdText);

while(!pRst->rsEOF)将查询到的数据加到列表框咯。

{

((CListBox*)GetDlgItem(IDC_LIST1))->AddString(

   (_bstr_t)pRst->GetCollect("au_lname"));

pRst->MoveNext();

}pRst->Close();

pConn->Close();

pCmd.Release();

pRst.Release();

pConn.Release();

CoUninitialize();

}


数据库编程:

 

COM

[小型可执行程序的扩展名串行通讯端口

[] Commercial organizations,商业组织,公司

The Component Object Model组件对象模型

ADO的三个核心对象

Connection对象

Connection对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。RecordestCommand对象都有一个ActiveConnection属性,该属性用来饮用Connection对象。

Command对象

Command对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。

Recordset对象

Recordset对象被用来获取数据。Recordset对象存放查询的结果,这些结果又数据的行(称为记录)和列(成为字段)组成。每一列都存放在RecordsetFields集合中的一个Filed对象中

 

 

关于ADO数据库连接方面知识的总结

 

1、导入库文件

 

使用ADO前必须在工程的stdafx.h文件最后用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下:

#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","EndOfFile") rename("BOF","FirstOfFile")

 

ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。

类型库描述了自治接口,以及C++使用的COM vtable接口。

当使用#import指令时,在运行时Visual C++需要从ADO DLL中读取这个类型库,

并以此创建一组C++头文件。这些头文件具有.tli .tlh扩展名,#import引入ADO库文件的代码编译后,在项目的目录下生成了这两个文件。在C++程序代码中调用的ADO类要在这些文件中定义。

程序的第三行指示ADO对象不使用名称空间,在有些应用程序中,

由于应用程序中的对象与ADO中的对象之间可能会出现命名冲突,所以有必要使用名称空间。

如果要使用名称空间,则可把第三行程序修改为: rename_namespace("AdoNS")

第四行代码将ADO中的EOF(文件结束)更名为adoEOF,因为文件的结尾也是以EOF结尾的,是为了避免与定义了自己的EOF的其他库冲突。 至于改为什么名字,可以根据自己的命名习惯自己确定。

 

 

2、初始化COM环境

OLE DB 是基于COM技术编写的,ADOOLE DB基础之上的用户程序,

OLE DB是一个COM组件,在访问COM组件的时候需要初始化COM库,方法如下:

1   ::CoInitialize(NULL); //初始化OLE/COM库环境

//对数据库的访问在上下代码之间写,下面第三步就应该写在这里

::CoUninitialize();//既然初始化了环境,当然一定要记得释放他了

2)也可以调用MFC全局函数

AfxOleInit();

 

3、三大指针对象的定义和创建实例

 

(1)

_ConnectionPtr pConnection("ADODB.Connection");

_RecordsetPtr pRecordset("ADODB.Recordset");

_CommandPtr pCommand("ADODN.Command");

 

(2)

 _ConnectionPtr pConnection;

_RecordsetPtr pRecordset;

_CommandPtr pCommand;

 

pConnection.CreateInstance(__uuidof(Connection));

pRecordset.CreateInstance(__uuidof(Recordset));

pCommand.CreateInstance(__uuidof(Command));

 

要产生一个智能指针对象,其实在定义的同时也可以初始化,如:

_ConnectionPtr pConnection(__uuidof(Connection));

_ConnectionPtr 是智能指针

__uuidof() 用来获取Connection全局唯一标识符

 

(3)

_ConnectionPtr pConnection;

_RecordsetPtr pRecordset;

_CommandPtr pCommand;

 

pConnection.CreateInstance("ADODB.Connection");

pRecordset.CreateInstance("ADODB.Recordset");

pCommand.CreateInstance("ADODB.Command");

 

4、打开一个连接

pConnection->ConnectionString = "这里的字符串有下面四种写法";//对连接字符串赋值

pConnection->Open(ConnectionString,"","",adModeUnknown); //连接数据库

第二三个参数分别为用户的ID与密码,

因为在连接字符串ConnectionCstring中已经设置好了,这里可以为空。

第四个参数可以取下面两个参数:

adAsyncConnect

异步打开数据库,在ASP中直接用16

adConnectUnspecified

同步打开数据库,在ASP中直接用-1

 

ConnectionString根据不同的数据源,分别对应不同的写法

(要记下来很困难,可以在VB中利用ADO控件先连接好,再将其拷贝在VC中,这样不容易出错)

    1

访问Access 2000

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassWord"

 

    2)

访问ODBC数据

"Provider=MADASQL;DSN=dsnName;UID=userName;PWD=userPassword;"

 

   3)

访问Oracle数据库

Provider=MSDAORA;Data Sourse=serverName;User ID=userName;Password=userPassword;"

 

   4)

访问MS SQL数据库

"Provider=SQLOLEDB,Data Source=serverName;Initial Catalog=databaseName;User ID=userName;Password=userPassword;"

 

5、执行SQL命令,得到数据

方法1

pRecordset = pConnection->Execute("Select * from authors",NULL,adCmdText);

方法2

pRecordset ->Open("Select * from authors",_

variant_t((Idispacth*) pConnection), //设置活动连接

adOpenDynamtic,

//游标类型

adLockOptimistic,

//锁的类型

adCmdText);

方法3

pCommand->put_ActiveConnection(_variant_t((Idispatch *) pConn);

pCommand->CommandText = "Select * from authors";

pRecordset = pCmd->Execute(NULL,NULL,adCmdText);

 

 

得到数据之后,做一个循环取得数据:

While (!pRecordset ->adoEOF)

{

Str = pRecordset->GetCollect("au_lname"));

pRst->MoveNext();

}

SQL命令比较多,但是不去考虑细节,这里只说出通用的方法

CString strSQL;//定义SQL命令串,用来保存SQL语句

 

strSQL.Format("SQL statement");

 

然后在每个要用到SQL命令串的方法中,使用strSQL.AllocSysString()的方法进行类型转换

 

6com的专用数据类型

 

variant ,bstr ,SafeArray

 

variant变量的范围包括很多,它是一种变体类型,主要用于支持自动化的语言访问,

从而在VB中非常方便地使用,但是VC中比较复杂,它使用_variant_t 进行管理

bstr是一种字符串变量,使用_bstr_t进行管理,这个类重载了char *操作符

 

7、关闭连接

 

if(pConnection->State);     //不能多次关闭,否则会出现错误

pConnection->Close();

pRecordset->Close();

pCommand.Release();

pConnection.Release();

//释放引用计数

pRecordset.Release();

 

 

    注意:调用Close()时用"->",调用Release()时要用".",为什么?

因为智能指针,_ConnectionPtr是一个重载了->运算符的类

 

_ConnectionPtr:它是一个接口指针模板。'.'是模板_com_ptr的函数。->'接口函数'调用。

//forexample:

_ConnectionPtr m_Conn;

m_Conn.CreateInstance(....);//Createinterfaceinstance.

m_Conn->Open(...);//Openaconnectiontodatabase.

 

'->'_com_ptr重载了的运算符.目的就是为了让你调用模板参数的函数.

 

8、结构化异常处理

ADO封装了COM接口,所以需要进行错误处理

如下例:

HRESULT hr;

try

{

hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象

if(SUCCEEDED(hr))

{

hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb","","",adModeUnknown);///连接数据库

///上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,需要改为:Provider=Microsoft.Jet.OLEDB.3.51; }

}

catch(_com_error e)///捕捉异常

{

CString errormessage;

errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());

AfxMessageBox(errormessage);///显示错误信息

}

 

这里介绍了三种对象通过ADO访问数据库,它们都可以执行SQL语句获取数据,但不是管那种方法获取数据,最终都将数据放置到记录集对象当中。


消息钩子函数入门篇 Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能。钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入, 阅读详情

相关推荐

孙鑫视频VC++深入详解学习笔记

<br />VC++深入详解学习笔记<br />Lesson1: Windows程序运行原理及程序编写流程<br />Lesson2: 掌握C++基本语法<br />Lesson3: MFC框架程序剖析<br />Lesson4: 简单绘图<br />Lesson5: 文本编程<br />Lesson6: 菜单编程<br />Lesson7: 对话框编程<br />Lesson9: 定制应用程序的外观<br />Lesson10: 绘图控制<br />Lesson11 图形的保存和重绘<br />Lesso

cora2008的专栏 1558

inner hook键盘钩子实例KeyHook

inner hook键盘钩子实例KeyHookinner hook键盘钩子实例KeyHookinner hook键盘钩子实例KeyHook

react native学习【7】——Crud APP 一个简单的、可增删改的待办事项

react native学习【7】——Crud APP 一个简单的、可增删改的待办事项

qq_48285331的博客 1011

Hook C++简单使用Demo

这个压缩包里面主要包含两个文件 一个是dll文件,一个是exe,原理是通过注入dll文件到应用程序中,从而实现hook 这边是用qq程序 作为demo来教学

VC++学习(20):HOOK数据编程

通过安装Hook过程,可以用来屏蔽消息队列中某些消息,可以某一线程相关或者当前桌面的所有线程相关; HHOOK SetWindowsHookEx( int idHook,       //Hook的类型WH_*,如WH_MOUSE监视鼠标过程 HOOKPROC lpfn,    //Hook过程(固定格式):DLL中的过程或者当前线程处于同一进程的过程 HINSTANCE hMo...

weixin_33862993的博客 228

基于Visual C++的钩子编程技巧

钩子概述  钩子(Hook)是Windows消息处理机制的一个要点(Point)。应用程序可以通过钩子机制截获处理Window消息或是其他一些特定事件。同DOS中断截获处理机制类似,应用程序可以在钩子上设置多个钩子函数,由其组成一个钩子相关联的指向钩子函数的指针列表(钩子链表)。当钩子所监视的消息出现时,Windows首先将其送到调用链表中所指向的第一个钩子函数中,钩子函数将根据其各自的功能

3150

在VC6中实现全局钩子及枚举窗口功能,设置timer

1、新建名称为CServerHook的MFC动态库,选择MFC扩展DLL选项,点击完成。2、系统自动生成ServerHook.cpp文件,但没有ServerHook.h文件,该文件需要手动添加。3、建立导出类CServerHook,ServerHook.h文件内容如下:BOOL _declspec(dllexport)  CALLBACK EnumWindowsProc(HWND hw

足迹 2471

hook简介

 1.Hook简介:作用是拦截某些消息,关键函数是SetWindowsHookEX()2.示例程序:  1.新建一基于对话框工程,InnerHook,此过程的钩子是只拦截本进程的。  2.在OnInitDialog()中添加代码:   g_hWnd=m_hWnd;g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThread

zy122的专栏 729

孙鑫lesson20 hook &database

hook 过滤某些消息/database connection 数据库连接,主要是通过ODBC进行数据库连接,三大核心 connection command recordset

clstudy13的博客 428

孙鑫VC视频Lesson20上:HOOK

HOOK,钩子    1.用来截取在“操作系统>>消息队列>>应用程序>>操作系统>>消息处理”这个过程中传递的Message    2.可以用来阻止应用程序接收到任何消息,或只接收特定消息。    3.所以应用程序本身有处理消息的能力,利用钩子也能处理消息。我们有了两个处理消息的方法了。     4.搞不懂的语句: _declspec(dllimport) void SetH

Data AI 577

Windows程序设计__孙鑫C++Lesson20HOOK数据库访问》

Windows程序设计__孙鑫C++Lesson20HOOK数据库访问》 本节要点: 1.Hook编程回顾Windows消息传递机制 2.安装内部钩子 3.安装全局钩子 4.数据库访问技术初步了解 //*******************************************************************************************

王定桥的专栏 3133

深度学习原理 Lesson 10:深入理解模型Model

1 本节简介callback了解callbacks和event handlers的本质了解Python中应用callbacks的方法,以及优缺点用callback把c...

增长浩克 445

(三)fastai 2019 lesson10 Wrapping up our CNN 重构CNN

lesson10 Wrapping up our CNN 重构CNN

hello world 563

React Native鸿蒙跨平台 基于HarmonyOS API 24 底部导航采用 justifyContent: space-around实现四等分布局

在垂直领域教育类应用开发中,手语学习平台需要兼顾三大核心诉求。本文以 React Native 开发的手语课程列表应用为例,深度拆解其数据模型设计、组件化实现逻辑,并系统阐述向鸿蒙(HarmonyOS)ArkTS 跨端迁移的技术路径,聚焦“多层级数据关联、动态列表渲染、跨端体验一致性”三大核心维度,为教育类应用的跨端开发提供可落地的技术参考。

2401_86113894的博客 728

React Native鸿蒙HarmonyOS API 24 跨平台采用组件化架构React Hooks状态管理,实现了课程列表渲染、动态样式绑定和响应式布局等功能

描述符的一个示例用法就是将类属性的初始化延迟到被实例访问时。如果这些属性的初始化依赖全局应用上下文的话,那么这一点可能有用。另一个使用场景是初始化的代价很大,但在导入类的时候不知道是否会用到这个属性。这样的描述符可以按照如下所示来实现:defdef’)else:’)下面是示例用法:m.lazily_m.lazilycached!

2401_86113894的博客 781

React Native鸿蒙 HarmonyOS ArkTS API 24 采用组件化架构(如FlatList、)React Hooks状态管理,动态样式绑定和响应式布局等功能

在移动应用开发领域,跨端技术已成为主流趋势,尤其是随着鸿蒙系统的兴起,如何实现一套代码覆盖多平台(iOS、Android、鸿蒙)成为开发者关注的焦点。本文将深入解析一个基于 React Native 开发的手语课程应用,探讨其架构设计、核心技术实现以及在鸿蒙系统上的跨端适配策略。

2401_86113894的博客 772

客户端热注入技术实战:从原理到Electron应用动态修改

热注入(Hot Injection)是一种在软件运行时动态修改其代码、资源或行为的技术,其核心原理是通过进程注入、API钩子或调试协议,将外部代码加载到目标进程的地址空间中。这项技术的核心价值在于无需重启应用或获取源码即可实现功能增强界面定制,能显著提升开发调试软件个性化效率。在客户端开发、软件逆向自动化测试等场景中,热注入为开发者提供了强大的运行时控制能力。本文以热词“figma官方桌面端注入汉化脚本”和“客户端”为切入点,深入探讨了针对基于Electron等现代客户端的热注入通用流程、工具链实战

weixin_33860553的博客 446

AI Agent记忆系统调研报告:MAGMA AgentMemory 对比分析

MAGMA(Multi-Graph based Agentic Memory Architecture)是一个面向长期对话记忆和多跳推理的学术研究项目。属性信息论文会议(2026/04/07 被接收)作者GitHub许可MIT定位学术研究系统,专注长对话记忆的多图检索MAGMA 是学术突破,AgentMemory 是工程最佳实践MAGMA 在多跳推理准确性上代表了 SOTA(ACL 2026)AgentMemory 在实际 AI Coding 体验上代表了最佳工程实现。

天赐一米阳光 410

React Native鸿蒙跨平台HarmonyOS API 24 底部导航采用 flexDirection: row + justifyContent: space-around实现四等分布局

在 Python 2 中,没有指定任何祖先的类被认为是旧式类。(self, obj, value):在读取属性时将调用这一方法(被称为 getter)。幸运的是,多亏了 Python 描述符的工作方式。• super 的使用必须一致:在类的层次结构中,要么全部用 super,要么全不用。它是一个类,定义了另一个类的属性的访问方式。为了避免前面提到的所有问题,在 Python 在这个领域取得进展之前,我们需要考虑以。Python 提供这一特性是为了避免继承中的名称冲突,因为属性被重命名为以类名为前。

2401_86113894的博客 653
上一篇: Lesson19 动态链接库DLL
下一篇: metin C++加解密算法
Debugyt
博客等级 码龄18年 7粉丝 15原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值