1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /* — kernelhook.h — */ #include <ntifs.h> #include <ntddk.h> #pragma pack(1) typedef struct _KERNEL_HOOK { PVOID FuncAddr; PVOID Hook; UCHAR JMP[5]; UCHAR OrgBytes[5]; PVOID OrgFunc; }KERNEL_HOOK,*PKERNEL_HOOK; #pragma pack() #ifdef __cplusplus extern "C" { VOID ClearWriteProtect(VOID); VOID SetWriteProtect(VOID); BOOLEAN InitHook(PKERNEL_HOOK Hook,PVOID Address,PVOID HookFunction); VOID StartHook(PKERNEL_HOOK Hook); VOID UnHook(PKERNEL_HOOK Hook); VOID RemoveHook(PKERNEL_HOOK Hook); } #else VOID ClearWriteProtect(VOID); VOID SetWriteProtect(VOID); BOOLEAN InitHook(PKERNEL_HOOK Hook,PVOID Address,PVOID HookFunction); VOID StartHook(PKERNEL_HOOK Hook); VOID UnHook(PKERNEL_HOOK Hook); VOID RemoveHook(PKERNEL_HOOK Hook); #endif BOOLEAN InitHook(PKERNEL_HOOK Hook,PVOID Address,PVOID HookFunction) { ULONG OrgFunc,FuncAddr; Hook–>FuncAddr=Address; Hook–>OrgFunc=ExAllocatePool(NonPagedPool,4096); if(!Hook–>OrgFunc) return FALSE; memcpy(Hook–>OrgBytes,Address,5); memcpy(Hook–>OrgFunc,Hook–>OrgBytes,5); Hook–>JMP[0]=0xe9; *(PULONG)&Hook–>JMP[1]=(ULONG)HookFunction–(ULONG)Address–5; OrgFunc=(ULONG)Hook–>OrgFunc+5; FuncAddr=(ULONG)Hook–>FuncAddr+5; *(PUCHAR)((PUCHAR)Hook–>OrgFunc+5)=0xe9; *(PULONG)((PUCHAR)Hook–>OrgFunc+6)=FuncAddr–OrgFunc–5; return TRUE; } VOID StartHook(PKERNEL_HOOK Hook) { ClearWriteProtect(); memcpy(Hook–>FuncAddr,Hook–>JMP,5); SetWriteProtect(); } VOID UnHook(PKERNEL_HOOK Hook) { ClearWriteProtect(); memcpy(Hook–>FuncAddr,Hook–>OrgBytes,5); SetWriteProtect(); } VOID RemoveHook(PKERNEL_HOOK Hook) { ExFreePool(Hook–>OrgFunc); memset(Hook,0,sizeof(KERNEL_HOOK)); } VOID ClearWriteProtect(VOID) { __asm { cli push eax mov eax, CR0 and eax, not 0x10000 mov CR0, eax pop eax } } VOID SetWriteProtect(VOID) { __asm { push eax mov eax, CR0 or eax, 0x10000 mov CR0, eax pop eax sti } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | /* — Driver.cpp — */ #include "kernelhook.h" #include<stdio.h> #define IOCTL_PROTECT_PROCESS (ULONG) CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_WRITE_ACCESS) extern "C" LPSTR PsGetProcessImageFileName(PEPROCESS); typedef NTSTATUS (*pPsLookupProcessByProcessId)(HANDLE,PEPROCESS*); pPsLookupProcessByProcessId fnPsLookupProcessByProcessId; KERNEL_HOOK PLPHook; UNICODE_STRING NtNameString; UNICODE_STRING Win32NameString; extern "C" { PVOID Hook(ULONG ServiceNumber,PVOID Hook); NTSTATUS HookPsLookupProcessByProcessId(HANDLE ProcessId,PEPROCESS* ep); NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObj, IN PUNICODE_STRING registryPath); VOID NTAPI DriverUnload(IN PDRIVER_OBJECT driverObj); NTSTATUS NTAPI CreateCloseHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS MyDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); } static ULONG ProcessID = 0; NTSTATUS HookPsLookupProcessByProcessId(HANDLE ProcessId,PEPROCESS* ep) { NTSTATUS ret; ret=fnPsLookupProcessByProcessId(ProcessId,ep); if(NT_SUCCESS(ret)) { if((ULONG)ProcessId >= ProcessID && (ULONG)ProcessId < (ProcessID + 4)) { ObDereferenceObject(*ep); *ep=NULL; return STATUS_ACCESS_DENIED; } } return ret; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObj, IN PUNICODE_STRING registryPath) { PDEVICE_OBJECT DeviceObject = NULL; NTSTATUS Status; RtlInitUnicodeString( &NtNameString, L"\\Device\\MyDevice" ); RtlInitUnicodeString( &Win32NameString , L"\\DosDevices\\MyDevice" ); Status = IoCreateDevice(driverObj, 0, &NtNameString, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if ( !NT_SUCCESS (Status) ) { DbgPrint("IoCreateDevice 실패"); return Status; } DbgPrint("IoCreateDevice 성공."); Status = IoCreateSymbolicLink(&Win32NameString, &NtNameString); if(!NT_SUCCESS(Status)) { DbgPrint("IoCreateSymbolicLink 실패."); IoDeleteDevice(driverObj–>DeviceObject); return Status; } DbgPrint("IoCreateSymbolicLink 성공."); driverObj–>DriverUnload = DriverUnload; driverObj–>MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceControl; driverObj–>MajorFunction[IRP_MJ_CREATE] = CreateCloseHandler; driverObj–>MajorFunction[IRP_MJ_CLOSE] = CreateCloseHandler; InitHook(&PLPHook,PsLookupProcessByProcessId,HookPsLookupProcessByProcessId); fnPsLookupProcessByProcessId=(pPsLookupProcessByProcessId)PLPHook.OrgFunc; StartHook(&PLPHook); return STATUS_SUCCESS; } VOID NTAPI DriverUnload(IN PDRIVER_OBJECT driverObj) { DbgPrint("드라이버 언로드 완료."); UnHook(&PLPHook); RemoveHook(&PLPHook); IoDeleteSymbolicLink(&Win32NameString); IoDeleteDevice(driverObj–>DeviceObject); } NTSTATUS NTAPI CreateCloseHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Irp–>IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Irp–>IoStatus.Status; } NTSTATUS MyDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); Irp–>IoStatus.Status = STATUS_SUCCESS; if(stack–>Parameters.DeviceIoControl.IoControlCode == IOCTL_PROTECT_PROCESS) { if(Irp–>AssociatedIrp.SystemBuffer == NULL) { Irp–>IoStatus.Status = STATUS_INVALID_BUFFER_SIZE; return Irp–>IoStatus.Status; } ProcessID = *((PULONG) Irp–>AssociatedIrp.SystemBuffer); } else { Irp–>IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; } IoCompleteRequest(Irp,IO_NO_INCREMENT); return Irp–>IoStatus.Status; } | cs |