kkmomo 發表於 2015-1-10 22:15:55

kernel driver - NTHook

本帖最後由 kkmomo 於 2015-1-10 23:17 編輯

幾年前從一個自稱香港人的 alan 大大那得到的
只有小改一點點讓 vc 可以 compile
當時在 32bits os 測試是可以 work
不過很久沒去碰這個了,剛才整理東西時翻到 給想研究的人看看

2樓  entry.cpp
3樓  NtOpenProcess.h
4樓  NtProtectVirtualMemory.h
5樓  NtReadVirtualMemory.h
6樓  NtWriteVirtualMemory.h

kkmomo 發表於 2015-1-10 22:19:55

// Author : alan
// entry.cpp

#include <ntddk.h>
#include "NtOpenProcess.h"
#include "NtReadVirtualMemory.h"
#include "NtProtectVirtualMemory.h"
#include "NtWriteVirtualMemory.h"

#define _Driver_name      L"\\Device\\NTHook"
#define _Symbolic_name      L"\\DosDevices\\NTHook1"

#define INITCODE code_seg("INIT")
#define PAGECODE code_seg("PAGE")
#pragma INITCODE

VOID DriverUnLoad(PDRIVER_OBJECT driver);
NTSTATUS DispatchIrp(PDEVICE_OBJECT driver,PIRP irp);

extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING driver_object_name)
{
  HookNtOpenProcess();
  HookNtReadVirtualMemory();
  HookNtProtectVirtualMemory();
  HookNtWriteVirtualMemory();

  NTSTATUS status=STATUS_SUCCESS;
  driver->MajorFunction=DispatchIrp;
  driver->MajorFunction=DispatchIrp;
  driver->MajorFunction=DispatchIrp;
  driver->MajorFunction=DispatchIrp;
  driver->MajorFunction=DispatchIrp;
  driver->DriverUnload=DriverUnLoad;
  
  UNICODE_STRING driver_name;
  RtlInitUnicodeString(&driver_name,_Driver_name);
  
  PDEVICE_OBJECT device_object;
  status=IoCreateDevice(driver,NULL,&driver_name,FILE_DEVICE_UNKNOWN,NULL,FALSE,&device_object);
  if(!NT_SUCCESS(status))
  {
    KdPrint(("創建設備失敗!\n"));
    return status;
  }
  KdPrint(("創建設備成功!\n"));
  device_object->Flags |= DO_BUFFERED_IO;
  
  UNICODE_STRING symbolic_name;
  RtlInitUnicodeString(&symbolic_name,_Symbolic_name);
  status=IoCreateSymbolicLink(&symbolic_name,&driver_name);
  if(!NT_SUCCESS(status))
  {
    IoDeleteDevice(device_object);
    KdPrint(("創建符號鏈接失敗!\n"));
    return status;
  }
  KdPrint(("創建符號鏈接成功!\n"));
  return STATUS_SUCCESS;
}

#pragma PAGEDCODE
VOID DriverUnLoad(PDRIVER_OBJECT driver)
{
  UNICODE_STRING symbol_name;
  RtlInitUnicodeString(&symbol_name,_Symbolic_name);
  IoDeleteSymbolicLink(&symbol_name);
  IoDeleteDevice(driver->DeviceObject);
  KdPrint(("刪除設備成功!\n"));
  UnhookNtOpenProcess();
  UnhookNtReadVirtualMemory();
  UnhookNtProtectVirtualMemory();
  UnhookNtWriteVirtualMemory();
}

#pragma PAGEDCODE
NTSTATUS DispatchIrp(PDEVICE_OBJECT driver,PIRP irp)
{
  irp->IoStatus.Status=STATUS_SUCCESS;
  irp->IoStatus.Information=0;
  IoCompleteRequest(irp,IO_NO_INCREMENT);
  KdPrint(("進入IRP例程!\n"));
  return STATUS_SUCCESS;
}

kkmomo 發表於 2015-1-10 22:20:41

// Author : alan
// NtOpenProcess.h

#include <ntddk.h>

typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PULONG ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
extern "C" PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

VOID HookNtOpenProcess();
VOID UnhookNtOpenProcess();

PEPROCESS  processEPROCESS = NULL;  
ANSI_STRING  p_str1,p_str2;      

ULONG OldNtOpenProcessAddress = 0;
ULONG Addr_NtOpenProcess;
ULONG Addr_ObWatchHandles;      
ULONG Addr_SEH_prolog;         
ULONG Jmp_Addr_NtOpenProcess;   

__declspec(naked) NTSTATUS __stdcall MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId)
{
processEPROCESS = IoGetCurrentProcess();
RtlInitAnsiString(&p_str1,(PCSZ)processEPROCESS+0x174);
RtlInitAnsiString(&p_str2,"MapleStory.exe");
   if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
_asm
{
jmp OldNtOpenProcessAddress
}  
}
   else
   {
_asm
{
push 0x0c4
mov edx,Addr_ObWatchHandles
push edx
mov edx,Jmp_Addr_NtOpenProcess
push edx
mov edx,Addr_SEH_prolog
jmp edx
        }
    }
}

