分享
 
 
 

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

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

转自安焦

????实现内核级 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)))

#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: NtCreateFile() \n",ProcessName,ProcessId);

???????????????? break;

????????????case 0x2b:

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

???????????????? break;

????????????case 0x30:

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

???????????????? break;

????????????????

????}

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

}

__declspec(naked) NewInt2eService()

{

????__asm{

????????pushad

????????pushfd

????????push fs

????????mov bx,0x30

????????mov fs,bx

????????push ds

????????push es

????????sti

????????call NativeApiCall; // 调用记录函数

????????cli

????????pop es

????????pop ds

????????pop fs

????????popfd

????????popad

????????jmp????OldInt2eService;??//跳到原始 INT 2E 继续工作

????}

}

VOID InstallNewInt2e()

{

????IDTR???????? idtr;

????PIDTENTRY????OIdt;

????PIDTENTRY????NIdt;

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

????__asm {

????????sidt idtr;

????}

????//得到IDT基地址

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

????//保存原来的 INT 2E 服务例程

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

????

????NIdt = &(OIdt[SYSTEMCALL]);

????__asm {

????????cli

????????lea eax,NewInt2eService;??//得到新的 INT 2E 服务例程偏移

????????mov ebx, NIdt;

????????mov [ebx],ax;?? //INT 2E 服务例程低 16 位

????????shr eax,16??????//INT 2E 服务例程高 16 位

????????mov [ebx+6],ax;

????????lidt idtr??//装入新的 IDT

????????sti

????}

}

VOID UninstallNewInt2e()

{

????IDTR???????? idtr;

????PIDTENTRY????OIdt;

????PIDTENTRY????NIdt;

????__asm {

????????sidt idtr;

????}

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

????NIdt = &(OIdt[SYSTEMCALL]);

????_asm {

????????cli

????????lea eax,OldInt2eService;

????????mov ebx, NIdt;

????????mov [ebx],ax;

????????shr eax,16

????????mov [ebx+6],ax;

????????lidt idtr

????????sti

????}

}

// 驱动入口

NTSTATUS??DriverEntry( IN PDRIVER_OBJECT DriverObject,??IN PUNICODE_STRING RegistryPath )

{

????

????UNICODE_STRING??nameString, linkString;

????PDEVICE_OBJECT??deviceObject;

????NTSTATUS????????status;

????HANDLE??????????hHandle;

????int????????????????i;

????

????//卸载驱动

????DriverObject-DriverUnload = DriverUnload;

????//建立设备

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

????

????status = IoCreateDevice( DriverObject,

???????????????????????????? 0,

???????????????????????????? &nameString,

???????????????????????????? FILE_DEVICE_UNKNOWN,

???????????????????????????? 0,

???????????????????????????? TRUE,

???????????????????????????? &deviceObject

?????????????????????????? );

??????????????????????????

????if (!NT_SUCCESS( status ))

????????return status;

????

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

????status = IoCreateSymbolicLink (&linkString, &nameString);

????if (!NT_SUCCESS( status ))

????{

????????IoDeleteDevice (DriverObject-DeviceObject);

????????return status;

????}????

????

????for ( i = 0; i

??????????DriverObject-MajorFunction[i] = MydrvDispatch;

????}

??????DriverObject-DriverUnload = DriverUnload;

????ProcessNameOffset = GetProcessNameOffset();

????InstallNewInt2e();

??return STATUS_SUCCESS;

}

//处理设备对象操作

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

????Irp-IoStatus.Status = STATUS_SUCCESS;

????Irp-IoStatus.Information = 0L;

????IoCompleteRequest( Irp, 0 );

????return Irp-IoStatus.Status;

????

}

VOID DriverUnload (IN PDRIVER_OBJECT????pDriverObject)

{

????UNICODE_STRING??nameString;

????UninstallNewInt2e();

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

????IoDeleteSymbolicLink(&nameString);

????IoDeleteDevice(pDriverObject-DeviceObject);

????return;

}

ULONG GetProcessNameOffset()

{

????????PEPROCESS curproc;

????????int i;

????????

????????curproc = PsGetCurrentProcess();

????????//

????????// Scan for 12KB, hopping the KPEB never grows that big!

????????//

????????for( i = 0; i

????????????if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {

????????????????return i;

????????????}

????????}

????????//

????????// Name not found - oh, well

????????//

????????return 0;

}

VOID GetProcessName( PCHAR Name )

