win0環異常處理與Object-Hook
阿新 • • 發佈:2018-06-22
loading reac wpa nts procedure address create eric sep 0環下沒有veh
有seh
有seh
#include <ntifs.h> VOID DriverUnload(PDRIVER_OBJECT pDriver); NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath) { UNREFERENCED_PARAMETER(pPath); DbgBreakPoint(); __try { int *p = 0; *p = 100; } except(1) { KdPrint(("哈哈:掠過了一個異常")); } pDriver->DriverUnload = DriverUnload; return STATUS_SUCCESS; } VOID DriverUnload(PDRIVER_OBJECT pDriver) { UNREFERENCED_PARAMETER(pDriver); }
Object-Hook
條件是要自己聲名相關結構(用的windbg查看)
問題是函數與平臺相關
例:
win32下
#include <ntifs.h> VOID DriverUnload(PDRIVER_OBJECT objDriver); typedef ULONG(*OBGETOBJECTTYPE)(PVOID Object); typedef NTSTATUS(*PARSEPRODECEDURE)(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object); PARSEPRODECEDURE g_OldFun; NTSTATUS NewParseProcedure(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object) { KdPrint(("Hook Success\n")); return g_OldFun(ParseObject, ObjectType, AccessState, AccessMode, Attributes, CompleteName, RemainingName, Context, SecurityQos, Object); } OBGETOBJECTTYPE g_OBGetObjectType; //獲得一個函數地址,這個函數能夠通過內核對象得到內核對象的類型 VOID GetObjectTypeAddress() { PUCHAR addr; UNICODE_STRING pslookup; RtlInitUnicodeString(&pslookup, L"ObGetObjectType"); // 類似於應用層的GetProcAddress addr = (PUCHAR)MmGetSystemRoutineAddress(&pslookup); g_OBGetObjectType = (OBGETOBJECTTYPE)addr; } typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; UCHAR ObjectTypeFlags; UCHAR CaseInsensitive; UCHAR UnnamedObjectsOnly; UCHAR UseDefaultObject; UCHAR SecurityRequired; UCHAR MaintainHandleCount; UCHAR MaintainTypeList; UCHAR SupportsObjectCallbacks; UCHAR CacheAligned; ULONG ObjectTypeCode; BOOLEAN InvalidAttributes; GENERIC_MAPPING GenericMapping; BOOLEAN ValidAccessMask; BOOLEAN RetainAccess; POOL_TYPE PoolType; BOOLEAN DefaultPagedPoolCharge; BOOLEAN DefaultNonPagedPoolCharge; PVOID DumpProcedure; ULONG OpenProcedure; PVOID CloseProcedure; PVOID DeleteProcedure; ULONG ParseProcedure; ULONG SecurityProcedure; ULONG QueryNameProcedure; UCHAR OkayToCloseProcedure; } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; typedef struct _OBJECT_TYPE { LIST_ENTRY TypeList; UNICODE_STRING Name; PVOID DefaultObject; ULONG Index; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; OBJECT_TYPE_INITIALIZER TypeInfo; ULONG TypeLock; ULONG Key; LIST_ENTRY CallbackList; } OBJECT_TYPE, *POBJECT_TYPE; HANDLE KernelCreateFile( IN PUNICODE_STRING pstrFile, // 文件路徑符號鏈接 IN BOOLEAN bIsDir) // 是否為文件夾 { HANDLE hFile = NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL; IO_STATUS_BLOCK StatusBlock = { 0 }; ULONG ulShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; ULONG ulCreateOpt = FILE_SYNCHRONOUS_IO_NONALERT; // 1. 初始化OBJECT_ATTRIBUTES的內容 OBJECT_ATTRIBUTES objAttrib = { 0 }; ULONG ulAttributes = OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE; InitializeObjectAttributes( &objAttrib, // 返回初始化完畢的結構體 pstrFile, // 文件對象名稱 ulAttributes, // 對象屬性 NULL, NULL); // 一般為NULL // 2. 創建文件對象 ulCreateOpt |= bIsDir ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE; Status = ZwCreateFile( &hFile, // 返回文件句柄 GENERIC_ALL, // 文件操作描述 &objAttrib, // OBJECT_ATTRIBUTES &StatusBlock, // 接受函數的操作結果 0, // 初始文件大小 FILE_ATTRIBUTE_NORMAL, // 新建文件的屬性 ulShareAccess, // 文件共享方式 FILE_OPEN_IF, // 文件存在則打開不存在則創建 ulCreateOpt, // 打開操作的附加標誌位 NULL, // 擴展屬性區 0); // 擴展屬性區長度 if (!NT_SUCCESS(Status)) return (HANDLE)-1; return hFile; } void OnHook() { //1 隨便打開一個文件,得到一個文件對象 UNICODE_STRING ustrFilePath; RtlInitUnicodeString(&ustrFilePath, L"\\??\\D:\\123.txt"); HANDLE hFile = KernelCreateFile(&ustrFilePath, FALSE); PVOID pObject; ObReferenceObjectByHandle(hFile, GENERIC_ALL, NULL, KernelMode, &pObject, NULL); //2 通過這個文件對象得到OBJECT_TYPE這個結構體 OBJECT_TYPE * FileType = NULL; FileType = (OBJECT_TYPE *)g_OBGetObjectType(pObject); //3 把這個函數地址保存起來 g_OldFun = (PARSEPRODECEDURE)FileType->TypeInfo.ParseProcedure; //4 把這個函數地址替換為自己的函數。 FileType->TypeInfo.ParseProcedure = (ULONG)NewParseProcedure; } void OffHook() { } NTSTATUS DriverEntry( PDRIVER_OBJECT pDriver, PUNICODE_STRING strRegPath) { // 避免編譯器報未引用參數的警告 UNREFERENCED_PARAMETER(strRegPath); // 打印一行字符串,並註冊驅動卸載函數,以便於驅動卸載 DbgBreakPoint();//_asm int 3 __try { GetObjectTypeAddress(); OnHook(); } except(1) { KdPrint(("掠過一個異常\n")); } KdPrint(("My First Dirver!")); pDriver->DriverUnload = DriverUnload; return STATUS_SUCCESS; } VOID DriverUnload(PDRIVER_OBJECT objDriver) { // 避免編譯器報未引用參數的警告 UNREFERENCED_PARAMETER(objDriver); // 什麽也不做,只打印一行字符串 KdPrint(("My Dirver is unloading...")); }
win0環異常處理與Object-Hook