欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言驅(qū)動(dòng)開發(fā)之內(nèi)核解鎖與強(qiáng)刪文件

 更新時(shí)間:2023年06月15日 11:10:09   作者:lyshark  
在某些時(shí)候我們的系統(tǒng)中會(huì)出現(xiàn)一些無法被正常刪除的文件,如果想要強(qiáng)制刪除則需要在驅(qū)動(dòng)層面對(duì)其進(jìn)行解鎖后才可刪掉,本文為大家介紹了內(nèi)核解鎖與強(qiáng)刪文件的方法,希望對(duì)大家有所幫助

在某些時(shí)候我們的系統(tǒng)中會(huì)出現(xiàn)一些無法被正常刪除的文件,如果想要強(qiáng)制刪除則需要在驅(qū)動(dòng)層面對(duì)其進(jìn)行解鎖后才可刪掉,而所謂的解鎖其實(shí)就是釋放掉文件描述符(句柄表)占用,文件解鎖的核心原理是通過調(diào)用ObSetHandleAttributes函數(shù)將特定句柄設(shè)置為可關(guān)閉狀態(tài),然后在調(diào)用ZwClose將其文件關(guān)閉,強(qiáng)制刪除則是通過ObReferenceObjectByHandle在對(duì)象上提供相應(yīng)的權(quán)限后直接調(diào)用ZwDeleteFile將其刪除,雖此類代碼較為普遍,但作為揭秘ARK工具來說也必須要將其分析并講解一下。

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

// 署名權(quán)
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include <ntddk.h>
// -------------------------------------------------------
// 引用微軟結(jié)構(gòu)
// -------------------------------------------------------
// 結(jié)構(gòu)體定義
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;
// -------------------------------------------------------
// 導(dǎo)出函數(shù)定義
// -------------------------------------------------------
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

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

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

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

NTSTATUS WINAPI ZwQuerySystemInformation(
  _In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,      // 傳入不同參數(shù)則輸出不同內(nèi)容
  _Inout_   PVOID                    SystemInformation,           // 輸出數(shù)據(jù)
  _In_      ULONG                    SystemInformationLength,     // 長(zhǎng)度
  _Out_opt_ PULONG                   ReturnLength                 // 返回長(zhǎng)度
);

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

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

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

NTSYSAPI NTSTATUS ZwQueryObject(
  [in, optional]  HANDLE                   Handle,                        // 要獲取相關(guān)信息的對(duì)象句柄。
  [in]            OBJECT_INFORMATION_CLASS ObjectInformationClass,        // 該值確定 ObjectInformation 緩沖區(qū)中返回的信息的類型。
  [out, optional] PVOID                    ObjectInformation,             // 指向接收請(qǐng)求信息的調(diào)用方分配緩沖區(qū)的指針。
  [in]            ULONG                    ObjectInformationLength,       // 指定 ObjectInformation 緩沖區(qū)的大?。ㄒ宰止?jié)為單位)。
  [out, optional] PULONG                   ReturnLength                   // 指向接收所請(qǐng)求密鑰信息的大?。ㄒ宰止?jié)為單位)的變量的指針。 
);

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

NTSYSAPI NTSTATUS ObSetHandleAttributes(
  HANDLE Handle,                                        // 傳入文件句柄
  POBJECT_HANDLE_FLAG_INFORMATION HandleFlags,          // OBJECT_HANDLE_FLAG_INFORMATION標(biāo)志
  KPROCESSOR_MODE PreviousMode                          // 指定運(yùn)行級(jí)別KernelMode
)

實(shí)現(xiàn)文件解鎖,該驅(qū)動(dòng)程序不僅可用于解鎖應(yīng)用層程序,也可用于解鎖驅(qū)動(dòng),如下代碼中我們解鎖pagefile.sys程序的句柄占用;

