内核级hook的几种实现与应用

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

内核级HOOK的几种实现与应用

创建时间:2003-03-26

文章来源:

文章提交:sinister (jiasys_at_)

内核级HOOK的几种实现与应用

Author : sinister

Email : sinister@

HomePage:

实现内核级 HOOK 对于拦截、分析、跟踪系统内核起着致关重要的作用。实现的方法不同意味着应用侧重点的不同。如想要拦截 NATIVE API 那么可能常用的就是 HOOK SERVICE TABLE 的方法。如果要分析一些系统调用,那么可能想到用 HOOK INT 2E 中断来实现。如果想要拦截或跟踪其他内核 DRIVER 的调用,那么就要用到HOOK PE 的方法来实现。这里我们更注重的是实现,原理方面已有不少高手在网上发表过文章。大家可以结合起来读。下面以我写的几个实例程序来讲解一下各种方法的实现。错误之处还望各位指正。

1、HOOK SERVICE TABLE 方法:

这种方法对于拦截 NATIVE API 来说用的比较多。原理就是通过替换系统导

出的一个 SERVICE TABLE 中相应的 NATIVE API 的地址来达到拦截的目的。

因为此方法较为简单,网上也有不少资料来介绍。所以这里就不给出实例程序了。SERVICE TABLE 的结构如下:

typedef struct ServiceDescriptorEntry {

unsigned int *ServiceTableBase;

unsigned int *ServiceCounterTableBase;

unsigned int NumberOfServices;

unsigned char *ParamTableBase;

} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;

2、HOOK INT 2E 方法:

这种方法对于跟踪、分析系统调用来说用的比较多。原理是通过替换 IDT

表中的 INT 2E 中断,使之指向我们自己的中断服务处理例程来实现的。掌握

此方法需要你对保护模式有一定的基础。下面的程序演示了这一过程。

/*****************************************************************

文件名 : WssHookInt2e.c

描述 : 系统调用跟踪

作者 : sinister

最后修改日期 : 2002-11-02

*****************************************************************/

#include "ntddk.h"

#include "string.h"

#define DWORD unsigned __int32

#define WORD unsigned __int16

#define BYTE unsigned __int8

#define BOOL __int32

#define LOWORD(l) ((WORD)(l))

#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))

#define LOBYTE(w) ((BYTE)(w))

#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))

#define MAKELONG(a, b) ((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))

#define SYSTEMCALL 0x2e

#define SYSNAME "System"

#define PROCESSNAMELEN 16

#pragma pack(1)

//定义 IDTR

typedef struct tagIDTR {

WORD IDTLimit;

WORD LowIDTbase;

WORD HiIDTbase;

}IDTR, *PIDTR;

//定义 IDT

typedef struct tagIDTENTRY{

WORD OffsetLow;

WORD selector;

BYTE unused_lo;

unsigned char unused_hi:5;

unsigned char DPL:2;

unsigned char P:1;

WORD OffsetHigh;

} IDTENTRY, *PIDTENTRY;

#pragma pack()

DWORD OldInt2eService;

ULONG ProcessNameOffset;

TCHAR ProcessName[PROCESSNAMELEN];

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);

ULONG GetProcessNameOffset();

VOID GetProcessName( PCHAR Name );

VOID InstallNewInt2e();

VOID UninstallNewInt2e();

VOID __fastcall NativeApiCall()

{

KIRQL OldIrql;

DWORD ServiceID;

DWORD ProcessId;

__asm mov ServiceID,eax;

ProcessId = (DWORD)PsGetCurrentProcessId();

GetProcessName(ProcessName);

KeRaiseIrql(HIGH_LEVEL, &OldIrql); // 提升当前的 IRQL 级别防止被中断

switch ( ServiceID )

{

case 0x20:

DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateFil e() \n",ProcessName,ProcessId);

break;

case 0x2b:

DbgPrint("NEWINT2E: ProcessName: %s; ProcessID: %d; Native Api: NtCreateSec

相关文档
最新文档