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 #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; NTSYSAPINTSTATUSNTAPIZwQueryObject(HANDLE Handle,ULONG ObjectInformationClass,PVOID ObjectInformation,ULONG ObjectInformationLength,PULONG ReturnLength OPTIONAL); NTSYSAPINTSTATUSNTAPIZwQuerySystemInformation( ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength); NTSYSAPINTSTATUSNTAPIZwDuplicateObject(HANDLE SourceProcessHandle,HANDLE SourceHandle,HANDLE TargetProcessHandle OPTIONAL,PHANDLE TargetHandle OPTIONAL,ACCESS_MASK DesiredAccess,ULONG HandleAttributes,ULONG Options); NTSYSAPINTSTATUSNTAPIZwOpenProcess( 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;elsereturn 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); //SystemHandleInformationwhile(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 PROCfor(i=0;iName),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
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~