8.2 Windows驅動開發:內核解鎖與強刪文件

在某些時候我們的系統中會出現一些無法被正常刪除的文件,如果想要強制刪除則需要在驅動層面對其進行解鎖后才可刪掉,而所謂的解鎖其實就是釋放掉文件描述符(句柄表)占用,文件解鎖的核心原理是通過調用ObSetHandleAttributes函數將特定句柄設置為可關閉狀態,然后在調用ZwClose將其文件關閉,強制刪除則是通過ObReferenceObjectByHandle在對象上提供相應的權限后直接調用ZwDeleteFile將其刪除。

在內核中實現解鎖和強制刪除文件是一種常見的技術,通常用于刪除被其他進程占用的文件。下面是一些實現方式:

  • 使用 ZwOpenFile 函數打開文件,并指定 FILE_SHARE_DELETE 標志,這將允許其他進程在文件打開期間進行刪除操作。然后,調用 ZwSetInformationFile 函數,將文件句柄作為參數傳遞給它,并指定 FILE_DISPOSITION_INFORMATION 類型,以刪除文件。

  • 使用 NtQuerySystemInformation 函數獲取系統進程信息,并枚舉每個進程以查找擁有要刪除文件的句柄的進程。然后,使用 ZwQuerySystemInformation 函數獲取有關進程打開句柄的信息,并枚舉每個句柄以查找要刪除的文件句柄。一旦找到了該句柄,就可以使用 ZwClose 函數關閉該句柄,并調用 ZwSetInformationFile 函數刪除文件。

需要注意的是,強制刪除文件可能會引起系統穩定性問題和數據丟失,因此應該謹慎使用,并避免誤刪重要文件。此外,一些安全軟件和操作系統可能會檢測到這些操作,并采取防御措施。因此,在實現這些技術時,需要遵循操作系統和安全軟件的規定,以確保系統的安全和穩定。

雖此類代碼較為普遍,但作為揭秘ARK工具來說也必須要將其分析并講解一下。

首先封裝lyshark.h通用頭文件,并定義好我們所需要的結構體,以及特定未導出函數的聲明,此處的定義部分是微軟官方的規范,如果不懂結構具體含義可自行去微軟官方查閱參考資料。

