XP中Inline HOOK 8042驱动实现键盘钩子的方法

《Windows内核安全与驱动编程》-第八章-键盘的过滤学习-day-4 键盘的过滤 Hook 分发函数 8.5.4 端口驱动和类驱动之间的协作机制 ​ 当键盘上一个键被按下时,产生一个 Make Code 引发键盘中断; 当键盘上一个键被松开时,产生一个 Break Code 引发键盘中断。键盘中断导致键盘中断服务例程被执行,最终导致 i8042prt 的 I8042KeyboardInterruptService 被执行。 ​ 在 I8042KeyboardInte... 阅读详情
首先说说我写这个驱动的动机,说来特别搞笑。首先是QQ的Nportect有时候会搞得我的键盘按键混乱,这搞得我很郁闷。这使我对键盘产生了兴趣,但是真正让我动手写的原因却更有趣。公司有一台老机器给我们用于测试,但机器的键盘却不好用,我们只能把测试用的命令复制到文本中上传上去。如此的不便使我动手写了一个远程控制键盘的驱动,由于我不知道每个键的scancode,网上的资料又乱七八糟懒得仔细看了,所以顺编写了这个按键记录的东东,本文的重点是讨论这个按键记录的东东。(遗憾的是在我完成前测试机的键盘已经被换掉了)。

先简单谈谈键盘的工作原理(具体的资料请再网上搜索),顺便说一下本文涉及的所有知识是我通过调试、试验、查书自己理解出来的,如果有错误请您务必与我联系,我将十分感谢。键盘的工作原理十分简单,键盘可以理解为一个按键矩阵和一个8048芯片,每个键都有个坐标值(并不准确,真实情况并不是一一对应,所以非机械键盘一定会有按键冲突),8042能把坐标成scancode,如果你有一个硬件的记录器,接在他们中间,Ok,Game Over了,你已经搞定了,请点击窗口右上角的叉。和我一样贫困的你,显然没有钱购买一个硬件记录器,所以我们还得花点精力继续Hack吧。8042会把这个scancode发给pc上的8048,8048偷偷告诉从8259a,8259a又告诉另一个主8259a叫它通知CPU在哪个IRQ上产生了一个中断,完了CPU就忙着去处理它了……嗯大体经过就是这样啦,大体了解到这个程度就行了。

好了,那我们该怎么办呢,以你敏锐的hacker直觉会马上想到,IDTHOOK呗。但是以我经历过的惨痛的教训可以告诉你,我不能再系统的ISR之前就吧0x60端口的数据读出来,这样0x60里的数据会清空,系统就无法得到这次按键了。你想说充填数据么?放弃吧,对0x60的充填导致了数次的BSOD,因为充填数据又将触发中断造成递归调用,你的机器将死于栈溢。我还企图屏蔽中断,结果是死锁。这些失败最终我放弃了这个方案。如果你充填成功了,一定记得告诉我昂,我的机器是Sonys56c/b 系统是Winxp sp2。我希望这能让你少走弯路。难道没办法了么,我跟到了i8042驱动(i8042prt.sys)里,很明显处理按键中断的例程是I8042KeyboardInterruptService。首先我想到的是替换它,但是入口都是IN参数,实在无法改变什么。无奈之下我最终选择了InlineHook,hoho~

首先是当然是得到它的地址啦,从IDT下手,开始找吧~sidt得到idtr的48,取后两个16位MAKELONG,这是IDT的入口,IDT里放的都是门结构,什么中断门啊、陷阱门啊、调用门啊……,门都长得不一样看仔细。然后呢,这里我有点糊涂,xpsp2的中断调用号为啥有的是0x93有的是0x31捏?不管了,我的是0x93,用WinDbg很容易看出来。反正要查也不太难,这里我都写死了。废话少说,赶快找到找到IDT里第0x93个门看看吧。门结构看起来是这样的
The cpp code:
  1. typedef struct  
  2. {   
  3. unsigned short LowOffset;   
  4. unsigned short selector;   
  5. unsigned char unused_lo;   
  6. unsigned char segment_type:4; //0x0E is an interrupt gate   
  7. unsigned char system_segment_flag:1;   
  8. unsigned char DPL:2; // descriptor privilege level    
  9. unsigned char P:1; /* present */  
  10. unsigned short HiOffset;   
  11. } IDTENTRY;  