// 署名權(quán)
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include "lyshark.h"
// 根據(jù)PID得到EProcess
PEPROCESS LookupProcess(HANDLE Pid)
{
	PEPROCESS eprocess = NULL;
	if (NT_SUCCESS(PsLookupProcessByProcessId(Pid, &eprocess)))
		return eprocess;
	else
		return NULL;
}
// 將uncode轉(zhuǎn)為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);
}
// 強(qiáng)制關(guān)閉句柄
VOID ForceCloseHandle(PEPROCESS Process, ULONG64 HandleValue)
{
	HANDLE h;
	KAPC_STATE ks;
	OBJECT_HANDLE_FLAG_INFORMATION ohfi;
	if (Process == NULL)
	{
		return;
	}
	// 驗(yàn)證進(jìn)程是否可讀寫
	if (!MmIsAddressValid(Process))
	{
		return;
	}
	// 附加到進(jìn)程
	KeStackAttachProcess(Process, &ks);
	h = (HANDLE)HandleValue;
	ohfi.Inherit = 0;
	ohfi.ProtectFromClose = 0;
	// 設(shè)置句柄為可關(guān)閉狀態(tài)
	ObSetHandleAttributes(h, &ohfi, KernelMode);
	// 關(guān)閉句柄
	ZwClose(h);
	// 脫離附加進(jìn)程
	KeUnstackDetachProcess(&ks);
	DbgPrint("EP = [ %d ] | HandleValue = [ %d ] 進(jìn)程句柄已被關(guān)閉 \n",Process,HandleValue);
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("驅(qū)動(dòng)卸載成功 \n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("Hello LyShark.com \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);
	// SystemHandleInformation
	Status = 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;
	}
	// 獲取系統(tǒng)中所有句柄表
	qwHandleCount = ((SYSTEM_HANDLE_INFORMATION *)Buffer)->NumberOfHandles;
	// 得到句柄表的SYSTEM_HANDLE_TABLE_ENTRY_INFO結(jié)構(gòu)
	p = (SYSTEM_HANDLE_TABLE_ENTRY_INFO *)((SYSTEM_HANDLE_INFORMATION *)Buffer)->Handles;
	// 初始化HandleInfo數(shù)組
	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;
		// 初始化對(duì)象結(jié)構(gòu)
		InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);
		// 通過句柄信息打開占用進(jìn)程
		ns = ZwOpenProcess(&hProcess, PROCESS_DUP_HANDLE, &oa, &cid);
		// 打開錯(cuò)誤
		if (!NT_SUCCESS(ns))
		{
			continue;
		}
		// 創(chuàng)建一個(gè)句柄,該句柄是指定源句柄的副本。
		ns = ZwDuplicateObject(hProcess, hHandle, NtCurrentProcess(), &hDupObj, PROCESS_ALL_ACCESS, 0, DUPLICATE_SAME_ACCESS);
		if (!NT_SUCCESS(ns))
		{
			continue;
		}
		// 查詢對(duì)象句柄的信息并放入BasicInfo
		ZwQueryObject(hDupObj, ObjectBasicInformation, &BasicInfo, sizeof(OBJECT_BASIC_INFORMATION), NULL);
		// 得到對(duì)象句柄的名字信息
		pNameInfo = ExAllocatePool(PagedPool, 1024);
		RtlZeroMemory(pNameInfo, 1024);
		// 查詢對(duì)象信息中的對(duì)象名,并將該信息保存到pNameInfo中
		qost = ZwQueryObject(hDupObj, ObjectNameInformation, pNameInfo, 1024, &rtl);
		// 獲取信息并關(guān)閉句柄
		UnicodeStringToCharArray(&(pNameInfo->Name), szFile);
		ExFreePool(pNameInfo);
		ZwClose(hDupObj);
		ZwClose(hProcess);
		// 檢查句柄是否被占用,如果被占用則關(guān)閉文件并刪除
		if (strstr(_strlwr(szFile), "pagefile.sys"))
		{
			PEPROCESS ep = LookupProcess((HANDLE)(p[i].UniqueProcessId));
			// 占用則強(qiáng)制關(guān)閉
			ForceCloseHandle(ep, p[i].HandleValue);
			ObDereferenceObject(ep);
		}
	}
	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

編譯并運(yùn)行這段驅(qū)動(dòng)程序,則會(huì)將pagefile.sys內(nèi)核文件進(jìn)行解鎖,輸出效果如下所示;

聊完了文件解鎖功能,接下來將繼續(xù)探討如何實(shí)現(xiàn)強(qiáng)制刪除文件的功能,文件強(qiáng)制刪除的關(guān)鍵在于ObReferenceObjectByHandle函數(shù),該函數(shù)可在對(duì)象句柄上提供訪問驗(yàn)證,并授予訪問權(quán)限返回指向?qū)ο蟮恼牡南鄳?yīng)指針,當(dāng)有了指定的權(quán)限以后則可以直接調(diào)用ZwDeleteFile()將文件強(qiáng)制刪除。

