@author: dlive

@date: 2016/12/19

0x01 SetWindowsHookEx()

HHOOK SetWindowsHookEx(
int idHook, //hook type
HOOKPROC lpfn, //hook procedure(回调函数)
HINSTANCE hMod, //hook procedure所属的DLL句柄
DWORD dwThreadId //想要挂钩的线程ID
);

使用SetWindowsHookEx() API可以轻松实现消息钩子。用于将制定的“钩子过程”注册到钩链中。无论在DLL内部还是外部都可以调用。(下面的例子是在DLL内部调用的)

hook procedure(钩子过程) 是由操作系统调用的回调函数,安装消息钩子时,钩子过程需要存在于某个DLL内部,且该DLL的instance handle(示例句柄)即是hMod

若dwThreadID参数被设置为0,则安装的钩子为全局钩子,它会影响到运行中的所有进程

0x02 HookMain.exe

#include "stdio.h"
#include "conio.h"
#include "windows.h" #define DEF_DLL_NAME "KeyHook.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop" typedef void (*PFN_HOOKSTART)();
typedef void (*PFN_HOOKSTOP)(); void main()
{
HMODULE hDll = NULL;
PFN_HOOKSTART HookStart = NULL;
PFN_HOOKSTOP HookStop = NULL;
char ch = 0; //加载DLL
hDll = LoadLibraryA(DEF_DLL_NAME);
if( hDll == NULL )
{
printf("LoadLibrary(%s) failed!!! [%d]", DEF_DLL_NAME, GetLastError());
return;
} //从DLL中获取函数地址
HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP); //执行HookStart函数
HookStart(); printf("press 'q' to quit!\n");
while( _getch() != 'q' ) ; HookStop(); //卸载DLL
FreeLibrary(hDll);
}

0x03 KeyHook.dll

