现在的位置: 首页 > 综合 > 正文

孙鑫教学视频笔记(20)Hook

2013年10月11日 ⁄ 综合 ⁄ 共 3935字 ⁄ 字号 评论关闭

通过安装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   //为零表示和所有安装的线程相关
);

要屏蔽鼠标过程,首先在BOOL CInnerHookerDlg::OnInitDialog()中添加
 SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
要获得当前线程句柄,使用函数DWORD GetCurrentThreadId(void);

其中鼠标过程MouseProc为:
LRESULT CALLBACK MouseProc(        
 int nCode,
    WPARAM wParam,
    LPARAM lParam
)
{
 return 1;  //返回值为一表示屏蔽鼠标过程
}

如果要屏蔽键盘消息,可以添加如下代码
HHOOK g_hKeyBoard;
1。
g_hKeyBoard=SetWindowsHookEx(WH_KEYBOARD,KeyBoardProc,NULL,GetCurrentThreadId());

2。

LRESULT CALLBACK KeyBoardProc(        
 int nCode,
    WPARAM wParam,
    LPARAM lParam
)
{
 if(VK_SPACE==wParam)  //VK_SPACE为设备虚拟码,表示空格
//我们可以选择go to definition找到其他虚拟码,如果我们同时屏蔽掉回车键,程序就无法//退出了,这时按键盘上的Alt+F4键可以退出。
//如果你连Alt+F4都想屏蔽,添加以下判断语句
//if(VK_F4==wParam && (lParam>>29 & 1))
//lParam右移29位,正好它的第二十九位在第一位上,lParam得第二十九位表示了Alt键//被按下
  return 1;
 else
  return CallNextHookEx(g_hKeyBoard,nCode,wParam,lParam);
 //返回下一个hook
}

下边添加代码使程序在F2键按下后退出。要关闭窗口,首先要获得窗口的句柄,先声明一个全局变量g_hWnd,在OnInitDialog()中把窗口句柄传给它:
g_hWnd=m_hWnd;
接下来为键盘钩子过程添加代码:
 if(VK_F2==wParam)
 {
  ::SendMessage(g_hWnd,WM_CLOSE,0,0);  //发送关闭消息
  UnhookWindowsHookEx(g_hKeyBoard);
 UnhookWindowsHookEx(g_hMouse);
 //当我们自己发送消息关闭程序时,一定要记得关闭Hook
 }
 return 1;
这时我们只能屏蔽主线程的键盘消息,如果要屏蔽所有消息,就得把代码放到动态链接库中实现。

得到动态链接库模块的句柄。
1。DllMain函数方式:
HINSTANCE g_hInst;

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved
)
{
 g_hInst=hinstDLL;
}

HMODULE和HINSTANCE可以通用
2。GetModuleHandle函数方式
 SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
这样我们所安装的钩子过程就和运行在同一个桌面上的所有进程相关了

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

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

接下来新建一个工程,用来测试刚才的DLL
在BOOL CHookTestDlg::OnInitDialog()前声明SetHook函数
_declspec(dllimport) void SetHook();

直接在OnInitDialog()中调用,
SetHook();
调试运行,你会发现你的鼠标坏了。

接下来安装键盘Hook,我们可以按照刚才所做键盘Hook的过程在动态链接库中也做一个Hook,这是需要给SetHook带上参数HWND hwnd.
在测试程序中要把函数也带上参数,并给SetHook传入窗口句柄 SetHook(m_hWnd)。

如果想让程序窗口始终在其他窗口之前,可以使用SetWindowPos函数
The SetWindowPos
function changes the size, position, and Z order of a child, pop-up, or
top-level window. Child, pop-up, and top-level windows are ordered
according to their appearance on the screen. The topmost window
receives the highest rank and is the first window in the Z order.

BOOL SetWindowPos(          HWND hWnd,
    HWND hWndInsertAfter,
    int X,
    int Y,
    int cx,
    int cy,
    UINT uFlags
);

如果要得到窗口的大小,可以使用函数GetSystemMetrics
The GetSystemMetrics function
retrieves various system metrics (widths and heights of display
elements) and system configuration settings. All dimensions retrieved
by GetSystemMetrics are in pixels.

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);
这样的话,我们的程序始终处于顶层窗口,不管怎样切换窗口,整个窗口都只有我们一个程序

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

我们可以发现当切换到其他程序后,我们按F2我们的程序不会退出,按动态链接库共享性的原理和我们对桌面线程的关联,应该是所有的线程都能使用这个DLL来关闭我们的程序。
这是因为系统的页面拷贝机制,如果系统发现被共享的DLL被某线程修改,它就会先拷贝一份页面数据,再对原先的页面数据进行修改,共享该DLL的其它线程使用新的页面数据。

如果确实想在其他程序窗口下关闭我们的程序窗口,可以把共享窗口句柄,使系统不再进行页面拷贝,方法是使用下面语句把窗口句柄设为共享:
#pragma data_seg("MySec")
HWND g_hWnd=NULL;  //这里的初始化是必须的,否则没有新建节的信息
#pragma  data_seg()   //以上为新建节

#pragma comment(linker,"/section:MySec,RWS")  //设置节的属性,读,写,共享
也可以把#pragma comment(linker,"/section:MySec,RWS")省略。
在Hook.def中添加如下代码:
SEGMENTS
MySec read write shared
也能对节的属性进行设置

把SetWindowsHookEx函数的第一个参数设为WH_GETMESSAGE,能够破解密码,具体方法还不会。

COM
[计] 小型可执行程序的扩展名, 串行通讯端口
[域] Commercial organizations,商业组织,公司
The Component Object Model组件对象模型
ADO的三个核心对象
Connection对象
     Connection对象表示了到数据库的连接,它管理应用程序和数据库之间的通信。Recordest和Command对象都有一个ActiveConnection属性,该属性用来饮用Connection对象。
Command对象
  Command对象被用来处理重复执行的查询,或处理需要检查在存储过程调用中的输出或返回参数的值的查询。
Recordset对象
  Recordset对象被用来获取数据。Recordset对象存放查询的结果,这些结果又数据的行(称为记录)和列(成为字段)组成。每一列都存放在Recordset的Fields集合中的一个Filed对象中

【上篇】
【下篇】

抱歉!评论已关闭.