如果文件被占坑,使用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 );