YOUBADBAD 发表于 2018-1-12 09:13:54

关于进程名的交流(直接使用API取完整进程路径)

本帖最后由 YOUBADBAD 于 2018-1-12 09:48 编辑

一般我们获取进程名都是用 “PsGetProcessImageFileName” 取到 16个字节 然鹅 今天突然用了一下这个函数 "SeLocateProcessImageName"
发现,PsGetProcessImageFileName(eproc)的时候,可以打印System,
而用 SeLocateProcessImageName(eproc,&UsImageName)的时候,取到别的程序全路径是正常的,而system的值是Null。

一开始是以为代码出了问题
后面通过windbg打印了才发现
人家本来就是空的

当然了,这个发现或许并没啥卵用,目的是发个贴交流心得

Tesla.Angela 发表于 2018-1-12 09:40:09

经研究,该函数在NT5时代就已经存在,从VISTA-6000开始导出。
数据从EPROCESS->SeAuditProcessCreationInfo.ImageFileName->Name里取出。NTSTATUS SeLocateProcessImageName
(
    __in PEPROCESS Process,
    __deref_out PUNICODE_STRING *pImageFileName
)
{
        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;
}在对路径可靠性要求不高的情况下可以直接使用。

gfw 发表于 2018-2-9 21:05:54

好方法
页: [1]
查看完整版本: 关于进程名的交流(直接使用API取完整进程路径)