Win64 驱动内核编程-29.强制解锁文件
生活随笔
收集整理的這篇文章主要介紹了
Win64 驱动内核编程-29.强制解锁文件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
強制解鎖文件
????強制解鎖因其他進程占用而無法刪除的文件。
1.調用?ZwQuerySystemInformation?的?16?功能號來枚舉系統里的句柄
2.打開擁有此句柄的進程并把此句柄復制到自己的進程
3.用?ZwQueryObject?查詢句柄的類型和名稱
4.如果?發現此句柄的類型是文件句柄,?名稱和被鎖定的文件一致,就關閉此句柄
5.重復?2、3、4?步,直到遍歷完系統里所有的句柄
?
第4步中因為是要解鎖其他進程占用的文件所以有如下細節:
1.用?KeStackAttachProcess“依附”到目標進程
2.用?ObSetHandleAttributes?設置句柄為“可以關閉”
3.用?ZwClose?關閉句柄
4.用?KeUnstackDetachProcess?脫離“依附”目標進程
?
以下代碼適用于Win7??X64,如果想支持全系統,請對應調教。
?
?
#include <ntddk.h>#define kprintf DbgPrint #define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ') #define kfree(_p) ExFreePool(_p)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;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 );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_NAME_INFORMATION {UNICODE_STRING Name;WCHAR NameBuffer[0]; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_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;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);PEPROCESS LookupProcess(HANDLE Pid) { PEPROCESS eprocess=NULL; if( NT_SUCCESS(PsLookupProcessByProcessId(Pid, &eprocess)) ) return eprocess; else return NULL; }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); }VOID CloseFileHandle(char *szFileName) { 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=kmalloc(BufferSize); memset(Buffer,0,BufferSize); Status = ZwQuerySystemInformation(16, Buffer, BufferSize, 0); //SystemHandleInformation while(Status == 0xC0000004) //STATUS_INFO_LENGTH_MISMATCH { kfree(Buffer); BufferSize = BufferSize * 2; Buffer=kmalloc(BufferSize); memset(Buffer,0,BufferSize); Status = ZwQuerySystemInformation(16, Buffer, BufferSize, 0); } if (!NT_SUCCESS(Status)) return; qwHandleCount=((SYSTEM_HANDLE_INFORMATION *)Buffer)->NumberOfHandles; p=(SYSTEM_HANDLE_TABLE_ENTRY_INFO *)((SYSTEM_HANDLE_INFORMATION *)Buffer)->Handles;//ENUM HANDLE PROC 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 ) ) { KdPrint(( "ZwOpenProcess : Fail " )); continue; } ns = ZwDuplicateObject( hProcess ,hHandle ,NtCurrentProcess() ,&hDupObj , PROCESS_ALL_ACCESS ,0 ,DUPLICATE_SAME_ACCESS ); if ( !NT_SUCCESS( ns ) ) { KdPrint(( "ZwDuplicateObject : Fail " )); continue; } //get basic information ZwQueryObject( hDupObj ,ObjectBasicInformation ,&BasicInfo , sizeof( OBJECT_BASIC_INFORMATION ) ,NULL ); //get name information pNameInfo = ExAllocatePoolWithTag( PagedPool ,1024 ,'ONON'); RtlZeroMemory( pNameInfo ,1024 ); qost=ZwQueryObject( hDupObj, ObjectNameInformation, pNameInfo, 1024, &rtl ); //get information and close handle UnicodeStringToCharArray(&(pNameInfo->Name),szFile); ExFreePool( pNameInfo ); ZwClose(hDupObj); ZwClose(hProcess); //if(!_stricmp(szFile,szFileName)) if(strstr(_strlwr(szFile),szFileName)) { PEPROCESS ep=LookupProcess((HANDLE)(p[i].UniqueProcessId)); ForceCloseHandle(ep,p[i].HandleValue); ObDereferenceObject(ep); } } }
執行結果:
?
之前:
啟動驅動之后可以成功刪除因為其他進程占用而導致的文件無法刪除。
宋孖健,13
總結
以上是生活随笔為你收集整理的Win64 驱动内核编程-29.强制解锁文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win64 驱动内核编程-28.枚举消息
- 下一篇: Win64 驱动内核编程-30.枚举与删