EPROCESS取进程全路径

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


你可能感兴趣的:(EPROCESS取进程全路径)