如果文件被占坑,使用FILE_READ_ATTRIBUTES权限应该能打开
xp:
PEPROCESS->NT路径->FILE HANDLE->FILE OBJECT->DOS路径
BOOLEAN PsGetDosName(PEPROCESS ProcessObject, PUNICODE_STRING *DosName)
{
BOOLEAN bRet = FALSE;
KPROCESSOR_MODE PreviousMode;
ULONG HandleExtension;
HANDLE ProcessHandle;
PreviousMode = PsGetCurrentThreadPreviousMode();
HandleExtension = (PreviousMode == KernelMode ? OBJ_KERNEL_HANDLE : 0);
if (NT_SUCCESS(ObOpenObjectByPointer(ProcessObject, HandleExtension, NULL, PROCESS_QUERY_INFORMATION, *PsProcessType, PreviousMode, &ProcessHandle)))
{
PVOID lpBuffer = NULL;
ULONG cbBuffer = 0;
if (ZwQueryInformationProcess(ProcessHandle, ProcessImageFileName, lpBuffer, cbBuffer, &cbBuffer) == STATUS_INFO_LENGTH_MISMATCH)
{
if (lpBuffer = ExAllocatePoolWithTag(PagedPool, cbBuffer, 0))
{
if (NT_SUCCESS(ZwQueryInformationProcess(ProcessHandle, ProcessImageFileName, lpBuffer, cbBuffer, &cbBuffer)))
{
HANDLE hFile;
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK sb;
InitializeObjectAttributes(&oa, (PUNICODE_STRING)lpBuffer, OBJ_CASE_INSENSITIVE|HandleExtension, NULL, NULL);
if (NT_SUCCESS(ZwOpenFile(&hFile, FILE_READ_ATTRIBUTES|SYNCHRONIZE, &oa, &sb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT)))
{
PFILE_OBJECT FileObject;
if (NT_SUCCESS(ObReferenceObjectByHandle(hFile, FILE_READ_ATTRIBUTES, *IoFileObjectType, PreviousMode, (PVOID*)&FileObject, NULL)))
{
POBJECT_NAME_INFORMATION lpName;
if (NT_SUCCESS(IoQueryFileDosDeviceName(FileObject, &lpName)))
{
*DosName = (UNICODE_STRING *)lpName;
bRet = TRUE;
}
ObDereferenceObject(FileObject);
}
ZwClose(hFile);
}
}
ExFreePool(lpBuffer);
}
}
ZwClose(ProcessHandle);
}
return bRet;
}
使用方法:
PUNICODE_STRING FileName;
if (PsGetDosName(Process, &FileName))
{
ExFreePool(FileName);
}
上面的方法很麻烦,但这是我总结出最靠谱的方法,无硬编码。
如果是windows7以上的系统,则非常简单,两个函数就行了。
NTSTATUS
PsReferenceProcessFilePointer (
IN PEPROCESS Process,
OUT PVOID *pFilePointer
);
NTSTATUS
IoQueryFileDosDeviceName(
IN PFILE_OBJECT FileObject,
OUT POBJECT_NAME_INFORMATION *ObjectNameInformation
);