{

????????PEPROCESS curproc;

????????char *nameptr;

????????ULONG i;

????????if( ProcessNameOffset ) {

????????????curproc = PsGetCurrentProcess();

????????????nameptr = (PCHAR) curproc + ProcessNameOffset;

????????????strncpy( Name, nameptr, 16 );

????????} else {

????????????strcpy( Name, "???");

????????}

}

3、 HOOK PE 方法

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

是根据替换 PE 格式导出表中的相应函数来实现的。此方法中需要用到一些小

技巧。如内核模式并没有直接提供类似应用层的 GetModuleHandl()、GetProcAddress() 等函数来获得模块的地址。那么我们就需要自己来编写,这

里用到了一个未公开的函数与结构。ZwQuerySystemInformation 与 SYSTEM_MODULE_INFORMATION 来实现得到模块的基地址。这样我们就可以根据

PE 格式来枚举导出表中的函数来替换了。但这又引出了一个问题,那就是从

WINDOWS 2000 后内核数据的页属性都是只读的,不能更改。内核模式也没有

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

我们自己来编写。因为我们是在内核模式所以我们可以通过修改 cr0 寄存器的

的写保护位来达到我们的目的。这样我们所期望的拦截内核模式函数的功能便

得以实现。此方法需要你对 PE 格式有一定的基础。下面的程序演示了这一过程。

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

文件名????????: WssHookPE.c

描述??????????: 拦截内核函数

作者??????????: sinister

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

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

#include "ntddk.h"

#include "windef.h"

typedef enum _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;

typedef struct tagSYSTEM_MODULE_INFORMATION {

????ULONG Reserved[2];

????PVOID Base;

????ULONG Size;

????ULONG Flags;

????USHORT Index;

????USHORT Unknown;

????USHORT LoadCount;

????USHORT ModuleNameOffset;

????CHAR ImageName[256];

} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

#define IMAGE_DOS_SIGNATURE????????0x5A4D??????// MZ

#define IMAGE_NT_SIGNATURE??????0x50450000??// PE00

#define IMAGE_NT_SIGNATURE1????????0x00004550????// 00EP

