- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
前面说过使用一大堆函数获取全路径
PID->eprocess->KeStackAttachProcess->ZwQueryInformationProcess->rocessImageFileName->ZwCreateFile
->ObReferenceObjectByHandle->RtlVolumeDeviceToDosName
->ZwQueryInformationFile
code:
- NTKERNELAPI NTSTATUS
- PsLookupProcessByProcessId(
- IN HANDLE ProcessId,
- OUT PEPROCESS *Process
- );
- /*NTSTATUS
- IoQueryFileDosDeviceName(
- IN PFILE_OBJECT FileObject,
- OUT POBJECT_NAME_INFORMATION *ObjectNameInformation
- ); */
- NTSTATUS
- NTAPI
- ZwQueryInformationProcess(
- __in HANDLE ProcessHandle,
- __in PROCESSINFOCLASS ProcessInformationClass,
- __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
- __in ULONG ProcessInformationLength,
- __out_opt PULONG ReturnLength
- );
复制代码
- NTSTATUS GetProcessFullNameByPid(HANDLE nPid, PUNICODE_STRING FullPath)
- {
- HANDLE hFile = NULL;
- ULONG nNeedSize = 0;
- NTSTATUS nStatus = STATUS_SUCCESS;
- NTSTATUS nDeviceStatus = STATUS_DEVICE_DOES_NOT_EXIST;
- PEPROCESS Process = NULL;
- KAPC_STATE ApcState = {0};
- PVOID lpBuffer = NULL;
- OBJECT_ATTRIBUTES ObjectAttributes = {0};
- IO_STATUS_BLOCK IoStatus = {0};
- PFILE_OBJECT FileObject = NULL;
- PFILE_NAME_INFORMATION FileName = NULL;
- WCHAR FileBuffer[MAX_PATH] = {0};
- DECLARE_UNICODE_STRING_SIZE(ProcessPath,MAX_PATH);
- DECLARE_UNICODE_STRING_SIZE(DosDeviceName,MAX_PATH);
-
- PAGED_CODE();
- nStatus = PsLookupProcessByProcessId(nPid, &Process);
- if(NT_ERROR(nStatus))
- {
- KdPrint(("%s error PsLookupProcessByProcessId.\n",__FUNCTION__));
- return nStatus;
- }
- __try
- {
- KeStackAttachProcess(Process, &ApcState);
-
- nStatus = ZwQueryInformationProcess(
- NtCurrentProcess(),
- ProcessImageFileName,
- NULL,
- NULL,
- &nNeedSize
- );
- if (STATUS_INFO_LENGTH_MISMATCH != nStatus)
- {
- KdPrint(("%s NtQueryInformationProcess error.\n",__FUNCTION__));
- nStatus = STATUS_MEMORY_NOT_ALLOCATED;
- __leave;
- }
- lpBuffer = ExAllocatePoolWithTag(NonPagedPool, nNeedSize,'GetP');
- if (lpBuffer == NULL)
- {
- KdPrint(("%s ExAllocatePoolWithTag error.\n",__FUNCTION__));
- nStatus = STATUS_MEMORY_NOT_ALLOCATED;
- __leave;
- }
- nStatus = ZwQueryInformationProcess(
- NtCurrentProcess(),
- ProcessImageFileName,
- lpBuffer,
- nNeedSize,
- &nNeedSize
- );
- if (NT_ERROR(nStatus))
- {
- KdPrint(("%s NtQueryInformationProcess error2.\n",__FUNCTION__));
- __leave;
- }
- RtlCopyUnicodeString(&ProcessPath,(PUNICODE_STRING)lpBuffer);
- InitializeObjectAttributes(
- &ObjectAttributes,
- &ProcessPath,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL
- );
- nStatus = ZwCreateFile(
- &hFile,
- FILE_READ_ATTRIBUTES,
- &ObjectAttributes,
- &IoStatus,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE,
- NULL,
- 0
- );
- if (NT_ERROR(nStatus))
- {
- hFile = NULL;
- __leave;
- }
- nStatus = ObReferenceObjectByHandle(
- hFile,
- NULL,
- *IoFileObjectType,
- KernelMode,
- (PVOID*)&FileObject,
- NULL
- );
- if (NT_ERROR(nStatus))
- {
- FileObject = NULL;
- __leave;
- }
-
- FileName = (PFILE_NAME_INFORMATION)FileBuffer;
-
- nStatus = ZwQueryInformationFile(
- hFile,
- &IoStatus,
- FileName,
- sizeof(WCHAR)*MAX_PATH,
- FileNameInformation
- );
- if (NT_ERROR(nStatus))
- {
- __leave;
- }
- if (FileObject->DeviceObject == NULL)
- {
- nDeviceStatus = STATUS_DEVICE_DOES_NOT_EXIST;
- __leave;
- }
- nDeviceStatus = RtlVolumeDeviceToDosName(FileObject->DeviceObject,&DosDeviceName);
- }
- __finally
- {
- if (NULL != FileObject)
- {
- ObDereferenceObject(FileObject);
- }
- if (NULL != hFile)
- {
- ZwClose(hFile);
- }
- if (NULL != lpBuffer)
- {
- ExFreePool(lpBuffer);
- }
- KeUnstackDetachProcess(&ApcState);
- }
- if (NT_SUCCESS(nStatus))
- {
- RtlInitUnicodeString(&ProcessPath,FileName->FileName);
- if (NT_SUCCESS(nDeviceStatus))
- {
- RtlCopyUnicodeString(FullPath,&DosDeviceName);
- RtlUnicodeStringCat(FullPath,&ProcessPath);
- }
- else
- {
- RtlCopyUnicodeString(FullPath,&ProcessPath);
- }
- }
- return nStatus;
- }
复制代码 这实在是太麻烦了
其实要获得全路径 就是要获得FIleObject 而FIleObject就在EPROCESS结构下 详细继续读下去
在NT5上PsReferenceProcessFilePointer没有导出,需要自己实现
在WRK中:
- NTSTATUS NTAPI PsReferenceProcessFilePointer
- (
- IN PEPROCESS Process,
- OUT PFILE_OBJECT * FileObject
- )
- {
- PSECTION Section;
- PAGED_CODE();
- /* Lock the process */
- ExAcquireRundownProtection(&Process->RundownProtect);
- /* Get the section */
- Section = Process->SectionObject;
- if (Section)
- {
- /* Get the file object and reference it */
- *FileObject = MmGetFileObjectForSection((PVOID)Section);
- ObReferenceObject(*FileObject);
- }
- /* Release the protection */
- ExReleaseRundownProtection(&Process->RundownProtect);
- /* Return status */
- return Section ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
- }
- PFILE_OBJECT NTAPI MmGetFileObjectForSection
- (
- IN PVOID Section
- )
- {
- PSECTION_OBJECT Section;
- ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
- ASSERT(SectionObject != NULL);
- /* Check if it's an ARM3, or ReactOS section */
- if (MiIsRosSectionObject(SectionObject) == FALSE)
- {
- /* Return the file pointer stored in the control area */
- Section = SectionObject;
- return Section->Segment->ControlArea->FilePointer;
- }
- /* Return the file object */
- return ((PROS_SECTION_OBJECT)SectionObject)->FileObject;
- }
复制代码 FileObject要这么获得:Process->SectionObject->Segment->ControlArea->FilePointer
大概需要4个硬编码
XP:
code:
除了这个以外:还有一个
Process->SeAuditProcessCreationInfo.ImageFileName->Name
在WRK中可以看到
这说明从这个路径可能是不存在的
- NTSTATUS
- SeLocateProcessImageName(
- __in PEPROCESS Process,
- __deref_out PUNICODE_STRING *pImageFileName
- )
- /*++
- Routine Description
-
- This routine returns the ImageFileName information from the process, if available. This is a "lazy evaluation" wrapper
- around SeInitializeProcessAuditName. If the image file name information has already been computed, then this call simply
- allocates and returns a UNICODE_STRING with this information. Otherwise, the function determines the name, stores the name in the
- EPROCESS structure, and then allocates and returns a UNICODE_STRING. Caller must free the memory returned in pImageFileName.
-
- Arguments
- Process - process for which to acquire the name
-
- pImageFileName - output parameter to return name to caller
-
- Return Value
- NTSTATUS.
-
- --*/
- {
- NTSTATUS Status = STATUS_SUCCESS;
- PVOID FilePointer = NULL;
- PVOID PreviousValue = NULL;
- POBJECT_NAME_INFORMATION pProcessImageName = NULL;
- PUNICODE_STRING pTempUS = NULL;
- ULONG NameLength = 0;
- PAGED_CODE();
- *pImageFileName = NULL;
-
- if (NULL == Process->SeAuditProcessCreationInfo.ImageFileName) {
- //
- // The name has not been predetermined. We must determine the process name. First, reference the
- // PFILE_OBJECT and lookup the name. Then again check the process image name pointer against NULL.
- // Finally, set the name.
- //
- Status = PsReferenceProcessFilePointer( Process, &FilePointer );
-
- if (NT_SUCCESS(Status)) {
- //
- // Get the process name information.
- //
- Status = SeInitializeProcessAuditName(
- FilePointer,
- TRUE, // skip audit policy
- &pProcessImageName // to be allocated in nonpaged pool
- );
- if (NT_SUCCESS(Status)) {
- //
- // Only use the pProcessImageName if the field in the process is currently NULL.
- //
- PreviousValue = InterlockedCompareExchangePointer(
- (PVOID *) &Process->SeAuditProcessCreationInfo.ImageFileName,
- (PVOID) pProcessImageName,
- (PVOID) NULL
- );
-
- if (NULL != PreviousValue) {
- ExFreePool(pProcessImageName); // free what we caused to be allocated.
- }
- }
- ObDereferenceObject( FilePointer );
- }
- }
-
-
- if (NT_SUCCESS(Status)) {
-
- //
- // Allocate space for a buffer to contain the name for returning to the caller.
- //
- NameLength = sizeof(UNICODE_STRING) + Process->SeAuditProcessCreationInfo.ImageFileName->Name.MaximumLength;
- pTempUS = ExAllocatePoolWithTag( NonPagedPool, NameLength, 'aPeS' );
- if (NULL != pTempUS) {
- RtlCopyMemory(
- pTempUS,
- &Process->SeAuditProcessCreationInfo.ImageFileName->Name,
- NameLength
- );
- pTempUS->Buffer = (PWSTR)(((PUCHAR) pTempUS) + sizeof(UNICODE_STRING));
- *pImageFileName = pTempUS;
- } else {
-
- Status = STATUS_NO_MEMORY;
- }
- }
- return Status;
- }
复制代码 我自己实现了下 在win7 x86下效果还是可以的 不过使用了硬编码,推荐还是在NT5上使用(NT6很简单)
- PUNICODE_STRING GetSeLocateProcessImageName(PEPROCESS Process,PUNICODE_STRING *pImageFileName)
- {
- POBJECT_NAME_INFORMATION pProcessImageName = NULL;
- PUNICODE_STRING pTempUS = NULL;
- ULONG NameLength = 0;
- //Process->SeAuditProcessCreationInfo.ImageFileName->Name
- //win7 x86 offset = 0x1ec
- //if (NULL == Process->SeAuditProcessCreationInfo.ImageFileName)
- pProcessImageName = (POBJECT_NAME_INFORMATION)(*(ULONG*)((ULONG)Process + 0x1ec));
- if(pProcessImageName == NULL)
- {
- DbgPrint("Process->SeAuditProcessCreationInfo.ImageFileName == NULL \n");
- return NULL;
- }
- else
- {
- NameLength = sizeof(UNICODE_STRING) + pProcessImageName->Name.MaximumLength;
- pTempUS = ExAllocatePoolWithTag( NonPagedPool, NameLength, 'aPeS' );
- if (NULL != pTempUS) {
- RtlCopyMemory(
- pTempUS,
- &pProcessImageName->Name,
- NameLength
- );
- pTempUS->Buffer = (PWSTR)(((PUCHAR) pTempUS) + sizeof(UNICODE_STRING));
- *pImageFileName = pTempUS;
- DbgPrint("Path:%wZ\n",&pProcessImageName->Name);
- return *pImageFileName;
- }
- return NULL;
- }
- }
复制代码
而NT6就很简单了
PsReferenceProcessFilePointe已经被导出了
那么直接使用
PsReferenceProcessFilePointe +IoQueryFileDosDeviceName就可以了
- PUNICODE_STRING PsGetProcessFullName(PEPROCESS pTargetProcess)
- {
- PFILE_OBJECT pFileObject=NULL;
- POBJECT_NAME_INFORMATION pObjectNameInfo=NULL;
- if(!NT_SUCCESS(PsReferenceProcessFilePointer(pTargetProcess,&pFileObject)))
- return NULL;
- if(!NT_SUCCESS(IoQueryFileDosDeviceName(pFileObject,&pObjectNameInfo)))
- return NULL;
- return &(pObjectNameInfo->Name);//尚未释放内存 以及 ObDereferenceObject
- }
复制代码
除了这些以前还有一些路径存在PEB里 如果在x64的系统中 还得看是PEB32还是PEB64 虽然可以使用PsGetProcessWow64Process来判断是不是64进程
但这些数据在r3就可以直接被修改了 所以不太建议使用
PEB->rocessParameters->ImagePathName
PEB->rocessParameters->CommandLine
PEB->rocessParameters->WindowTitle
PEB->Ldr->InLoadOrderLinks->FullDllName
PEB->Ldr->InMemoryOrderLinks->FullDllName
大家看看黑客防线里面的《伪造进程初探》和获取进程完整路径方法小结.pdf
另外一个博主写的也是不错的
42969803 //EPROCESS取进程全路径
43638651 //EPROCESS取进程全路径(xp) |
|