软件工程内核级HOOK的几种实现与应用.docx

上传人:b****5 文档编号:11848803 上传时间:2023-04-06 格式:DOCX 页数:36 大小:26.55KB
下载 相关 举报
软件工程内核级HOOK的几种实现与应用.docx_第1页
第1页 / 共36页
软件工程内核级HOOK的几种实现与应用.docx_第2页
第2页 / 共36页
软件工程内核级HOOK的几种实现与应用.docx_第3页
第3页 / 共36页
软件工程内核级HOOK的几种实现与应用.docx_第4页
第4页 / 共36页
软件工程内核级HOOK的几种实现与应用.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

软件工程内核级HOOK的几种实现与应用.docx

《软件工程内核级HOOK的几种实现与应用.docx》由会员分享,可在线阅读,更多相关《软件工程内核级HOOK的几种实现与应用.docx(36页珍藏版)》请在冰豆网上搜索。

软件工程内核级HOOK的几种实现与应用.docx

软件工程内核级HOOK的几种实现与应用

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

实现内核级HOOK对于拦截、分析、跟踪系统内核起着致关重要的作用。

实现的方法不同意味着应用侧重点的不同。

如想要拦截NATIVEAPI那么可能常用的就是HOOKSERVICETABLE的方法。

如果要分析一些系统调用,那么可能想到用HOOKINT2E中断来实现。

如果想要拦截或跟踪其他内核DRIVER的调用,那么就要用到HOOKPE的方法来实现。

这里我们更注重的是实现,原理方面已有不少高手在网上发表过文章。

大家可以结合起来读。

下面以我写的几个实例程序来讲解一下各种方法的实现。

错误之处还望各位指正。

 

1、HOOKSERVICETABLE方法:

这种方法对于拦截NATIVEAPI来说用的比较多。

原理就是通过替换系统导

出的一个SERVICETABLE中相应的NATIVEAPI的地址来达到拦截的目的。

因为此方法较为简单,网上也有不少资料来介绍。

所以这里就不给出实例程序了。

SERVICETABLE的结构如下:

typedefstructServiceDescriptorEntry{

unsignedint*ServiceTableBase;

unsignedint*ServiceCounterTableBase;

unsignedintNumberOfServices;

unsignedchar*ParamTableBase;

}ServiceDescriptorTableEntry_t,*PServiceDescriptorTableEntry_t;

2、HOOKINT2E方法:

这种方法对于跟踪、分析系统调用来说用的比较多。

原理是通过替换IDT

表中的INT2E中断,使之指向我们自己的中断服务处理例程来实现的。

掌握

此方法需要你对保护模式有一定的基础。

下面的程序演示了这一过程。

 

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

文件名:

WssHookInt2e.c

描述:

系统调用跟踪

作者:

sinister

最后修改日期:

2002-11-02

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

#include"ntddk.h"

#include"string.h"

#defineDWORDunsigned__int32

#defineWORDunsigned__int16

#defineBYTEunsigned__int8

#defineBOOL__int32

#defineLOWORD(l)((WORD)(l))

#defineHIWORD(l)((WORD)(((DWORD)(l)>>16)&0xFFFF))

#defineLOBYTE(w)((BYTE)(w))

#defineHIBYTE(w)((BYTE)(((WORD)(w)>>8)&0xFF))

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

#defineSYSTEMCALL0x2e

#defineSYSNAME"System"

#definePROCESSNAMELEN16

#pragmapack

(1)

//定义IDTR

typedefstructtagIDTR{

WORDIDTLimit;

WORDLowIDTbase;

WORDHiIDTbase;

}IDTR,*PIDTR;

//定义IDT

typedefstructtagIDTENTRY{

WORDOffsetLow;

WORDselector;

BYTEunused_lo;

unsignedcharunused_hi:

5;

unsignedcharDPL:

2;

unsignedcharP:

1;

WORDOffsetHigh;

}IDTENTRY,*PIDTENTRY;

 

#pragmapack()

DWORDOldInt2eService;

ULONGProcessNameOffset;

TCHARProcessName[PROCESSNAMELEN];

staticNTSTATUSMydrvDispatch(INPDEVICE_OBJECTDeviceObject,INPIRPIrp);

VOIDDriverUnload(INPDRIVER_OBJECTpDriverObject);

ULONGGetProcessNameOffset();

VOIDGetProcessName(PCHARName);

VOIDInstallNewInt2e();

VOIDUninstallNewInt2e();

VOID__fastcallNativeApiCall()