VOID HookNtOpenProcess()
{
            
ULONG NtOpenProcessIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtOpenProcessIndexAddress1 = NtOpenProcessIndexAddress + 0x7A*4;

OldNtOpenProcessAddress = *(ULONG*)NtOpenProcessIndexAddress1;

__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax

mov ebx,NtOpenProcessIndexAddress1      
mov eax,dword ptr
mov Addr_NtOpenProcess,eax   
      
add eax,0x0f
mov Jmp_Addr_NtOpenProcess,eax      
         
mov ebx,Addr_NtOpenProcess        
mov eax,dword ptr            
mov Addr_ObWatchHandles,eax

mov eax,dword ptr         
add eax,Addr_NtOpenProcess
add eax,0x0a
add eax,5
mov Addr_SEH_prolog,eax
}

*(ULONG*)NtOpenProcessIndexAddress1 = (ULONG)MyNtOpenProcess;
DbgPrint("Addr_ObWatchHandles is %x",Addr_ObWatchHandles);
DbgPrint("Addr_NtOpenProcess is %x",Addr_NtOpenProcess);
DbgPrint("Addr_SEH_prolog is %x",Addr_SEH_prolog);
DbgPrint("Jmp_Addr_NtOpenProcess is %x",Jmp_Addr_NtOpenProcess);
__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("HookNtOpenProcess");
}

VOID UnhookNtOpenProcess()
{
ULONG NtOpenProcessIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtOpenProcessIndexAddress1 = NtOpenProcessIndexAddress + 0x7A*4;

_asm
{
cli
pushad                  
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*(ULONG*)NtOpenProcessIndexAddress1 = (ULONG)OldNtOpenProcessAddress;
_asm
{     
mov eax,cr0
or eax,10000h
mov cr0,eax
popad
sti
}

DbgPrint("UnhookNtOpenProcess");

}

kkmomo 發表於 2015-1-10 22:21:36

// Author : alan
// NtProtectVirtualMemory.h

#include <ntddk.h>

VOID HookNtProtectVirtualMemory();
VOID UnhookNtProtectVirtualMemory();

ULONG JmpNtProtectVirtualMemory = 0;
ULONG OldNtProtectVirtualMemoryAddress = 0;

PEPROCESS  ProtectEPROCESS = NULL;
ANSI_STRING pp_str1,pp_str2;

ULONG Addr_NtProtectVirtualMemory;
ULONG Addr_P_NoAccessPte;  
ULONG Addr_P_SEH_prolog;        
ULONG Jmp_Addr_NtProtectVirtualMemory = 0;   

__declspec(naked) NTSTATUS __stdcall MyNtProtectVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection
)
{
ProtectEPROCESS = IoGetCurrentProcess();
RtlInitAnsiString(&pp_str1,(PCSZ)ProtectEPROCESS+0x174);
RtlInitAnsiString(&pp_str2,"MapleStory.exe");
    if (RtlCompareString(&pp_str1,&pp_str2,TRUE) == 0)
    {
_asm
{
jmp OldNtProtectVirtualMemoryAddress
}  
    }
    else
    {
_asm
{
push 0x44
mov edx,Addr_P_NoAccessPte
push edx
mov edx,Jmp_Addr_NtProtectVirtualMemory
push edx
mov edx,Addr_P_SEH_prolog
jmp edx
}
    }
}

VOID HookNtProtectVirtualMemory()
{

ULONG NtProtectVirtualMemoryIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtProtectVirtualMemoryIndexAddress1 = NtProtectVirtualMemoryIndexAddress + 0x89*4;

OldNtProtectVirtualMemoryAddress = *(ULONG*)NtProtectVirtualMemoryIndexAddress1 ;
/*
JmpNtProtectVirtualMemory = OldNtProtectVirtualMemoryAddress + 7;
Addr_P_NoAccessPte =  OldNtProtectVirtualMemoryAddress - 0xDE38E;
Addr_P_SEH_prolog = OldNtProtectVirtualMemoryAddress - 0x7C7F6;
Jmp_Addr_NtProtectVirtualMemory = OldNtProtectVirtualMemoryAddress + 0xC;
*/
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax

mov ebx,NtProtectVirtualMemoryIndexAddress1   
mov eax,dword ptr
mov Addr_NtProtectVirtualMemory,eax

add eax,0x0c
mov Jmp_Addr_NtProtectVirtualMemory,eax   
         
mov ebx,Addr_NtProtectVirtualMemory     
mov eax,dword ptr       
mov Addr_P_NoAccessPte,eax   

mov eax,dword ptr
add eax,Addr_NtProtectVirtualMemory
add eax,7
add eax,5
mov Addr_P_SEH_prolog,eax           
}
DbgPrint("Addr_NtProtectVirtualMemory is %x",Addr_NtProtectVirtualMemory);
DbgPrint("Addr_P_NoAccessPte is %x",Addr_P_NoAccessPte);
DbgPrint("Addr_P_SEH_prolog is %x",Addr_P_SEH_prolog);
DbgPrint("Jmp_Addr_NtProtectVirtualMemory is %x",Jmp_Addr_NtProtectVirtualMemory);