#include "stdio.h"
#include "windows.h" #define DEF_PROCESS_NAME "notepad.exe" HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL; //DLL中的Main函数
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
switch( dwReason )
{
//DLL加载的时候
case DLL_PROCESS_ATTACH:
//钩子过程(KeyboardProc)所属DLL句柄,即本DLL
g_hInstance = hinstDLL;
break;
//DLL卸载的时候
case DLL_PROCESS_DETACH:
break;
} return TRUE;
} //钩子过程
//MSDN对KeyboardProc的定义:https://msdn.microsoft.com/en-us/library/ms644984(v=vs.85).aspx
//nCode :HC_ACTION(0), HC_NOREMOVE(3)
//wParam : 虚拟键值(virtual key code),对于键盘而言a和A具有相同的虚拟键值
//lParam 额外信息
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
char szPath[MAX_PATH] = {0,};
char *p = NULL; if( nCode >= 0 )
{
// bit 31 : 0 => press, 1 => release
if( !(lParam & 0x80000000) )
{
//获得应用程序的目录路径
GetModuleFileNameA(NULL, szPath, MAX_PATH);
p = strrchr(szPath, '\\');
//对比当前进行是否为notepad.exe
if( !_stricmp(p + 1, DEF_PROCESS_NAME) )
//终止KeyboardProc函数,意味着截获并删除信息
return 1;
}
}
//Passes the hook information to the next hook procedure in the current hook chain.
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
} #ifdef __cplusplus
//关于为何使用ifdef __cplusplus
//参考:http://blog.csdn.net/miyunhong/article/details/4589541
extern "C" {
#endif
//DLL的导出函数
__declspec(dllexport) void HookStart()
{
//设置消息钩子
//WH_KEYBOARD 钩子类型
//参考:https://msdn.microsoft.com/en-us/library/ms644959(v=vs.85).aspx#wh_keyboardhook
//KeyboardProc 钩子过程(回调函数)
//g_hInstance 钩子过程所在DLL的句柄
//0 想要挂钩的线程ID,若为0则为全局Hook
g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
} __declspec(dllexport) void HookStop()
{
if( g_hHook )
{
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}
#ifdef __cplusplus
}
#endif

0x04 调试KeyLogger.dll

首先运行notepad.exe

然后再OD的”调试选择“中选择Event->Break on new moudle(DLL)

开启该选项后,每当有新的DLL装入被调试进程时就会停止调试

0x05 参考资料

  1. MSDN Hook

    https://msdn.microsoft.com/en-us/library/ms644959(v=vs.85).aspx

Windows消息钩取的更多相关文章

  1. DLL注入之windows消息钩取

    DLL注入之windows消息钩取 0x00 通过Windows消息的钩取 通过Windows消息钩取可以使用SetWindowsHookEx.该函数的原型如下: SetWindowsHookEx( ...

  2. 《逆向工程核心原理》Windows消息钩取

    DLL注入--使用SetWindowsHookEx函数实现消息钩取 MSDN: SetWindowsHookEx Function The SetWindowsHookEx function inst ...

  3. Reverse Core 第三部分 - 21章 - Windows消息钩取

    @author: dlive @date: 2016/12/19 0x01 SetWindowsHookEx() HHOOK SetWindowsHookEx( int idHook, //hook ...

  4. 逆向学习-Windows消息钩取

    钩子 Hook,就是钩子.偷看或截取信息时所用的手段或工具. 消息钩子 常规Windows流: 1.发生键盘输入事件时,WM_KEYDOWN消息被添加到[OS message queue]. 2.OS ...

  5. SetWindowsHookEx 消息钩取进程卡死

    <逆向工程核心原理> windows消息钩取部分的例子在win10下卡死,失败.通过搜索发现,要保证钩取的进程与注入的dll要保持cpu平台相同 SetWindowsHookEx可用于将d ...

  6. windows消息钩子注册底层机制浅析

    标 题: [原创]消息钩子注册浅析 作 者: RootSuLe 时 间: 2011-06-18,23:10:34 链 接: http://bbs.pediy.com/showthread.php?t= ...

  7. x64 下记事本WriteFile() API钩取

    <逆向工程核心原理>第30章 记事本WriteFile() API钩取 原文是在x86下,而在x64下函数调用方式为fastcall,前4个参数保存在寄存器中.在原代码基础上进行修改: 1 ...

  8. Windows消息机制详解

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

  9. Windows消息机制知识点总结

    1.windows消息类型 以下四种,前三种是系统消息,范围在[0x0000, 0x03ff],第四种是用户自定义消息. 1.1 窗口消息 与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等.可以 ...

随机推荐

  1. k8s使用自定义证书将客户端认证接入到API Server

    自定义证书使用kubectl认证接入API Serverkubeconfig是API Server的客户端连入API Server时使用的认证格式的客户端配置文件.使用kubectl config v ...

  2. 学习Pytbon第七天,集合

    list_1=[5,22,2,6,5,66,6,8] list_1=set(list_1)#把列表转成集合,天生不允许 重复 print(list_1,type(list_1) list_2=set( ...

  3. python3下最全的wordcloud用法,附源代码及相关文件

    一.wordcloud是什么 词云,在一段文本中提取关键词进行扁平化的展示,更能吸引目标客户的眼球. 市面上有很多在线生成词云的工具,本文以Python中的第三方库wordcloud为例讲解如何自动生 ...

  4. Android 获取地理位置信息 封装好了 直接用

    前言:花了一个早上研究了以下android获取经纬度,然后网上的参考资料都是杂七杂八,基本上都是过去几年的,现在我用 android6.0参照别人的结果发生好多错误,我的内心几乎是崩溃的.后来,不断百 ...

  5. Python中*和**的区别

    Python中,(*)会把接收到的参数形成一个元组,而(**)则会把接收到的参数存入一个字典 我们可以看到,foo方法可以接收任意长度的参数,并把它们存入一个元组中 >>> def ...

  6. 成都大学CTF 网络攻防演练平台 WP

    web1 输入框那里鼠标右键,审查元素,删除maxlength web2 http://ctf.cdusec.org:8082/web2/?cdusec=tql web3 同上,用火狐hackbar或 ...

  7. 【LoadRunner】如何对GIS服务器进行性能测试

    1.需求了解 首先确定对gis服务器压测的测试范围,形成具体的测试用例,gis平台都是通过网页端的javascript api调用的gis集群服务接口,通过LR录制上一步中的业务操作,找到javasc ...

  8. LuffyCity-MySQL综合练习50实例

    1.请创建如下表,并添加相应约束: 2.自行构造测试数据: 新建数据库 创建表 构造测试数据 #Step1-创建数据库LuffyCity_MySQL; #CREATE DATABASE LuffyCi ...

  9. IO Streams:对象流

    简介 正如数据流支持原始数据类型的I / O一样,对象流支持对象的I / O.标准类中的大多数但不是全部都支持对象的序列化.那些实现标记接口Serializable的那些. 对象流类是ObjectIn ...

  10. POJ 3254:Corn Fields(状态压缩DP)

    题目大意:一个矩形的草地,分为多个格子,有的格子可以有奶牛(标为1),有的格子不可以放置奶牛(标为0),计算摆放奶牛的方案数. 分析: f[i,j]表示第i行状态为j的方案总数. 状态转移方程f[i, ...