typedef struct
{
unsigned short LowOffset;
unsigned short selector;
unsigned char unused_lo;
unsigned char segment_type:4; //0x0E is an interrupt gate
unsigned char system_segment_flag:1;
unsigned char DPL:2; // descriptor privilege level
unsigned char P:1; /* present */
unsigned short HiOffset;
} IDTENTRY;


聪明的你一定知道MAKELONG(LowOffset,HiOffset)将指引你去那,我比较笨找了很久才知道,传说中有这么个结构叫_KINTERRUPT,呵呵,问问WinDbg它长什么样吧
>!dt _KINTERRUPT
Int2B        Type             0x000
Int2B        Size              0x002
_LIST_ENTRY    InterruptListEntry   0x004
Ptr32        ServiceRoutine   0x00c
Ptr32 Void     ServiceContext   0x010
Uint4B       SpinLock         0x014
Uint4B      TickCount        0x018
Ptr32 Uint4B   ActualLock       0x01c
Ptr32       DispatchAddress  0x020
Uint4B      Vector           0x024
UChar       Irql             0x028
UChar       SynchronizeIrql  0x029
UChar       FloatingSave     0x02a
UChar       Connected        0x02b
Char       Number           0x02c
UChar       ShareVector      0x02d
_KINTERRUPT_MODE Mode             0x030
Uint4B      ServiceCount     0x034
Uint4B      DispatchCount    0x038
[106] Uint4B   DispatchCode     0x03c

忠实可靠的WinDbg不厌其烦的告诉你这就是传说中的_KINTERRUPT,我在惊叹WinDbg的博学多才之余很快地发现了原来MAKELONG(LowOffset,HiOffset)龌龊的指向了DispatchCode这里,而I8042KeyboardInterruptService的地址安详的躺在ServiceRoutine处。秘密一览无余了,哈哈。接下来是我最擅长的类型猜解,恩,很有难度,比1难多了……