*(ULONG*)NtProtectVirtualMemoryIndexAddress1 = (ULONG)MyNtProtectVirtualMemory;

__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("HookNtProtectVirtualMemory");

}

VOID UnhookNtProtectVirtualMemory()
{
ULONG NtProtectVirtualMemoryIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtProtectVirtualMemoryIndexAddress1 = NtProtectVirtualMemoryIndexAddress + 0x89*4;
_asm
{
cli
pushad                  
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*(ULONG*)NtProtectVirtualMemoryIndexAddress1 = (ULONG)OldNtProtectVirtualMemoryAddress;
_asm
{     
mov eax,cr0
or eax,10000h
mov cr0,eax
popad
sti
}

DbgPrint("UnhookNtProtectVirtualMemory");

}

kkmomo 發表於 2015-1-10 22:22:35

// Author : alan
// NtReadVirtualMemory.h

#include <ntddk.h>

VOID HookNtReadVirtualMemory();
VOID UnhookNtReadVirtualMemory();

ULONG JmpNtReadVirtualMemory = 0;
ULONG OldNtReadVirtualMemoryAddress = 0;

PEPROCESS  ReadEPROCESS = NULL;
ANSI_STRING r_str1,r_str2;

ULONG Addr_NtReadVirtualMemory;
ULONG Addr_MmClaimParameter;   
ULONG Addr_R_SEH_prolog;        
ULONG Jmp_Addr_NtReadVirtualMemory = 0;

__declspec(naked) NTSTATUS __stdcall MyNtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL
)
{
ReadEPROCESS = IoGetCurrentProcess();
RtlInitAnsiString(&r_str1,(PCSZ)ReadEPROCESS+0x174);
RtlInitAnsiString(&r_str2,"MapleStory.exe");
    if (RtlCompareString(&r_str1,&r_str2,TRUE) == 0)
    {
_asm
{
jmp OldNtReadVirtualMemoryAddress
}  
    }
    else
{
_asm
{
push 0x1c
mov edx,Addr_MmClaimParameter
push edx
mov edx,Jmp_Addr_NtReadVirtualMemory
push edx
mov edx,Addr_R_SEH_prolog
jmp edx
}
    }
}

VOID HookNtReadVirtualMemory()
{

ULONG NtReadVirtualMemoryIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtReadVirtualMemoryIndexAddress1 = NtReadVirtualMemoryIndexAddress + 0xba*4;

OldNtReadVirtualMemoryAddress = *(ULONG*)NtReadVirtualMemoryIndexAddress1 ;

/*JmpNtReadVirtualMemory = OldNtReadVirtualMemoryAddress + 7;
Addr_R_SEH_prolog = OldNtReadVirtualMemoryAddress - 0x7869A;
Addr_MmClaimParameter = OldNtReadVirtualMemoryAddress - 0xDA3DA;
Jmp_Addr_NtReadVirtualMemory = OldNtReadVirtualMemoryAddress + 0xC;
*/
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax

mov ebx,NtReadVirtualMemoryIndexAddress1     
mov eax,dword ptr
mov Addr_NtReadVirtualMemory,eax
     
add eax,0x0c        
mov Jmp_Addr_NtReadVirtualMemory,eax
         
mov ebx,Addr_NtReadVirtualMemory
mov eax,dword ptr            
mov Addr_MmClaimParameter,eax

mov eax,dword ptr
add eax,Addr_NtReadVirtualMemory
add eax,7
add eax,5
mov Addr_R_SEH_prolog,eax           
}
DbgPrint("Addr_NtReadVirtualMemory is %x",Addr_NtReadVirtualMemory);
DbgPrint("Addr_R_SEH_prolog is %x",Addr_R_SEH_prolog);
DbgPrint("Addr_MmClaimParameter is %x",Addr_MmClaimParameter);
DbgPrint("Jmp_Addr_NtReadVirtualMemory is %x",Jmp_Addr_NtReadVirtualMemory);
*(ULONG*)NtReadVirtualMemoryIndexAddress1 = (ULONG)MyNtReadVirtualMemory;

__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("HookNtReadVirtualMemory");

}

