一直在使用一个小工具叫unlocker。知道它是用关闭句柄的方法来删除文件的,但是自己也没有怎么研究过这东西。传说中更厉害的方法是直接向磁盘写0和Xcb大法,最近准备好好研究这些删除方法。那么就从句柄开始吧。这里我只做枚举句柄的工作,因为关闭句柄就是把ZwDuplicateObject 的Options 这个参数赋值为DUPLICATE_CLOSE_SOURCE 。这里还要感谢一下sudami和NetRoc同学。。。O(∩_∩)O哈哈~
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
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[];
} 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 _KOBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
WCHAR NameBuffer[];
} KOBJECT_NAME_INFORMATION, *PKOBJECT_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;
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryObject(
IN HANDLE Handle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG ObjectInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwDuplicateObject(
IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle OPTIONAL,
OUT PHANDLE TargetHandle OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN ULONG HandleAttributes,
IN ULONG Options
);
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
);
NTSTATUS NTAPI AYA_EnumHandle();
void AYA_Unload( IN PDRIVER_OBJECT pDriverObj )
{
UNICODE_STRING Temp;
RtlInitUnicodeString( &Temp ,AYA_LINK );
IoDeleteSymbolicLink( &Temp );
IoDeleteDevice( pDriverObj->DeviceObject );
}
NTSTATUS AYA_Dispatch( IN PDEVICE_OBJECT pDeviceObj ,IN PIRP pIrp )
{
NTSTATUS ns = STATUS_SUCCESS;
PIO_STACK_LOCATION stIrp;
stIrp = IoGetCurrentIrpStackLocation( pIrp );
switch( stIrp->MajorFunction )
{
case
IRP_MJ_CREATE:
break
;
case
IRP_MJ_CLOSE:
break
;
case
IRP_MJ_DEVICE_CONTROL:
break
;
default:
pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;
break
;
}
ns = pIrp->IoStatus.Status;
IoCompleteRequest( pIrp ,IO_NO_INCREMENT );
return
ns;
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObj ,IN PUNICODE_STRING RegistryPath )
{
NTSTATUS ns = STATUS_SUCCESS;
UNICODE_STRING AYA;
UNICODE_STRING AYAL;
PDEVICE_OBJECT pDevice;
ns = AYA_EnumHandle();
RtlInitUnicodeString( &AYA ,AYA_DEVICE );
ns = IoCreateDevice( pDriverObj ,0 ,&AYA ,FILE_DEVICE_UNKNOWN ,0 ,FALSE ,&pDevice );
RtlInitUnicodeString( &AYAL ,AYA_LINK );
ns = IoCreateSymbolicLink( &AYAL ,&AYA );
pDriverObj->MajorFunction[IRP_MJ_CREATE] =
pDriverObj->MajorFunction[IRP_MJ_CLOSE] =
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AYA_Dispatch;
pDriverObj->DriverUnload = AYA_Unload;
return
ns;
}
NTSTATUS AYA_EnumHandle()
{
NTSTATUS ns = STATUS_SUCCESS;
ULONG ulSize;
PVOID pSysBuffer;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo;
SYSTEM_HANDLE_TABLE_ENTRY_INFO pSysHandleTEI;
OBJECT_BASIC_INFORMATION BasicInfo;
PKOBJECT_NAME_INFORMATION pNameInfo;
POBJECT_TYPE_INFORMATION pTypeInfo;
OBJECT_ATTRIBUTES oa;
ULONG ulProcessID;
HANDLE hProcess;
HANDLE hHandle;
HANDLE hDupObj;
CLIENT_ID cid;
ULONG i;
ulSize = 100;
do
{
pSysBuffer = ExAllocatePoolWithTag( PagedPool ,ulSize ,
'A0'
);
ns = ZwQuerySystemInformation( SystemHandleInformation ,pSysBuffer ,ulSize ,NULL );
ulSize *= 2;
if
( !NT_SUCCESS( ns ) )
{
ExFreePool( pSysBuffer );
}
}
while
( !NT_SUCCESS( ns ) );
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION)pSysBuffer;
for
( i = 0 ;i < pSysHandleInfo->NumberOfHandles ;i++ )
{
pSysHandleTEI = pSysHandleInfo->Handles[i];
if
( pSysHandleTEI.ObjectTypeIndex != OB_TYPE_PROCESS )
{
continue
;
}
ulProcessID = (ULONG)pSysHandleTEI.UniqueProcessId;
cid.UniqueProcess = (HANDLE)ulProcessID;
cid.UniqueThread = (HANDLE)0;
hHandle = (HANDLE)pSysHandleTEI.HandleValue;
InitializeObjectAttributes( &oa ,NULL ,0 ,NULL ,NULL );
ns = ZwOpenProcess( &hProcess ,PROCESS_DUP_HANDLE ,&oa ,&cid );
if
( !NT_SUCCESS( ns ) )
{
KdPrint((
"ZwOpenProcess : Fail "
));
break
;
}
ns = ZwDuplicateObject( hProcess ,hHandle ,NtCurrentProcess() ,&hDupObj ,\
PROCESS_ALL_ACCESS ,0 ,DUPLICATE_SAME_ACCESS );
if
( !NT_SUCCESS( ns ) )
{
KdPrint((
"ZwDuplicateObject : Fail "
));
break
;
}
ZwQueryObject( hDupObj ,ObjectBasicInformation ,&BasicInfo ,\
sizeof( OBJECT_BASIC_INFORMATION ) ,NULL );
pNameInfo = ExAllocatePoolWithTag( PagedPool ,BasicInfo.NameInformationLength ,
'A1'
);
RtlZeroMemory( pNameInfo ,BasicInfo.NameInformationLength );
ZwQueryObject( hDupObj ,ObjectNameInformation ,pNameInfo ,\
BasicInfo.NameInformationLength ,NULL );
pTypeInfo = ExAllocatePoolWithTag( PagedPool ,BasicInfo.TypeInformationLength ,
'A2'
);
RtlZeroMemory( pTypeInfo ,BasicInfo.TypeInformationLength );
ZwQueryObject( hDupObj ,ObjectTypeInformation ,pTypeInfo ,\
BasicInfo.TypeInformationLength ,NULL );
KdPrint((
"NAME:%wZ\t\t\tTYPE:%wZ\n"
,&(pNameInfo->Name) ,&(pTypeInfo->TypeName) ));
ExFreePool( pNameInfo );
ExFreePool( pTypeInfo );
}
ZwClose( hDupObj );
ZwClose( hProcess );
ZwClose( hHandle );
ExFreePool( pSysBuffer );
if
( !NT_SUCCESS( ns ) )
{
return
STATUS_UNSUCCESSFUL;
}
return
ns;
}