我们轻易的就得到了入口地址,看看它都干了些什么吧(不能贴出所有代码,有长度限制,只能这样了)
f9a1c495 6a18            push    18h
f9a1c497 68a8f7a1f9      push    offset i8042prt!`string'+0x154 (f9a1f7a8)
f9a1c49c e8ff000000      call    i8042prt!_SEH_prolog (f9a1c5a0)
……
f9a1c4d1 8d45e3          lea     eax,[ebp-1Dh]
f9a1c4d4 50              push    eax
f9a1c4d5 6a01            push    1
f9a1c4d7 e818ffffff      call    i8042prt!I8xGetByteAsynchronous (f9a1c3f4)
f9a1c4dc 8d864a010000    lea     eax,[esi+14Ah]
f9a1c4e2 8a08            mov     cl,byte ptr [eax]
f9a1c4e4 888e4b010000    mov     byte ptr [esi+14Bh],cl
f9a1c4ea 8a4de3          mov     cl,byte ptr [ebp-1Dh]
……
f9a1c593 e848000000      call    i8042prt!_SEH_epilog (f9a1c5e0)
f9a1c598 c20800          ret     8
以你精湛的汇编功底一定比我看得快,其实我压根就没看,跟到I8xGetByteAsynchronous这里面看看,果然在这读端口了,返回后eax就是数据,好吧,不用往下看了,开始表演杂技吧,把你的代码贴进来吧!!从偏移0xf9a1c4dc - 0xf9a1c495出开始覆盖代码吧!!关于运行时补丁的方法这里不再赘述了,可以阅读著名的Detours: Binary Interception of Win32 Functions。

文章不错!但是关于键盘原理的描述上有些小语误:

很早以前,键盘端的芯片叫8048、PC端的芯片叫8042,为了兼容早期6针脚的 XT/AT 键盘,不知道是什么组织一共设计了三套键盘扫描码(我怀疑是IBM最早定义的)。

键盘端8048检测到矩阵状态变化时产生扫描码2,传输到PC端后8042又会转码成扫描码1(因为6针脚的 XT/AT 键盘用 Scan Code 1,做芯片的时候要考虑的比较多)

然后8042触发8259A级联第一片的IRQ1,再下面就是你Hook的舞台了~

由于实模式和保护模式的中断是不同的,所以需要重定位。用 Alexander 写的 Interrupt Hook 来看(代码和Rootkit.com的代码基本类似),可以很容易的发现,Win32在保护模式下将8259A的中断地址(IRQ0 - IRQ15)重定位到端口 0x30 - 0x3F,所以,这就是“xpsp2的中断调用号为啥有的是0x93有的是0x31捏?”的原因 —— 0x93的确是真正的键盘中断端口,我没研究过,但我怀疑这是Win键盘驱动造成的(键盘驱动还要干好多事,光是支持组合键这功能写代码就能把人烦死...)。

最后,现在的机器里都没有这些芯片了,这是最老早的 IBM PC 的设计,现在它们都集成在南桥里了,台湾的威盛搞这个很悍(收复台湾...)。另外,买一个硬件键盘嗅探器没多少钱。

看代码去了~ 呵呵

<寒江独钓>Windows内核安全编程__键盘过滤之内核级Hook(一) Hook分发函数 前一篇文章讲述了进行键盘过滤,截取用户输入的方法。本篇文章开始更加深入地讨论键盘的过滤与反过滤对抗。无论是过滤还是饭过滤,原理都是过滤,取胜的关键在于谁第一个得到信息。 一种方发是Hook分发函数,即将键盘驱动的分发函数替换成自己的函数用来达到过滤的目的。 阅读详情

相关推荐

<寒江独钓>Windows内核安全编程__键盘过滤之内核级Hook(二)

Windows内核安全编程__键盘过滤内核级Hook(二) 如果不想让键盘过滤驱动程序或回调函数首先获得按键,则必须比端口驱动更加底层一些。 早期版本的QQ反盗号驱动的原理是这样的:用户要输入密码时(比如把输入焦点移动到了密码框里),就注册一个中断服务来接管键盘中断,比如0x

The New Old Things 3892

应用层InLine HOOK

exe程序在xp下运行需要设置的地方 // ConsoleApplication6.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> typedef int(__stdcall *MessageBox_type) ( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType ); MessageBox_type old_MessageBoxA; //定

Windows内核学习笔记 167

api钩子的实现--用Detours拦截Win32API函数

api钩子的实现--用Detours拦截Win32API函数

中转inline hook,不需要恢复首字节的hook

中转inline hook,不需要恢复首字节的hook 分类: HOOK2015-02-23 23:38 446人阅读 评论(1) 收藏 举报 HOOKinline hook 注:我实验的环境:win7 x64 经验证XP会有稍微区别,主要是我本次实验HOOK的API, 从XP到WIN7微软有了些许改变。 -----------------------------

linuxheik的专栏 796

完美支持64&32位InlineHook,C语言,C++类 都有

Windows 64位和32位Inline Hook的例子。包括C语言代码,和封装好的C++类,绝对超值,超简单实用的例子,可以直接运行,用了绝对说好!

XP键盘钩子源码

XP下的键盘钩子,有记录键盘事件和屏蔽系统组合键的功能。

键盘驱动系列---JIURL键盘驱动 5

7 键盘驱动的运作 7.1 输入数据队列简介 i8042prt 和 kbdclass 各有一个输入数据队列,他们是循环使用的缓冲区。他们的每个单元是一个 KEYBOARD_INPUT_DATA 结构。 i8042prt 的自定义的设备扩展中,保存着一些指针和计数值,用来使用它的那个输入数据队列。 PKEYBOARD_INPUT_DATA 类型的 InputData , Da

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 2027

VC写的一个简单的InlineHook小例子

一个vc写的inlineHook MessageBox小例子,希望对大家有帮助。

基于VC++开发InlineHook网络数据发送接收函数

大家都懂,很多时候开发项目需要修改网络数据,代码如下,请柬代码分析#include "stdafx.h" #include <stdio.h> #include <Windows.h> #include <Winsock2.h> #ifdef _MANAGED #pragma managed(push, off)...

weixin_30662849的博客 341

Hypermesh二次开发实战:从Tcl/Tk脚本到Ext API的进阶之路

本文系统介绍了Hypermesh二次开发的进阶路径,从自动化重复操作的Tcl/Tk脚本入门,到利用HMASCII接口深度读写模型数据,最终深入Ext API进行高性能计算与功能定制。通过实战案例,帮助工程师掌握从脚本录制到C++插件开发的完整技能,显著提升CAE前处理效率与自动化水平。

weixin_29306875的博客 670

开关电源环路稳定性分析(01)-Buck变换器

这篇文章主要是根据Buck变换器的拓扑结构,利用欧姆定律,基尔霍夫定律,积分微分,这些我们所熟悉的理论推导出了开关电源输入和输出关系的表达式,我相信看完这篇文章,应该是可以自己推导一次。在后面的文章中,我们同样会按照这样的风格,尽量使用大家都已经掌握的知识,来一步一步的拆解晦涩难懂的环路稳定性的问题,在前面先把积木搭起来,后面综合分析的时候就不会显得那么困难!

D_Katter的博客 3833

InlineHook和API HOOK从原理开始,一次性掌握劫持技术

在汇编中可以转移指令执行流程的指令是JMP和CALL,我们要干的就是在要将原来的执行流中插入JMP或CALL,在开始写代码之前,你需要想清楚使用JMP还是CALL,如何使用在于你的目的,使用JMP可以保证堆栈偏移不会发生变化,但需要计算两次JMP 的偏移量,而使用CALL则只需要计算一次,就是CALL的偏移量,而回跳地址直接使用ret,但缺点是CALL会更改堆栈的偏移,因为要压入回跳地址,我通常喜欢使用CALL来做劫持,因为堆栈的偏移相对于JMP那种繁琐的计算是不值一提(😄)的。

qq_50749602的博客 1125

单细胞分析避坑指南:SCTransform和Harmony参数设置详解

本文深入解析了单细胞分析中SCTransform标准化与Harmony批次校正的关键参数设置。针对10x Genomics等数据,详细探讨了如何通过调整`vars.to.regress`、`theta`等核心参数,在有效去除技术噪音的同时,避免过度校正以保留关键的生物学差异,从而提升分析结果的可靠性与可解释性。

weixin_29053073的博客 608

安全控件

0x01 定义    简单说,安全控件是一种为了提升账户安全性,防止账户密码等私密信息被木马或病毒窃取的客户端程序,安全控件大多小巧,可以通过 ActiveX 或者手工下载的方式安装。0x02 使用安全控件    随着移动互联网的普及和网上支付的盛行,越来越多的恶意软件病毒木马针对用户的键盘鼠标操作进行记录,从而窃取用户的账号密码等。因此,如何让用户的帐号信息输入更安全,如何防止木马和病毒盗取用户...

煜铭2011 3043

ESP32连接PDM麦克风操作指南:新手入门必看

手把手教你如何将ESP32与PDM麦克风连接,采集音频数据并用于音频分类应用。内容涵盖硬件接线、代码配置及实际调试技巧,适合初学者快速上手esp32在声音识别场景中的使用。

weixin_42590539的博客 1329

手把手教你用STM32的SPI驱动MCP2517FD实现CAN FD通信(附完整代码)

本文详细介绍了如何使用STM32通过SPI驱动MCP2517FD实现CAN FD通信,涵盖硬件连接、SPI驱动编写、寄存器配置及数据收发实战。提供完整代码示例和常见问题排查指南,帮助开发者快速构建高可靠性的CAN FD通信系统,适用于汽车电子和工业控制等领域。

weixin_30607029的博客 674

驱动键盘钩子

现在网上很多盗QQ的木马,发现都不管用得,顺便做了这只QQ木马,这里发布一部分核心的代码内核代码,用于记录QQ密码,此代码编译后可以在win2000到win7下正常运行,百分百能获取正确的QQ和密码,用户太下面的代码,只能获取QQ和密码,不带邮件发送功能,和系统隐藏功能,主要是怕有些人哪去干坏事,所以我不发布完整版的代码,以下驱动代码需要编译为NTI0.SYS文件放到C:\\Windo...

weixin_30443731的博客 471

C#上位机与MES系统数据对接:从协议选型到安全传输的实战解析

本文详细解析了C#上位机与MES系统数据对接的全过程,从协议选型到安全传输的实战技巧。针对工业互联网场景下的数据对接挑战,提供了RESTful API、MQTT和OPC UA等协议的选型建议,并分享了健壮性设计、异常处理和安全传输的实用代码示例,帮助开发者高效实现数据上传与系统集成。

weixin_30566063的博客 105

FSD键盘钩子框架参考爱写驱动的女装大佬

环境:vs2013+wdk8.1 #include <ntddk.h> extern POBJECT_TYPE *IoDriverObjectType; PDRIVER_OBJECT kbdriver = NULL; typedef NTSTATUS(*pBeforeRead)(PDEVICE_OBJECT pDevice, PIRP pIrp); pBeforeRead Befo...

Cosmopolitan的博客 494

麻辣香锅病毒分析

Spicy Hot Pot浏览器劫持病毒(麻辣香锅病毒)从2020年初被安全公司监测到,因其病毒模块带有MLXG_KM被安全行业代称麻辣香锅病毒。目前通过各种激活工具传播, 包括暴风激活、小马激活和KMS激活等诸多工具,疑似与下载站进行合作推广此类激活工具。Spicy Hot Pot 是一个浏览器劫持 Rootkit,它会将用户的主页更改为指向恶意软件操作员控制的页面,此外还会将内存转储从机器上传到预定义的服务器,并结合本地更新功能以确保其保持更新。通常浏览器劫持者会通过更改用户主页的恶意可执行文件或注册表

不忘初心,护天下安全! 4788

题解:洛谷 P14357 [CSP-J 2025] 拼数

等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。小 R 想知道,在他所有能拼成的正整数中,最大的是多少。你需要帮助小 R 求出他能拼成的正整数的最大值。小 X 给了小 R 一个字符串。输出一行一个正整数,表示小 R 能拼成的正整数的最大值。中的任意多个数字,按任意顺序拼成一个正整数。,表示小 X 给小 R 的字符串。#普及-# #其他排序#洛谷:[P14357。

团爸讲算法 1394

键盘按键处理过程

键盘按键: 1. 当按下键盘的一个按键时,键盘产生硬件中断信号发到总线,总线将信号发送到ioapic寄存器接收,ioapic寄存器存储了键盘中断的中断idt的索引号,和发给哪个cpu来处理(针对多核),    然后发给该cpu的local apic 寄存器 2. local apic接收到信号,里面存储了中断idt 索引号到idt键盘中断处理地址的映射。然后发给键盘中断处理例程,该例程再依次...

研究源码的最底层,只持有正确的仓位 3420

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

用Detours实现APIHOOK

用Detours实现APIHOOK Detours是一个软件开发库,它用于实现拦截Win32二进制代码中的API函数。 它使用一个Jmp指令替换了目标函数的前面几个字节,使得控制直接调用实现的 Detours函数。并通过一个trampoline函数保留了原来函数的功能调用。 我们知道,实现APIHOOK主要有两个重要环节,一是如何把代码注入到目标地 址空间,二是如何让自己的代码被调用。

Lassewang的成长历程 4404

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Detours内联HOOK

1.Detours文件夹中有所需要用到的lib文件和h文件 2.将Detours文件夹拖动到工作目录下 3.附加包含目录,这样在添加头文件时就不需要填写目录而是直接可以填写头文件名,VS可以根据附加包含目录知道头文件在工作目录的哪个文件夹里 4.在工程里面添加一个筛选器Detours 5将工作目录下的detours41x86.lib直接拖动到工程中的筛选器里面。 ps:(当然也可以不拖到库文件到工程中,因为这样有时候可能会感觉很混乱。 在连接器-输出里面的附加依赖项中添加 detours41x86

sanqiuai的博客 910

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Inline Hook 钩子编写技巧

有时候我们需要自定义Hook对象,这时候我们就可以使用本方法,直接在最后写上我们需要Hook的地址即可。Inline Hook 钩子编写技巧

微软技术分享 1万+

简明的Detours Hook教程

tag: Hook, Detours,Windows,CreateRemoteThread,MessageBox 前言     项目开发中需要跟踪其它程序的API调用情况。但厂商又无源码提供,故只好自己动手去Trace了。     Google/Baidu了许久,也搜集了很多代码。也经过实验和测试,总结了本文供大家参考。     本文针对Windows Hook技术在编程中的应用进行讨论,

天外飞猪的家 1万+
上一篇: 对抗瑞星文件监控 恢复fsd
下一篇: IrpCreateFile
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值