VOID UnhookNtReadVirtualMemory()
{
ULONG NtReadVirtualMemoryIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtReadVirtualMemoryIndexAddress1 = NtReadVirtualMemoryIndexAddress + 0xba*4;
_asm
{
cli
pushad                  
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*(ULONG*)NtReadVirtualMemoryIndexAddress1 = (ULONG)OldNtReadVirtualMemoryAddress;
_asm
{     
mov eax,cr0
or eax,10000h
mov cr0,eax
popad
sti
}

DbgPrint("UnhookNtReadVirtualMemory");

}

kkmomo 發表於 2015-1-10 22:23:15

// Author : alan
// NtWriteVirtualMemory.h

#include <ntddk.h>

VOID HookNtWriteVirtualMemory();
VOID UnhookNtWriteVirtualMemory();

ULONG JmpNtWriteVirtualMemory = 0;
ULONG OldWriteVirtualMemoryAddress = 0;

PEPROCESS  WriteEPROCESS = NULL;
ANSI_STRING w_str1,w_str2;

ULONG Addr_NtWriteVirtualMemory;
ULONG Addr_W_MmClaimParameter;  
ULONG Addr_W_SEH_prolog;        
ULONG Jmp_Addr_NtWriteVirtualMemory = 0;   

__declspec(naked) NTSTATUS __stdcall MyNtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten OPTIONAL)
{
WriteEPROCESS = IoGetCurrentProcess();
RtlInitAnsiString(&w_str1,(PCSZ)WriteEPROCESS+0x174);
RtlInitAnsiString(&w_str2,"MapleStory.exe");
    if (RtlCompareString(&w_str1,&w_str2,TRUE) == 0)
    {
_asm
{
jmp OldWriteVirtualMemoryAddress
}  
    }
    else
    {
_asm
{
push 0x1C
mov edx,Addr_W_MmClaimParameter
push edx
mov edx,Jmp_Addr_NtWriteVirtualMemory
push edx
mov edx,Addr_W_SEH_prolog
jmp edx
}
    }
}

VOID HookNtWriteVirtualMemory()
{

ULONG NtWriteVirtualMemoryIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtWriteVirtualMemoryIndexAddress1 = NtWriteVirtualMemoryIndexAddress + 0x115*4;

OldWriteVirtualMemoryAddress = *(ULONG*)NtWriteVirtualMemoryIndexAddress1;
/*
JmpNtWriteVirtualMemory = OldWriteVirtualMemoryAddress + 7;
Addr_W_MmClaimParameter =  OldWriteVirtualMemoryAddress - 0xDA4CC;
Addr_W_SEH_prolog = OldWriteVirtualMemoryAddress - 0x787A4;
Jmp_Addr_NtWriteVirtualMemory = OldWriteVirtualMemoryAddress + 0xC;
*/
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax

mov ebx,NtWriteVirtualMemoryIndexAddress1   
mov eax,dword ptr
mov Addr_NtWriteVirtualMemory,eax

add eax,0x0c
mov Jmp_Addr_NtWriteVirtualMemory,eax   
         
mov ebx,Addr_NtWriteVirtualMemory     
mov eax,dword ptr       
mov Addr_W_MmClaimParameter,eax   

mov eax,dword ptr
add eax,Addr_NtWriteVirtualMemory
add eax,7
add eax,5
mov Addr_W_SEH_prolog,eax           
}
DbgPrint("Addr_NtWriteVirtualMemory is %x",Addr_NtWriteVirtualMemory);
DbgPrint("Addr_W_MmClaimParameter is %x",Addr_W_MmClaimParameter);
DbgPrint("Addr_W_SEH_prolog is %x",Addr_W_SEH_prolog);
DbgPrint("Jmp_Addr_NtWriteVirtualMemory is %x",Jmp_Addr_NtWriteVirtualMemory);

*(ULONG*)NtWriteVirtualMemoryIndexAddress1 = (ULONG)MyNtWriteVirtualMemory;

__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
DbgPrint("HookNtWriteVirtualMemory");

}

VOID UnhookNtWriteVirtualMemory()
{
ULONG NtWriteVirtualMemoryIndexAddress = (ULONG)(KeServiceDescriptorTable->ServiceTableBase);
ULONG NtWriteVirtualMemoryIndexAddress1 = NtWriteVirtualMemoryIndexAddress + 0x115*4;
_asm
{
cli
pushad                  
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*(ULONG*)NtWriteVirtualMemoryIndexAddress1 = (ULONG)OldWriteVirtualMemoryAddress;
_asm
{     
mov eax,cr0
or eax,10000h
mov cr0,eax
popad
sti
}

DbgPrint("UnhookNtWriteVirtualMemory");

}

zaq947 發表於 2015-1-27 15:17:28

好多的API阿~~
也許學習外褂這是必經的過程XD
頁: [1]
查看完整版本: kernel driver - NTHook