强制解锁文件
强制解锁因其他进程占用而无法删除的文件。
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
NTSTAT