在調(diào)用初始化句柄前提之下需要先調(diào)用KeGetCurrentIrql()函數(shù),該函數(shù)返回當(dāng)前IRQL級(jí)別,那么什么是IRQL呢?

Windows中系統(tǒng)中斷請(qǐng)求(IRQ)可分為兩種,一種外部中斷(硬件中斷),一種是軟件中斷(INT3),微軟將中斷的概念進(jìn)行了擴(kuò)展,提出了中斷請(qǐng)求級(jí)別(IRQL)的概念,其中就規(guī)定了32個(gè)中斷請(qǐng)求級(jí)別。

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

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

好開始步入正題,函數(shù)ObReferenceObjectByHandle需要傳入一個(gè)文件句柄,而此句柄需要通過IoCreateFileSpecifyDeviceObjectHint對(duì)其進(jìn)行初始化,文件系統(tǒng)篩選器驅(qū)動(dòng)程序使用IoCreateFileSpecifyDeviceObjectHint函數(shù)創(chuàng)建,該函數(shù)的微軟完整定義如下所示;

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

當(dāng)調(diào)用IoCreateFileSpecifyDeviceObjectHint()函數(shù)完成初始化并創(chuàng)建設(shè)備后,則下一步就是調(diào)用ObReferenceObjectByHandle()并傳入初始化好的設(shè)備句柄到Handle參數(shù)上,

NTSTATUS ObReferenceObjectByHandle(
  [in]            HANDLE                     Handle,             // 指定對(duì)象的打開句柄。
  [in]            ACCESS_MASK                DesiredAccess,      // 指定對(duì)對(duì)象的請(qǐng)求訪問類型。
  [in, optional]  POBJECT_TYPE               ObjectType,         // 指向?qū)ο箢愋偷闹羔槨?
  [in]            KPROCESSOR_MODE            AccessMode,         // 指定要用于訪問檢查的訪問模式。 它必須是 UserMode 或 KernelMode。
  [out]           PVOID                      *Object,            // 指向接收指向?qū)ο笳牡闹羔樀淖兞康闹羔槨?
  [out, optional] POBJECT_HANDLE_INFORMATION HandleInformation   // 驅(qū)動(dòng)程序?qū)⒋嗽O(shè)置為 NULL。
);

通過調(diào)用如上兩個(gè)函數(shù)將權(quán)限設(shè)置好以后,我們?cè)偈謩?dòng)將ImageSectionObject也就是映像節(jié)對(duì)象填充為0,然后再將DeleteAccess刪除權(quán)限位打開,最后調(diào)用ZwDeleteFile()函數(shù)即可實(shí)現(xiàn)強(qiáng)制刪除文件的效果,其核心代碼如下所示;