typedef struct _IMAGE_DOS_HEADER {??????// DOS .EXE header

????WORD?? e_magic;???????????????????? // Magic number

????WORD?? e_cblp;??????????????????????// Bytes on last page of file

????WORD?? e_cp;????????????????????????// Pages in file

????WORD?? e_crlc;??????????????????????// Relocations

????WORD?? e_cparhdr;?????????????????? // Size of header in paragraphs

????WORD?? e_minalloc;??????????????????// Minimum extra paragraphs needed

????WORD?? e_maxalloc;??????????????????// Maximum extra paragraphs needed

????WORD?? e_ss;????????????????????????// Initial (relative) SS value

????WORD?? e_sp;????????????????????????// Initial SP value

????WORD?? e_csum;??????????????????????// Checksum

????WORD?? e_ip;????????????????????????// Initial IP value

????WORD?? e_cs;????????????????????????// Initial (relative) CS value

????WORD?? e_lfarlc;????????????????????// File address of relocation table

????WORD?? e_ovno;??????????????????????// Overlay number

????WORD?? e_res[4];????????????????????// Reserved words

????WORD?? e_oemid;???????????????????? // OEM identifier (for e_oeminfo)

????WORD?? e_oeminfo;?????????????????? // OEM information; e_oemid specific

????WORD?? e_res2[10];??????????????????// Reserved words

????LONG?? e_lfanew;????????????????????// File address of new exe header

??} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct _IMAGE_FILE_HEADER {

????WORD????Machine;

????WORD????NumberOfSections;

????DWORD?? TimeDateStamp;

????DWORD?? PointerToSymbolTable;

????DWORD?? NumberOfSymbols;

????WORD????SizeOfOptionalHeader;

????WORD????Characteristics;

} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {

????DWORD?? VirtualAddress;

????DWORD?? Size;

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES????16

//

// Optional header format.

//

typedef struct _IMAGE_OPTIONAL_HEADER {

????//

????// Standard fields.

????//

????WORD????Magic;

????BYTE????MajorLinkerVersion;

????BYTE????MinorLinkerVersion;

????DWORD?? SizeOfCode;

????DWORD?? SizeOfInitializedData;

????DWORD?? SizeOfUninitializedData;

????DWORD?? AddressOfEntryPoint;

????DWORD?? BaseOfCode;

????DWORD?? BaseOfData;

????//

????// NT additional fields.

????//

????DWORD?? ImageBase;

????DWORD?? SectionAlignment;

????DWORD?? FileAlignment;

????WORD????MajorOperatingSystemVersion;

????WORD????MinorOperatingSystemVersion;

????WORD????MajorImageVersion;

????WORD????MinorImageVersion;

????WORD????MajorSubsystemVersion;

????WORD????MinorSubsystemVersion;

????DWORD?? Win32VersionValue;

????DWORD?? SizeOfImage;

????DWORD?? SizeOfHeaders;

????DWORD?? CheckSum;

????WORD????Subsystem;

????WORD????DllCharacteristics;

????DWORD?? SizeOfStackReserve;

????DWORD?? SizeOfStackCommit;

????DWORD?? SizeOfHeapReserve;

????DWORD?? SizeOfHeapCommit;

????DWORD?? LoaderFlags;

????DWORD?? NumberOfRvaAndSizes;

????IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_NT_HEADERS {

????DWORD Signature;

????IMAGE_FILE_HEADER FileHeader;

????IMAGE_OPTIONAL_HEADER32 OptionalHeader;

} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef IMAGE_NT_HEADERS32??????????????????IMAGE_NT_HEADERS;

typedef PIMAGE_NT_HEADERS32???????????????? PIMAGE_NT_HEADERS;

//

// Section header format.

//

#define IMAGE_SIZEOF_SHORT_NAME??????????????8

typedef struct _IMAGE_SECTION_HEADER {

????BYTE????Name[IMAGE_SIZEOF_SHORT_NAME];

????union {

????????????DWORD?? PhysicalAddress;

????????????DWORD?? VirtualSize;

????} Misc;

????DWORD?? VirtualAddress;

????DWORD?? SizeOfRawData;

????DWORD?? PointerToRawData;

????DWORD?? PointerToRelocations;

????DWORD?? PointerToLinenumbers;

????WORD????NumberOfRelocations;

????WORD????NumberOfLinenumbers;

????DWORD?? Characteristics;

} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

#define IMAGE_SIZEOF_SECTION_HEADER??????????40

//

// Export Format

//

typedef struct _IMAGE_EXPORT_DIRECTORY {

????DWORD?? Characteristics;

????DWORD?? TimeDateStamp;

????WORD????MajorVersion;

????WORD????MinorVersion;

????DWORD?? Name;

????DWORD?? Base;

????DWORD?? NumberOfFunctions;

????DWORD?? NumberOfNames;

????DWORD?? AddressOfFunctions;???? // RVA from base of image

????DWORD?? AddressOfNames;???????? // RVA from base of image

????DWORD?? AddressOfNameOrdinals;??// RVA from base of image

} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

#define BASEADDRLEN 10

NTSYSAPI

NTSTATUS

NTAPI

ZwQuerySystemInformation(

????IN SYSTEM_INFORMATION_CLASS SystemInformationClass,

????IN OUT PVOID SystemInformation,

????IN ULONG SystemInformationLength,

????OUT PULONG ReturnLength OPTIONAL

????);

typedef NTSTATUS (* ZWCREATEFILE)(

??OUT PHANDLE FileHandle,

??IN ACCESS_MASK DesiredAccess,

??IN POBJECT_ATTRIBUTES ObjectAttributes,

??OUT PIO_STATUS_BLOCK IoStatusBlock,

??IN PLARGE_INTEGER AllocationSize??OPTIONAL,

??IN ULONG FileAttributes,

??IN ULONG ShareAccess,

??IN ULONG CreateDisposition,

??IN ULONG CreateOptions,

??IN PVOID EaBuffer??OPTIONAL,

??IN ULONG EaLength

??);

ZWCREATEFILE????OldZwCreateFile;

static NTSTATUS??MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);

VOID DisableWriteProtect( PULONG pOldAttr);

VOID EnableWriteProtect( ULONG ulOldAttr );

FARPROC HookFunction(????PCHAR pModuleBase, PCHAR pHookName, FARPROC pHookFunc );

NTSTATUS??

HookNtCreateFile(

??OUT PHANDLE FileHandle,

??IN ACCESS_MASK DesiredAccess,

??IN POBJECT_ATTRIBUTES ObjectAttributes,

??OUT PIO_STATUS_BLOCK IoStatusBlock,

??IN PLARGE_INTEGER AllocationSize??OPTIONAL,

??IN ULONG FileAttributes,

??IN ULONG ShareAccess,

??IN ULONG CreateDisposition,

??IN ULONG CreateOptions,

??IN PVOID EaBuffer??OPTIONAL,

??IN ULONG EaLength

??);

PCHAR MyGetModuleBaseAddress( PCHAR pModuleName )

{

????PSYSTEM_MODULE_INFORMATION????pSysModule;????

????ULONG????????????uReturn;

????ULONG????????????uCount;

????PCHAR????????????pBuffer = NULL;

????PCHAR????????????pName????= NULL;

????NTSTATUS????????status;

????UINT????????????ui;

????CHAR????????????szBuffer[BASEADDRLEN];

????PCHAR????????????pBaseAddress;

????

????status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );

????pBuffer = ( PCHAR )ExAllocatePool( NonPagedPool, uReturn );

????if ( pBuffer )

????{

????????status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );

????????if( status == STATUS_SUCCESS )

????????{

????????????uCount = ( ULONG )*( ( ULONG * )pBuffer );

????????????pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );

????????????for ( ui = 0; ui

????????????{

????????????????pName = MyStrchr( pSysModule-ImageName, '\\' );

????????????????if ( !pName )

????????????????{

????????????????????pName = pSysModule-ImageName;

????????????????}

????????????????else {

????????????????????pName++;

????????????????}

????????????????if( !_stricmp( pName, pModuleName ) )

????????????????{

????????????????????pBaseAddress = ( PCHAR )pSysModule-Base;

????????????????????ExFreePool( pBuffer );

????????????????????return pBaseAddress;

????????????????}

????????????????pSysModule ++;

????????????}

????????}

????????ExFreePool( pBuffer );

????}