{

KIRQLOldIrql;

DWORDServiceID;

DWORDProcessId;

__asmmovServiceID,eax;

 

ProcessId=(DWORD)PsGetCurrentProcessId();

GetProcessName(ProcessName);

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

 

switch(ServiceID)

{

case0x20:

DbgPrint("NEWINT2E:

ProcessName:

%s;ProcessID:

%d;NativeApi:

NtCreateFile()\n",ProcessName,ProcessId);

break;

case0x2b:

DbgPrint("NEWINT2E:

ProcessName:

%s;ProcessID:

%d;NativeApi:

NtCreateSection()\n",ProcessName,ProcessId);

break;

 

case0x30:

DbgPrint("NEWINT2E:

ProcessName:

%s;ProcessID:

%d;NativeApi:

NtCreateToken()\n",ProcessName,ProcessId);

break;

}

KeLowerIrql(OldIrql);//恢复原始IRQL

}

__declspec(naked)NewInt2eService()

{

__asm{

pushad

pushfd

pushfs

movbx,0x30

movfs,bx

pushds

pushes

sti

callNativeApiCall;//调用记录函数

cli

popes

popds

popfs

popfd

popad

jmpOldInt2eService;//跳到原始INT2E继续工作

}

}

VOIDInstallNewInt2e()

{

IDTRidtr;

PIDTENTRYOIdt;

PIDTENTRYNIdt;

//得到IDTR中得段界限与基地址

__asm{

sidtidtr;

}

//得到IDT基地址

OIdt=(PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase);

//保存原来的INT2E服务例程

OldInt2eService=MAKELONG(OIdt[SYSTEMCALL].OffsetLow,OIdt[SYSTEMCALL].OffsetHigh);

NIdt=&(OIdt[SYSTEMCALL]);

__asm{

cli

leaeax,NewInt2eService;//得到新的INT2E服务例程偏移

movebx,NIdt;

mov[ebx],ax;//INT2E服务例程低16位

shreax,16//INT2E服务例程高16位

mov[ebx+6],ax;

lidtidtr//装入新的IDT

sti

}

}

VOIDUninstallNewInt2e()

{

IDTRidtr;

PIDTENTRYOIdt;

PIDTENTRYNIdt;

__asm{

sidtidtr;

}

OIdt=(PIDTENTRY)MAKELONG(idtr.LowIDTbase,idtr.HiIDTbase);

NIdt=&(OIdt[SYSTEMCALL]);

_asm{

cli

leaeax,OldInt2eService;

movebx,NIdt;

mov[ebx],ax;

shreax,16

mov[ebx+6],ax;

lidtidtr

sti

}

}

 

//驱动入口

NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath)

{

UNICODE_STRINGnameString,linkString;

PDEVICE_OBJECTdeviceObject;

NTSTATUSstatus;

HANDLEhHandle;

inti;

//卸载驱动

DriverObject->DriverUnload=DriverUnload;

//建立设备

RtlInitUnicodeString(&nameString,L"\\Device\\WssHookInt2e");

status=IoCreateDevice(DriverObject,

0,

&nameString,

FILE_DEVICE_UNKNOWN,

0,

TRUE,

&deviceObject

);

if(!

NT_SUCCESS(status))

returnstatus;

RtlInitUnicodeString(&linkString,L"\\DosDevices\\WssHookInt2e");

status=IoCreateSymbolicLink(&linkString,&nameString);

if(!

NT_SUCCESS(status))

{

IoDeleteDevice(DriverObject->DeviceObject);

returnstatus;

}

for(i=0;i

DriverObject->MajorFunction[i]=MydrvDispatch;

}

DriverObject->DriverUnload=DriverUnload;

ProcessNameOffset=GetProcessNameOffset();

InstallNewInt2e();

returnSTATUS_SUCCESS;

}

 

//处理设备对象操作

staticNTSTATUSMydrvDispatch(INPDEVICE_OBJECTDeviceObject,INPIRPIrp)

{

Irp->IoStatus.Status=STATUS_SUCCESS;

Irp->IoStatus.Information=0L;

IoCompleteRequest(Irp,0);

returnIrp->IoStatus.Status;

}

 

VOIDDriverUnload(INPDRIVER_OBJECTpDriverObject)

{

UNICODE_STRINGnameString;

UninstallNewInt2e();

RtlInitUnicodeString(&nameString,L"\\DosDevices\\WssHookInt2e");

IoDeleteSymbolicLink(&nameString);

IoDeleteDevice(pDriverObject->DeviceObject);

return;

}

 

ULONGGetProcessNameOffset()

{

PEPROCESScurproc;

inti;

curproc=PsGetCurrentProcess();

//

//Scanfor12KB,hoppingtheKPEBnevergrowsthatbig!

//

for(i=0;i<3*PAGE_SIZE;i++){

if(!

strncmp(SYSNAME,(PCHAR)curproc+i,strlen(SYSNAME))){

returni;

}

}

//

//Namenotfound-oh,well

//

return0;

}

VOIDGetProcessName(PCHARName)

{

PEPROCESScurproc;

char*nameptr;

ULONGi;

if(ProcessNameOffset){

curproc=PsGetCurrentProcess();

nameptr=(PCHAR)curproc+ProcessNameOffset;

strncpy(Name,nameptr,16);

}else{

strcpy(Name,"?

?

?

");

}

}

 

3、HOOKPE方法

这种方法对于拦截、分析其他内核驱动的函数调用来说用的比较多。

原理

是根据替换PE格式导出表中的相应函数来实现的。

此方法中需要用到一些小

技巧。

如内核模式并没有直接提供类似应用层的GetModuleHandl()、GetProcAddress()等函数来获得模块的地址。

那么我们就需要自己来编写,这

里用到了一个未公开的函数与结构。

ZwQuerySystemInformation与SYSTEM_MODULE_INFORMATION来实现得到模块的基地址。

这样我们就可以根据

PE格式来枚举导出表中的函数来替换了。

但这又引出了一个问题,那就是从

WINDOWS2000后内核数据的页属性都是只读的,不能更改。

内核模式也没有

提供类似应用层的VirtualProtectEx()等函数来修改页面属性。

那么也需要

我们自己来编写。

因为我们是在内核模式所以我们可以通过修改cr0寄存器的

的写保护位来达到我们的目的。

这样我们所期望的拦截内核模式函数的功能便

得以实现。

此方法需要你对PE格式有一定的基础。

下面的程序演示了这一过程。

 

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

文件名:

WssHookPE.c

描述:

拦截内核函数

作者:

sinister

最后修改日期:

2002-11-02

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

#include"ntddk.h"

#include"windef.h"

 

typedefenum_SYSTEM_INFORMATION_CLASS{

SystemBasicInformation,

SystemProcessorInformation,

SystemPerformanceInformation,

SystemTimeOfDayInformation,

SystemNotImplemented1,

SystemProcessesAndThreadsInformation,

SystemCallCounts,

SystemConfigurationInformation,

SystemProcessorTimes,

SystemGlobalFlag,

SystemNotImplemented2,

SystemModuleInformation,

SystemLockInformation,

SystemNotImplemented3,

SystemNotImplemented4,

SystemNotImplemented5,

SystemHandleInformation,

SystemObjectInformation,

SystemPagefileInformation,

SystemInstructionEmulationCounts,

SystemInvalidInfoClass1,

SystemCacheInformation,

SystemPoolTagInformation,

SystemProcessorStatistics,

SystemDpcInformation,

SystemNotImplemented6,

SystemLoadImage,

SystemUnloadImage,

SystemTimeAdjustment,

SystemNotImplemented7,

SystemNotImplemented8,

SystemNotImplemented9,

SystemCrashDumpInformation,

SystemExceptionInformation,

SystemCrashDumpStateInformation,

SystemKernelDebuggerInformation,

SystemContextSwitchInformation,

SystemRegistryQuotaInformation,

SystemLoadAndCallImage,

SystemPrioritySeparation,

SystemNotImplemented10,

SystemNotImplemented11,

SystemInvalidInfoClass2,

SystemInvalidInfoClass3,

SystemTimeZoneInformation,

SystemLookasideInformation,

SystemSetTimeSlipEvent,

SystemCreateSession,

SystemDeleteSession,

SystemInvalidInfoClass4,

SystemRangeStartInformation,

SystemVerifierInformation,

SystemAddVerifier,

SystemSessionProcessesInformation

}SYSTEM_INFORMATION_CLASS;

 

typedefstructtagSYSTEM_MODULE_INFORMATION{

ULONGReserved[2];

PVOIDBase;

ULONGSize;

ULONGFlags;

USHORTIndex;

USHORTUnknown;

USHORTLoadCount;

USHORTModuleNameOffset;

CHARImageName[256];

}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;

#defineIMAGE_DOS_SIGNATURE0x5A4D//MZ

#defineIMAGE_NT_SIGNATURE0x50450000//PE00

#defineIMAGE_NT_SIGNATURE10x00004550//00EP

typedefstruct_IMAGE_DOS_HEADER{//DOS.EXEheader

WORDe_magic;//Magicnumber

WORDe_cblp;//Bytesonlastpageoffile

WORDe_cp;//Pagesinfile

WORDe_crlc;//Relocations

WORDe_cparhdr;//Sizeofheaderinparagraphs

WORDe_minalloc;//Minimumextraparagraphsneeded

WORDe_maxalloc;//Maximumextraparagraphsneeded

WORDe_ss;//Initial(relative)SSvalue

WORDe_sp;//InitialSPvalue

WORDe_csum;//Checksum

WORDe_ip;//InitialIPvalue

WORDe_cs;//Initial(relative)CSvalue

WORDe_lfarlc;//Fileaddressofrelocationtable

WORDe_ovno;//Overlaynumber

WORDe_res[4];//Reservedwords

WORDe_oemid;//OEMidentifier(fore_oeminfo)

WORDe_oeminfo;//OEMinformation;e_oemidspecific

WORDe_res2[10];//Reservedwords

LONGe_lfanew;//Fileaddressofnewexeheader

}IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;

 

typedefstruct_IMAGE_FILE_HEADER{

WORDMachine;

WORDNumberOfSections;

DWORDTimeDateSta

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1