// 署名權(quán)
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include "lyshark.h"
// 強(qiáng)制刪除文件
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;
	// 判斷中斷等級(jí)不大于0
	if (KeGetCurrentIrql() > PASSIVE_LEVEL)
	{
		return FALSE;
	}
	if (pwzFileName.Buffer == NULL || pwzFileName.Length <= 0)
	{
		return FALSE;
	}
	__try
	{
		// 讀取當(dāng)前進(jìn)程的EProcess
		pCurEprocess = IoGetCurrentProcess();
		// 附加進(jìn)程
		KeStackAttachProcess(pCurEprocess, &kapc);
		// 初始化結(jié)構(gòu)
		InitializeObjectAttributes(&fileOb, &pwzFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
		// 文件系統(tǒng)篩選器驅(qū)動(dòng)程序 僅向指定設(shè)備對(duì)象下面的篩選器和文件系統(tǒng)發(fā)送創(chuàng)建請(qǐng)求。
		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;
		}
		// 在對(duì)象句柄上提供訪問驗(yàn)證,如果可以授予訪問權(quán)限,則返回指向?qū)ο蟮恼牡南鄳?yīng)指針。
		status = ObReferenceObjectByHandle(hFile, 0, 0, 0, &pHandleFileObject, 0);
		if (!NT_SUCCESS(status))
		{
			return FALSE;
		}
		// 鏡像節(jié)對(duì)象設(shè)置為0
		((PFILE_OBJECT)(pHandleFileObject))->SectionObjectPointer->ImageSectionObject = 0;
		// 刪除權(quán)限打開
		((PFILE_OBJECT)(pHandleFileObject))->DeleteAccess = 1;
		// 調(diào)用刪除文件API
		status = 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("驅(qū)動(dòng)卸載成功 \n");
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("Hello LyShark.com \n");
	UNICODE_STRING local_path;
	UNICODE_STRING file_path;
	BOOLEAN ref = FALSE;
	// 初始化被刪除文件
	RtlInitUnicodeString(&file_path, L"\\??\\C:\\lyshark.exe");
	// 獲取自身驅(qū)動(dòng)文件
	local_path = ((PLDR_DATA_TABLE_ENTRY64)Driver->DriverSection)->FullDllName;
	// 刪除lyshark.exe
	ref = ForceDeleteFile(file_path);
	if (ref == TRUE)
	{
		DbgPrint("[+] 已刪除 %wZ \n",file_path);
	}
	// 刪除WinDDK.sys
	ref = ForceDeleteFile(local_path);
	if (ref == TRUE)
	{
		DbgPrint("[+] 已刪除 %wZ \n", local_path);
	}
	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

編譯并運(yùn)行如上程序,則會(huì)分別將c://lyshark.exe以及驅(qū)動(dòng)程序自身刪除,并輸出如下圖所示的提示信息;

以上就是C語(yǔ)言驅(qū)動(dòng)開發(fā)之內(nèi)核解鎖與強(qiáng)刪文件的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言內(nèi)核解鎖強(qiáng)刪文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實(shí)現(xiàn)郵件群發(fā)的方法

    C++實(shí)現(xiàn)郵件群發(fā)的方法

    這篇文章主要介紹了C++實(shí)現(xiàn)郵件群發(fā)的方法,較為詳細(xì)的分析了郵件發(fā)送的原理與C++相關(guān)實(shí)現(xiàn)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C++ 實(shí)現(xiàn)雙向鏈表的實(shí)例

    C++ 實(shí)現(xiàn)雙向鏈表的實(shí)例

    這篇文章主要介紹了C++ 實(shí)現(xiàn)雙向鏈表的實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • 使用mmap實(shí)現(xiàn)多進(jìn)程對(duì)大文件拷貝

    使用mmap實(shí)現(xiàn)多進(jìn)程對(duì)大文件拷貝

    這篇文章主要介紹了使用mmap實(shí)現(xiàn)多進(jìn)程對(duì)大文件拷貝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++?qsort函數(shù)排序與冒泡模擬實(shí)現(xiàn)流程詳解

    C++?qsort函數(shù)排序與冒泡模擬實(shí)現(xiàn)流程詳解

    qsort是一個(gè)庫(kù)函數(shù),基于快速排序算法實(shí)現(xiàn)的一個(gè)排序的函數(shù),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言qsort()函數(shù)使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • C語(yǔ)言實(shí)現(xiàn)飛機(jī)訂票系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)飛機(jī)訂票系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)飛機(jī)訂票系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++實(shí)現(xiàn)簡(jiǎn)單迷宮游戲

    C++實(shí)現(xiàn)簡(jiǎn)單迷宮游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單迷宮游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C++無try-catch的異常捕獲示例詳解

    C++無try-catch的異常捕獲示例詳解

    這篇文章主要為大家介紹了C++無try-catch的異常捕獲示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中堆排序的分析總結(jié)

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中堆排序的分析總結(jié)

    堆是計(jì)算機(jī)科學(xué)中一類特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱,通常是一個(gè)可以被看做一棵完全二叉樹的數(shù)組對(duì)象。而堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法。本文將通過圖片詳細(xì)介紹堆排序,需要的可以參考一下
    2022-04-04
  • C語(yǔ)言零基礎(chǔ)講解指針和數(shù)組

    C語(yǔ)言零基礎(chǔ)講解指針和數(shù)組

    由于數(shù)據(jù)的表現(xiàn)形式多種多樣,還有字符型和其它的數(shù)值類型,因此僅有基本數(shù)據(jù)類型是不夠的。是否可以通過基本數(shù)據(jù)類型的組合抽象構(gòu)造其它的數(shù)據(jù)類型呢?下面是小編為大家?guī)淼腃語(yǔ)言數(shù)組與指針詳解的知識(shí)
    2022-04-04
  • C++實(shí)現(xiàn)從數(shù)組中同時(shí)取出最大最小元素算法示例

    C++實(shí)現(xiàn)從數(shù)組中同時(shí)取出最大最小元素算法示例

    這篇文章主要介紹了C++實(shí)現(xiàn)從數(shù)組中同時(shí)取出最大最小元素算法,結(jié)合具體實(shí)例形式分析了C++通過數(shù)組的遍歷、排序獲取最大與最小元素的相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09

最新評(píng)論