????return NULL;

}

FARPROC HookFunction( PCHAR pModuleBase, PCHAR HookFunName, FARPROC HookFun )

{

????PIMAGE_DOS_HEADER???????? pDosHdr;

????PIMAGE_NT_HEADERS???????? pNtHdr;

????PIMAGE_SECTION_HEADER???? pSecHdr;

????PIMAGE_EXPORT_DIRECTORY??pExtDir;

????UINT????????????????????ui,uj;

????PCHAR????????????????????FunName;

????DWORD????????????????????*dwAddrName;

????DWORD????????????????????*dwAddrFun;

????FARPROC????????????????????pOldFun;

????ULONG????????????????????uAttrib;

????pDosHdr = ( PIMAGE_DOS_HEADER )pModuleBase;

????if ( IMAGE_DOS_SIGNATURE == pDosHdr-e_magic )

????{

????????pNtHdr = ( PIMAGE_NT_HEADERS )( pModuleBase + pDosHdr-e_lfanew );

????????if( IMAGE_NT_SIGNATURE??== pNtHdr-Signature ||????IMAGE_NT_SIGNATURE1 == pNtHdr-Signature )

????????{

????????????pSecHdr = ( PIMAGE_SECTION_HEADER )( pModuleBase + pDosHdr-e_lfanew + sizeof( IMAGE_NT_HEADERS ) );

????????????for ( ui = 0; ui FileHeader.NumberOfSections; ui++ )

????????????{

????????????????if ( !strcmp( pSecHdr-Name, ".edata" ) )

????????????????{????????????????

????????????????????pExtDir = ( PIMAGE_EXPORT_DIRECTORY )( pModuleBase + pSecHdr-VirtualAddress );

????????????????????dwAddrName = ( PDWORD )(pModuleBase + pExtDir-AddressOfNames );

????????????????????dwAddrFun = ( PDWORD )(pModuleBase + pExtDir-AddressOfFunctions );

????????????????????for ( uj = 0; uj NumberOfFunctions; uj++ )

????????????????????{

????????????????????????FunName = pModuleBase + *dwAddrName;

????????????????????????if( !strcmp( FunName, HookFunName ) )

????????????????????????{

????????????????????????????DbgPrint(" HOOK??%s()\n",FunName);

????????????????????????????DisableWriteProtect( &uAttrib );

????????????????????????????pOldFun = ( FARPROC )( pModuleBase + *dwAddrFun );

????????????????????????????*dwAddrFun = ( PCHAR )HookFun - pModuleBase;

????????????????????????????EnableWriteProtect( uAttrib );

????????????????????????????return pOldFun;

????????????????????????}

??????????????????????dwAddrName ++;

??????????????????????dwAddrFun ++;

????????????????????}

????????????????}

????????????????pSecHdr++;

????????????}

????????}

????}

????return NULL;

}

// 驱动入口

NTSTATUS??DriverEntry( IN PDRIVER_OBJECT DriverObject,??IN PUNICODE_STRING RegistryPath )

