TA的每日心情 | 开心 2024-12-9 18:45 |
---|
签到天数: 124 天 [LV.7]常住居民III
|
欢迎您注册加入!这里有您将更精采!
您需要 登录 才可以下载或查看,没有账号?注册
x
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;
- };
- }
复制代码 |
|