#include <ntddk.h>// -------------------------------------------------------
// 引用微軟結構
// -------------------------------------------------------
// 結構體定義
typedef struct _HANDLE_INFO
{UCHAR ObjectTypeIndex;UCHAR HandleAttributes;USHORT  HandleValue;ULONG GrantedAccess;ULONG64 Object;UCHAR Name[256];
} HANDLE_INFO, *PHANDLE_INFO;HANDLE_INFO HandleInfo[1024];typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{USHORT  UniqueProcessId;USHORT  CreatorBackTraceIndex;UCHAR ObjectTypeIndex;UCHAR HandleAttributes;USHORT  HandleValue;PVOID Object;ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;typedef struct _SYSTEM_HANDLE_INFORMATION
{ULONG64 NumberOfHandles;SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;typedef enum _OBJECT_INFORMATION_CLASS
{ObjectBasicInformation,ObjectNameInformation,ObjectTypeInformation,ObjectAllInformation,ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;typedef struct _OBJECT_BASIC_INFORMATION
{ULONG                   Attributes;ACCESS_MASK             DesiredAccess;ULONG                   HandleCount;ULONG                   ReferenceCount;ULONG                   PagedPoolUsage;ULONG                   NonPagedPoolUsage;ULONG                   Reserved[3];ULONG                   NameInformationLength;ULONG                   TypeInformationLength;ULONG                   SecurityDescriptorLength;LARGE_INTEGER           CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;typedef struct _OBJECT_TYPE_INFORMATION
{UNICODE_STRING          TypeName;ULONG                   TotalNumberOfHandles;ULONG                   TotalNumberOfObjects;WCHAR                   Unused1[8];ULONG                   HighWaterNumberOfHandles;ULONG                   HighWaterNumberOfObjects;WCHAR                   Unused2[8];ACCESS_MASK             InvalidAttributes;GENERIC_MAPPING         GenericMapping;ACCESS_MASK             ValidAttributes;BOOLEAN                 SecurityRequired;BOOLEAN                 MaintainHandleCount;USHORT                  MaintainTypeList;POOL_TYPE               PoolType;ULONG                   DefaultPagedPoolCharge;ULONG                   DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;typedef struct _KAPC_STATE
{LIST_ENTRY ApcListHead[2];PVOID Process;BOOLEAN KernelApcInProgress;BOOLEAN KernelApcPending;BOOLEAN UserApcPending;
}KAPC_STATE, *PKAPC_STATE;typedef struct _OBJECT_HANDLE_FLAG_INFORMATION
{BOOLEAN Inherit;BOOLEAN ProtectFromClose;
}OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION;typedef struct _LDR_DATA_TABLE_ENTRY64
{LIST_ENTRY64 InLoadOrderLinks;LIST_ENTRY64 InMemoryOrderLinks;LIST_ENTRY64 InInitializationOrderLinks;ULONG64 DllBase;ULONG64 EntryPoint;ULONG64 SizeOfImage;UNICODE_STRING FullDllName;UNICODE_STRING BaseDllName;ULONG Flags;USHORT LoadCount;USHORT TlsIndex;LIST_ENTRY64 HashLinks;ULONG64 SectionPointer;ULONG64 CheckSum;ULONG64 TimeDateStamp;ULONG64 LoadedImports;ULONG64 EntryPointActivationContext;ULONG64 PatchInformation;LIST_ENTRY64 ForwarderLinks;LIST_ENTRY64 ServiceTagLinks;LIST_ENTRY64 StaticLinks;ULONG64 ContextInformation;ULONG64 OriginalBase;LARGE_INTEGER LoadTime;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;// -------------------------------------------------------
// 導出函數定義
// -------------------------------------------------------NTKERNELAPI NTSTATUS ObSetHandleAttributes
(HANDLE Handle,POBJECT_HANDLE_FLAG_INFORMATION HandleFlags,KPROCESSOR_MODE PreviousMode
);NTKERNELAPI VOID KeStackAttachProcess
(PEPROCESS PROCESS,PKAPC_STATE ApcState
);NTKERNELAPI VOID KeUnstackDetachProcess
(PKAPC_STATE ApcState
);NTKERNELAPI NTSTATUS PsLookupProcessByProcessId
(IN HANDLE ProcessId,OUT PEPROCESS *Process
);NTSYSAPI NTSTATUS NTAPI ZwQueryObject
(HANDLE  Handle,ULONG ObjectInformationClass,PVOID ObjectInformation,ULONG ObjectInformationLength,PULONG  ReturnLength OPTIONAL
);NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation
(ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG  ReturnLength
);NTSYSAPI NTSTATUS NTAPI ZwDuplicateObject
(HANDLE    SourceProcessHandle,HANDLE    SourceHandle,HANDLE    TargetProcessHandle OPTIONAL,PHANDLE   TargetHandle OPTIONAL,ACCESS_MASK DesiredAccess,ULONG   HandleAttributes,ULONG   Options
);NTSYSAPI NTSTATUS NTAPI ZwOpenProcess
(PHANDLE       ProcessHandle,ACCESS_MASK     AccessMask,POBJECT_ATTRIBUTES  ObjectAttributes,PCLIENT_ID      ClientId
);#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004

接下來將具體分析如何解鎖指定文件的句柄表,強制解鎖文件句柄表,大體步驟如下所示。

  • 1.首先調用ZwQuerySystemInformation的16功能號SystemHandleInformation來枚舉系統里的句柄。
  • 2.通過ZwOpenProcess()打開擁有此句柄的進程,通過ZwDuplicateObject創建一個新的句柄,并把此句柄復制到自己的進程內。
  • 3.通過調用ZwQueryObject并傳入ObjectNameInformation查詢到句柄的名稱,并將其放入到pNameInfo變量內。
  • 4.循環這個過程并在每次循環中通過strstr()判斷是否是我們需要關閉的文件名,如果是則調用ForceCloseHandle強制解除占用。
  • 5.此時會進入到ForceCloseHandle流程內,通過KeStackAttachProcess附加到進程內,并調用ObSetHandleAttributes將句柄設置為可關閉狀態。
  • 6.最后調用ZwClose關閉句柄占用,并KeUnstackDetachProcess脫離該進程。

實現代碼流程非常容易理解,此類功能也沒有其他別的寫法了一般也就這種,但是還是需要注意這些內置函數的參數傳遞,這其中ZwQuerySystemInformation()一般用于查詢系統進程等信息居多,但通過對SystemInformationClass變量傳入不同的參數可實現對不同結構的枚舉工作,具體的定義可去查閱微軟定義規范;

NTSTATUS WINAPI ZwQuerySystemInformation(_In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,      // 傳入不同參數則輸出不同內容_Inout_   PVOID                    SystemInformation,           // 輸出數據_In_      ULONG                    SystemInformationLength,     // 長度_Out_opt_ PULONG                   ReturnLength                 // 返回長度
);

函數ZwDuplicateObject(),該函數例程用于創建一個句柄,該句柄是指定源句柄的副本,此函數的具體聲明部分如下;

NTSYSAPI NTSTATUS ZwDuplicateObject([in]            HANDLE      SourceProcessHandle,    // 要復制的句柄的源進程的句柄。[in]            HANDLE      SourceHandle,           // 要復制的句柄。[in, optional]  HANDLE      TargetProcessHandle,    // 要接收新句柄的目標進程的句柄。[out, optional] PHANDLE     TargetHandle,           // 指向例程寫入新重復句柄的 HANDLE 變量的指針。[in]            ACCESS_MASK DesiredAccess,          // 一個ACCESS_MASK值,該值指定新句柄的所需訪問。[in]            ULONG       HandleAttributes,       // 一個 ULONG,指定新句柄的所需屬性。 [in]            ULONG       Options                 // 一組標志,用于控制重復操作的行為。
);

函數ZwQueryObject()其可以返回特定的一個對象參數,此函數尤為注意第二個參數,當下我們傳入的是ObjectNameInformation則代表需要取出對象名稱,而如果使用ObjectTypeInformation則是返回對象類型,該函數微軟定義如下所示;

NTSYSAPI NTSTATUS ZwQueryObject([in, optional]  HANDLE                   Handle,                        // 要獲取相關信息的對象句柄。[in]            OBJECT_INFORMATION_CLASS ObjectInformationClass,        // 該值確定 ObjectInformation 緩沖區中返回的信息的類型。[out, optional] PVOID                    ObjectInformation,             // 指向接收請求信息的調用方分配緩沖區的指針。[in]            ULONG                    ObjectInformationLength,       // 指定 ObjectInformation 緩沖區的大小(以字節為單位)。[out, optional] PULONG                   ReturnLength                   // 指向接收所請求密鑰信息的大小(以字節為單位)的變量的指針。 
);

而對于ForceCloseHandle函數中,需要注意的只有一個ObSetHandleAttributes該函數微軟并沒有格式化文檔,但是也并不影響我們使用它,如下最需要注意的是PreviousMode變量,該變量如果傳入KernelMode則是內核模式,傳入UserMode則代表用戶模式,為了權限最大化此處需要寫入KernelMode模式;

NTSYSAPI NTSTATUS ObSetHandleAttributes(HANDLE Handle,                                        // 傳入文件句柄POBJECT_HANDLE_FLAG_INFORMATION HandleFlags,          // OBJECT_HANDLE_FLAG_INFORMATION標志KPROCESSOR_MODE PreviousMode                          // 指定運行級別KernelMode
)

實現文件解鎖,該驅動程序不僅可用于解鎖應用層程序,也可用于解鎖驅動,如下代碼中我們解鎖pagefile.sys程序的句柄占用;

#include "lyshark.h"// 根據PID得到EProcess
PEPROCESS LookupProcess(HANDLE Pid)
{PEPROCESS eprocess = NULL;if (NT_SUCCESS(PsLookupProcessByProcessId(Pid, &eprocess)))return eprocess;elsereturn NULL;
}// 將uncode轉為char*
VOID UnicodeStringToCharArray(PUNICODE_STRING dst, char *src)
{ANSI_STRING string;if (dst->Length > 260){return;}RtlUnicodeStringToAnsiString(&string, dst, TRUE);strcpy(src, string.Buffer);RtlFreeAnsiString(&string);
}// 強制關閉句柄
VOID ForceCloseHandle(PEPROCESS Process, ULONG64 HandleValue)
{HANDLE h;KAPC_STATE ks;OBJECT_HANDLE_FLAG_INFORMATION ohfi;if (Process == NULL){return;}// 驗證進程是否可讀寫if (!MmIsAddressValid(Process)){return;}// 附加到進程KeStackAttachProcess(Process, &ks);h = (HANDLE)HandleValue;ohfi.Inherit = 0;ohfi.ProtectFromClose = 0;// 設置句柄為可關閉狀態ObSetHandleAttributes(h, &ohfi, KernelMode);// 關閉句柄ZwClose(h);// 脫離附加進程KeUnstackDetachProcess(&ks);DbgPrint("EP = [ %d ] | HandleValue = [ %d ] 進程句柄已被關閉 \n",Process,HandleValue);
}VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint("驅動卸載成功 \n");
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("Hello lyshark \n");PVOID Buffer;ULONG BufferSize = 0x20000, rtl = 0;NTSTATUS Status, qost = 0;NTSTATUS ns = STATUS_SUCCESS;ULONG64 i = 0;ULONG64 qwHandleCount;SYSTEM_HANDLE_TABLE_ENTRY_INFO *p;OBJECT_BASIC_INFORMATION BasicInfo;POBJECT_NAME_INFORMATION pNameInfo;ULONG ulProcessID;HANDLE hProcess;HANDLE hHandle;HANDLE hDupObj;CLIENT_ID cid;OBJECT_ATTRIBUTES oa;CHAR szFile[260] = { 0 };Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, "LyShark");memset(Buffer, 0, BufferSize);// SystemHandleInformationStatus = ZwQuerySystemInformation(16, Buffer, BufferSize, 0);while (Status == STATUS_INFO_LENGTH_MISMATCH){ExFreePool(Buffer);BufferSize = BufferSize * 2;Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, "LyShark");memset(Buffer, 0, BufferSize);Status = ZwQuerySystemInformation(16, Buffer, BufferSize, 0);}if (!NT_SUCCESS(Status)){return;}// 獲取系統中所有句柄表qwHandleCount = ((SYSTEM_HANDLE_INFORMATION *)Buffer)->NumberOfHandles;// 得到句柄表的SYSTEM_HANDLE_TABLE_ENTRY_INFO結構p = (SYSTEM_HANDLE_TABLE_ENTRY_INFO *)((SYSTEM_HANDLE_INFORMATION *)Buffer)->Handles;// 初始化HandleInfo數組memset(HandleInfo, 0, 1024 * sizeof(HANDLE_INFO));// 開始枚舉句柄for (i = 0; i<qwHandleCount; i++){ulProcessID = (ULONG)p[i].UniqueProcessId;cid.UniqueProcess = (HANDLE)ulProcessID;cid.UniqueThread = (HANDLE)0;hHandle = (HANDLE)p[i].HandleValue;// 初始化對象結構InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);// 通過句柄信息打開占用進程ns = ZwOpenProcess(&hProcess, PROCESS_DUP_HANDLE, &oa, &cid);// 打開錯誤if (!NT_SUCCESS(ns)){continue;}// 創建一個句柄,該句柄是指定源句柄的副本。ns = ZwDuplicateObject(hProcess, hHandle, NtCurrentProcess(), &hDupObj, PROCESS_ALL_ACCESS, 0, DUPLICATE_SAME_ACCESS);if (!NT_SUCCESS(ns)){continue;}// 查詢對象句柄的信息并放入BasicInfoZwQueryObject(hDupObj, ObjectBasicInformation, &BasicInfo, sizeof(OBJECT_BASIC_INFORMATION), NULL);// 得到對象句柄的名字信息pNameInfo = ExAllocatePool(PagedPool, 1024);RtlZeroMemory(pNameInfo, 1024);// 查詢對象信息中的對象名,并將該信息保存到pNameInfo中qost = ZwQueryObject(hDupObj, ObjectNameInformation, pNameInfo, 1024, &rtl);// 獲取信息并關閉句柄UnicodeStringToCharArray(&(pNameInfo->Name), szFile);ExFreePool(pNameInfo);ZwClose(hDupObj);ZwClose(hProcess);// 檢查句柄是否被占用,如果被占用則關閉文件并刪除if (strstr(_strlwr(szFile), "pagefile.sys")){PEPROCESS ep = LookupProcess((HANDLE)(p[i].UniqueProcessId));// 占用則強制關閉ForceCloseHandle(ep, p[i].HandleValue);ObDereferenceObject(ep);}}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

編譯并運行這段驅動程序,則會將pagefile.sys內核文件進行解鎖,輸出效果如下所示;

聊完了文件解鎖功能,接下來將繼續探討如何實現強制刪除文件的功能,文件強制刪除的關鍵在于ObReferenceObjectByHandle函數,該函數可在對象句柄上提供訪問驗證,并授予訪問權限返回指向對象的正文的相應指針,當有了指定的權限以后則可以直接調用ZwDeleteFile()將文件強制刪除。

在調用初始化句柄前提之下需要先調用KeGetCurrentIrql()函數,該函數返回當前IRQL級別,那么什么是IRQL呢?

Windows中系統中斷請求(IRQ)可分為兩種,一種外部中斷(硬件中斷),一種是軟件中斷(INT3),微軟將中斷的概念進行了擴展,提出了中斷請求級別(IRQL)的概念,其中就規定了32個中斷請求級別。

  • 其中0-2級為軟中斷,順序由小到大分別是:PASSIVE_LEVEL,APC_LEVEL,DISPATCH_LEVEL
  • 其中27-31為硬中斷,順序由小到大分別是:PROFILE_LEVEL,CLOCK1_LEVEL,CLOCK2_LEVEL,IPI_LEVEL,POWER_LEVEL,HIGH_LEVEL

我們的代碼中開頭部分KeGetCurrentIrql() > PASSIVE_LEVEL則是在判斷當前的級別不大于0級,也就是說必須要大于0才可以繼續執行。

好開始步入正題,函數ObReferenceObjectByHandle需要傳入一個文件句柄,而此句柄需要通過IoCreateFileSpecifyDeviceObjectHint對其進行初始化,文件系統篩選器驅動程序使用IoCreateFileSpecifyDeviceObjectHint函數創建,該函數的微軟完整定義如下所示;

NTSTATUS IoCreateFileSpecifyDeviceObjectHint([out]          PHANDLE            FileHandle,               // 指向變量的指針,該變量接收文件對象的句柄。[in]           ACCESS_MASK        DesiredAccess,            // 標志的位掩碼,指定調用方需要對文件或目錄的訪問類型。[in]           POBJECT_ATTRIBUTES ObjectAttributes,         // 指向已由 InitializeObjectAttributes 例程初始化的OBJECT_ATTRIBUTES結構的指針。[out]          PIO_STATUS_BLOCK   IoStatusBlock,            // 指向 IO_STATUS_BLOCK 結構的指針,該結構接收最終完成狀態和有關所請求操作的信息。[in, optional] PLARGE_INTEGER     AllocationSize,           // 指定文件的初始分配大小(以字節為單位)。[in]           ULONG              FileAttributes,           // 僅當文件創建、取代或在某些情況下被覆蓋時,才會應用顯式指定的屬性。[in]           ULONG              ShareAccess,              // 指定調用方希望的對文件的共享訪問類型(為零或 1,或以下標志的組合)。[in]           ULONG              Disposition,              // 指定一個值,該值確定要執行的操作,具體取決于文件是否已存在。[in]           ULONG              CreateOptions,            // 指定要在創建或打開文件時應用的選項。[in, optional] PVOID              EaBuffer,                 // 指向調用方提供的 FILE_FULL_EA_INFORMATION結構化緩沖區的指針。[in]           ULONG              EaLength,                 // EaBuffer 的長度(以字節為單位)。[in]           CREATE_FILE_TYPE   CreateFileType,           // 驅動程序必須將此參數設置為 CreateFileTypeNone。[in, optional] PVOID              InternalParameters,       // 驅動程序必須將此參數設置為 NULL。[in]           ULONG              Options,                  // 指定要在創建請求期間使用的選項。[in, optional] PVOID              DeviceObject              // 指向要向其發送創建請求的設備對象的指針。
);

當調用IoCreateFileSpecifyDeviceObjectHint()函數完成初始化并創建設備后,則下一步就是調用ObReferenceObjectByHandle()并傳入初始化好的設備句柄到Handle參數上,

NTSTATUS ObReferenceObjectByHandle([in]            HANDLE                     Handle,             // 指定對象的打開句柄。[in]            ACCESS_MASK                DesiredAccess,      // 指定對對象的請求訪問類型。[in, optional]  POBJECT_TYPE               ObjectType,         // 指向對象類型的指針。[in]            KPROCESSOR_MODE            AccessMode,         // 指定要用于訪問檢查的訪問模式。 它必須是 UserMode 或 KernelMode。[out]           PVOID                      *Object,            // 指向接收指向對象正文的指針的變量的指針。[out, optional] POBJECT_HANDLE_INFORMATION HandleInformation   // 驅動程序將此設置為 NULL。
);

通過調用如上兩個函數將權限設置好以后,我們再手動將ImageSectionObject也就是映像節對象填充為0,然后再將DeleteAccess刪除權限位打開,最后調用ZwDeleteFile()函數即可實現強制刪除文件的效果,其核心代碼如下所示;

#include "lyshark.h"// 強制刪除文件
BOOLEAN ForceDeleteFile(UNICODE_STRING pwzFileName)
{PEPROCESS pCurEprocess = NULL;KAPC_STATE kapc = { 0 };OBJECT_ATTRIBUTES fileOb;HANDLE hFile = NULL;NTSTATUS status = STATUS_UNSUCCESSFUL;IO_STATUS_BLOCK iosta;PDEVICE_OBJECT DeviceObject = NULL;PVOID pHandleFileObject = NULL;// 判斷中斷等級不大于0if (KeGetCurrentIrql() > PASSIVE_LEVEL){return FALSE;}if (pwzFileName.Buffer == NULL || pwzFileName.Length <= 0){return FALSE;}__try{// 讀取當前進程的EProcesspCurEprocess = IoGetCurrentProcess();// 附加進程KeStackAttachProcess(pCurEprocess, &kapc);// 初始化結構InitializeObjectAttributes(&fileOb, &pwzFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);// 文件系統篩選器驅動程序 僅向指定設備對象下面的篩選器和文件系統發送創建請求。status = IoCreateFileSpecifyDeviceObjectHint(&hFile,SYNCHRONIZE | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | FILE_READ_DATA,&fileOb,&iosta,NULL,0,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,FILE_OPEN,FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,0,0,CreateFileTypeNone,0,IO_IGNORE_SHARE_ACCESS_CHECK,DeviceObject);if (!NT_SUCCESS(status)){return FALSE;}// 在對象句柄上提供訪問驗證,如果可以授予訪問權限,則返回指向對象的正文的相應指針。status = ObReferenceObjectByHandle(hFile, 0, 0, 0, &pHandleFileObject, 0);if (!NT_SUCCESS(status)){return FALSE;}// 鏡像節對象設置為0((PFILE_OBJECT)(pHandleFileObject))->SectionObjectPointer->ImageSectionObject = 0;// 刪除權限打開((PFILE_OBJECT)(pHandleFileObject))->DeleteAccess = 1;// 調用刪除文件APIstatus = ZwDeleteFile(&fileOb);if (!NT_SUCCESS(status)){return FALSE;}}_finally{if (pHandleFileObject != NULL){ObDereferenceObject(pHandleFileObject);pHandleFileObject = NULL;}KeUnstackDetachProcess(&kapc);if (hFile != NULL || hFile != (PVOID)-1){ZwClose(hFile);hFile = (PVOID)-1;}}return TRUE;
}VOID UnDriver(PDRIVER_OBJECT driver)
{DbgPrint("驅動卸載成功 \n");
}NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{DbgPrint("Hello lyshark \n");UNICODE_STRING local_path;UNICODE_STRING file_path;BOOLEAN ref = FALSE;// 初始化被刪除文件RtlInitUnicodeString(&file_path, L"\\??\\C:\\lyshark.exe");// 獲取自身驅動文件local_path = ((PLDR_DATA_TABLE_ENTRY64)Driver->DriverSection)->FullDllName;// 刪除lyshark.exeref = ForceDeleteFile(file_path);if (ref == TRUE){DbgPrint("[+] 已刪除 %wZ \n",file_path);}// 刪除WinDDK.sysref = ForceDeleteFile(local_path);if (ref == TRUE){DbgPrint("[+] 已刪除 %wZ \n", local_path);}Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;
}

編譯并運行如上程序,則會分別將c://lyshark.exe以及驅動程序自身刪除,并輸出如下圖所示的提示信息;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/160546.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/160546.shtml
英文地址,請注明出處:http://en.pswp.cn/news/160546.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Axios使用方式

ajax是JQUERY封裝的XMLHttprequest用來發送http請求 Axios簡單點說它就是一個js庫,支持ajax請求,發送axios請求功能更加豐富,豐富在哪不知道 1.npm使用方式 vue項目中 npm install axios 2.cdn方式 <script src"https://unpkg.com/axios/dist/axios.min.js">…

【三維幾何學習】自制簡單的網格可視化軟件 — Mesh Visualization

自制簡單的網格可視化軟件 — Mesh Visualization 引言一、整體框架1.1 三角形網格1.2 界面管理1.3 VTK可視化界面 二、核心源碼2.1 三角形網格&#xff1a;TriMesh類2.2 界面Widget_Mesh_Manager2.3 VTK可視化2.4 main 引言 使用PyQt自制簡單的網格可視化軟件 - 視頻展示 本是…

Node.js入門指南(一)

目錄 Node.js入門 什么是Node.js Node.js的作用 Node.js安裝 Node.js編碼注意事項 Buffer(緩沖器&#xff09; 定義 使用 fs模塊 概念 文件寫入 文件讀取 文件移動與重命名 文件刪除 文件夾操作 查看資源狀態 路徑問題 path模塊 Node.js入門 什么是Node.js …

2023最新面試題

第一家 自我介紹介紹一下最近一個&#xff08;最熟悉的一個&#xff09;項目 項目幾個人在負責 項目實際在用了嗎&#xff0c;哪個平臺在用啊&#xff08;在哪里上線&#xff09; 你認為你自己做的項目里面哪個比較難做呢&#xff0c;項目里面有什么難點&#xff1f;常用的是V…

安卓隱私指示器學習筆記

最近了解到Google 在Android12上新增了權限指示器&#xff0c;可以在信號欄的右側顯示當前訪問錄音機和Camera的應用&#xff0c;點擊后可以跳轉到相應應用的權限界面&#xff0c;消費者可以控制權限的開啟和關閉。國內手機廠商最近幾年都在增加隱私看板供能&#xff0c;消費者…

java 中漢字轉拼音

需要引入的jar <!-- pinyin --><dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.0</version></dependency> 實現工具類 package com.julong.util;import java.util.regex…

編程語言發展史:高級語言的興起

一、高級語言的定義 高級語言是相對于匯編語言而言的&#xff0c;它是一種更加抽象、更加易于理解和使用的計算機編程語言。高級語言的特點是語法簡單、易于學習、易于使用、可讀性強、可移植性好等。高級語言的出現極大地提高了程序員的工作效率&#xff0c;同時也使得計算機…

Qt connect()方法Qt::ConnectionType

connect() Qt&#xff0c;綁定信號和槽原型&#xff1a; static QMetaObject::Connection connect(const QObject *sender, const char *signal,const QObject *receiver, const char *member, Qt::ConnectionType Qt::AutoConnection);static QMetaObject::Connection conn…

JSP:Javabean

起初&#xff0c;JavaBean的目的是為了將可以重復使用的代碼進行打包&#xff0c;在傳統的應用中&#xff0c;JavaBean主要用于實現一些可視化界面&#xff0c;如一個窗體、按鈕、文本框等&#xff0c;這樣的JavaBean稱之可視化的JavaBean。 隨著技術的不斷發展與項目的需求&am…

防火墻部署模式 -- 鏡像流量(旁路模式)

鏡像流量&#xff08;旁路模式&#xff09; 如圖&#xff0c;與單臂路由模式不同&#xff0c;旁路模式中&#xff0c;PC的流量不會流經防火墻&#xff0c;就算防火墻宕機也不會影他們之間的數據傳輸。 鏡像的原理是交換機把被鏡像端口的流量復制一份&#xff0c;發到監聽端口&…

尋找二叉樹最近公共祖先

二叉樹為BST LCR 193. 二叉搜索樹的最近公共祖先 1.1 遞歸 利用BST的性質 p root 或者 q root ,顯然根為公共祖先p < root < q 或者 p > root > q,顯然p&#xff0c;q分別位于root的一顆子樹上&#xff0c;故根為公共祖先max{p,q} < root ,顯然 p 和q 均在…

基于單片機聲光控智能路燈系統仿真設計

**單片機設計介紹&#xff0c; 基于單片機聲光控智能路燈系統仿真設計 文章目錄 一 概要二、功能設計設計思路 三、 軟件設計原理圖 五、 程序六、 文章目錄 一 概要 基于單片機的聲光控智能路燈系統是一種利用單片機技術實現智能控制的路燈系統。它通過感知環境音量和光照強度…

Axios 請求響應結果的結構

發送請求 this.$axios.get(https://apis.jxcxin.cn/api/title?urlhttps://apis.jxcxin.cn/,{params: {id: 10}}).then(res > {console.log(res)})輸出返回結果 confing 請求時的配置對象&#xff0c;如果請求的url&#xff0c;請求的方法&#xff0c;請求的參數&#xff0c…

深入理解Java注解的實現原理以及前世今生

深入理解Java注解的實現原理以及前世今生 小雪初寒&#xff0c;請添衣&#xff0c;冬棋如意&#xff0c;待良人&#xff0c;望歸期。 1.Java注解的前世今生 Java注解是一種元數據標記&#xff0c;它提供了一種在Java代碼中添加元數據&#xff08;注釋&#xff09;的方式。注解…

Linux文件

目錄 一、基本概念 二、研究進程和被打開文件的關系 &#xff08;一&#xff09;w方式 &#xff08;二&#xff09;a方式 三、認識系統接口&#xff0c;操作文件 &#xff08;一&#xff09;認識文件描述符 &#xff08;二&#xff09;舉例 &#xff08;三&#xff09;…

2023年中國油墨樹脂主要環節、產量及市場規模分析[圖]

油墨樹脂是指用于油墨制造中的一種高分子材料&#xff0c;主要用于改善油墨的粘性、流動性、光澤度和耐磨性等性能。其主要成分為合成樹脂&#xff0c;如聚酯、聚酰胺、聚丙烯酸酯等。油墨樹脂在油墨制造中的應用非常廣泛&#xff0c;可以用于各種類型的油墨&#xff0c;包括印…

github訪問不了問題

git clone github上的項目的時候&#xff0c;不是訪問不了&#xff0c;就是克隆過程被中斷了 最近找到一個代理&#xff0c;從代理那里clone而不是github上 GitHub代理 – 初果編程

python BDD 的相關概念

在Python 語言中進行BDD的規格和測試文件的編寫的時候&#xff0c;常常會遇到下面的概念&#xff1a; Fixture : 測試設施。設定測試環境的預設狀態或值的機制。Background&#xff1a; 背景。所有場景的公共部分。Scenario&#xff1a; 場景。Given &#xff1a; 前置條件Whe…

centos7 安裝node.js,不用wget也不用解壓文件

更新系統&#xff1a;首先&#xff0c;更新系統的軟件包列表和已安裝的軟件包。在終端中以root用戶或具有sudo權限的用戶身份運行以下命令&#xff1a; sudo yum update添加Node.js源&#xff1a;CentOS 7默認的軟件倉庫中可能不包含最新的Node.js版本。因此&#xff0c;我們需…

[leetcode 數位運算] 2939. 最大異或乘積 M

給你三個整數 a &#xff0c;b 和 n &#xff0c;請你返回 (a XOR x) * (b XOR x) 的 最大值 且 x 需要滿足 0 < x < 2n。 由于答案可能會很大&#xff0c;返回它對 109 7 取余 后的結果。 注意&#xff0c;XOR 是按位異或操作。 示例 1&#xff1a; 輸入&#xff1…