{

????

????UNICODE_STRING??nameString, linkString;

????PDEVICE_OBJECT??deviceObject;

????NTSTATUS????????status;

????HANDLE??????????hHandle;

????PCHAR????????????pModuleAddress;

????int????????????????i;

????

????//卸载驱动

????DriverObject-DriverUnload = DriverUnload;

????//建立设备

????RtlInitUnicodeString( &nameString, L"\\Device\\WssHookPE" );

????

????status = IoCreateDevice( DriverObject,

???????????????????????????? 0,

???????????????????????????? &nameString,

???????????????????????????? FILE_DEVICE_UNKNOWN,

???????????????????????????? 0,

???????????????????????????? TRUE,

???????????????????????????? &deviceObject

?????????????????????????? );

??????????????????????????

????if (!NT_SUCCESS( status ))

????????return status;

????

????RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssHookPE" );

????status = IoCreateSymbolicLink (&linkString, &nameString);

????if (!NT_SUCCESS( status ))

????{

????????IoDeleteDevice (DriverObject-DeviceObject);

????????return status;

????}????

????

????pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");

????if ( pModuleAddress == NULL)

????{

????????DbgPrint(" MyGetModuleBaseAddress()\n");

????????return 0;

????}

????OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)HookNtCreateFile);

????if ( OldZwCreateFile == NULL)

????{

????????DbgPrint(" HOOK FAILED\n");

????????return 0;

????}

????DbgPrint("HOOK SUCCEED\n");

????for ( i = 0; i

??????????DriverObject-MajorFunction[i] = MydrvDispatch;

????}

??????DriverObject-DriverUnload = DriverUnload;

????

??return STATUS_SUCCESS;

}

//处理设备对象操作

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

????Irp-IoStatus.Status = STATUS_SUCCESS;

????Irp-IoStatus.Information = 0L;

????IoCompleteRequest( Irp, 0 );

????return Irp-IoStatus.Status;

????

}

VOID DriverUnload (IN PDRIVER_OBJECT????pDriverObject)

{

????UNICODE_STRING??nameString;

????PCHAR????????????pModuleAddress;

????pModuleAddress = MyGetModuleBaseAddress("ntoskrnl.exe");

????if ( pModuleAddress == NULL)

????{

????????DbgPrint("MyGetModuleBaseAddress()\n");

????????return ;

????}

????OldZwCreateFile = (ZWCREATEFILE)HookFunction( pModuleAddress, "ZwCreateFile",(ZWCREATEFILE)OldZwCreateFile);

????if ( OldZwCreateFile == NULL)

????{

????????DbgPrint(" UNHOOK FAILED!\n");

????????return ;

????}

????DbgPrint("UNHOOK SUCCEED\n");

????RtlInitUnicodeString( &nameString, L"\\DosDevices\\WssHookPE" );????

????IoDeleteSymbolicLink(&nameString);

????IoDeleteDevice(pDriverObject-DeviceObject);

????return;

}

NTSTATUS??

HookNtCreateFile(

??OUT PHANDLE FileHandle,

??IN ACCESS_MASK DesiredAccess,

??IN POBJECT_ATTRIBUTES ObjectAttributes,

??OUT PIO_STATUS_BLOCK IoStatusBlock,

??IN PLARGE_INTEGER AllocationSize??OPTIONAL,

??IN ULONG FileAttributes,

??IN ULONG ShareAccess,

??IN ULONG CreateDisposition,

??IN ULONG CreateOptions,

??IN PVOID EaBuffer??OPTIONAL,

??IN ULONG EaLength

??)

{

????NTSTATUS????status;

????DbgPrint("Hook ZwCreateFile()\n");

????status = ((ZWCREATEFILE)(OldZwCreateFile))(

?????????????? FileHandle,

?????????????? DesiredAccess,

?????????????? ObjectAttributes,

?????????????? IoStatusBlock,

?????????????? AllocationSize,

?????????????? FileAttributes,

?????????????? ShareAccess,

?????????????? CreateDisposition,

?????????????? CreateOptions,

?????????????? EaBuffer,

?????????????? EaLength

??????????????);

????return status;

}

VOID DisableWriteProtect( PULONG pOldAttr)

{

???? ULONG uAttr;

???? _asm

????{

??????????push eax;

??????????mov??eax, cr0;

??????????mov??uAttr, eax;

??????????and??eax, 0FFFEFFFFh; // CR0 16 BIT = 0

??????????mov??cr0, eax;

??????????pop??eax;

????};

???? *pOldAttr = uAttr; //保存原有的 CRO 属性

}

VOID EnableWriteProtect( ULONG uOldAttr )

{

??_asm

??{

?????? push eax;

?????? mov??eax, uOldAttr; //恢复原有 CR0 属性

?????? mov??cr0, eax;

?????? pop??eax;

??};

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有