|
|
内核级HOOK的几种实现与应用 |
|
|
作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站 |
转自安焦 ????实现内核级 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: 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 < IRP_MJ_MAXIMUM_FUNCTION; 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 < 3*PAGE_SIZE; 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 < uCount; 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 < (UINT)pNtHdr->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 < (UINT)pExtDir->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 < IRP_MJ_MAXIMUM_FUNCTION; 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; ??};
}

|
|
相关文章:相关软件: |
|