메뉴 닫기

[Kernel Driver] PsLookupProcessByProcessId Hooking [32bit]

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)Address5;
   OrgFunc=(ULONG)Hook>OrgFunc+5;
   FuncAddr=(ULONG)Hook>FuncAddr+5;
   *(PUCHAR)((PUCHAR)Hook>OrgFunc+5)=0xe9;
   *(PULONG)((PUCHAR)Hook>OrgFunc+6)=FuncAddrOrgFunc5;
   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

 

 

댓글 남기기

이메일은 공개되지 않습니다.