• 驱动层得到进程的完整路径


       在得到进程EProcess之后,对于进程完整路径的获得一般有两种方法,一种是访问的进程的PEB结构,在PEB结构中保存有进程的完整路径,另一种方法就是采用访问_FILE_OBJECT的方法。

      访问PEB的方法便存在线程靠挂的问题,因为运行于Ring0层的线程是无法去访问用户地址空间的,需要将线程暂时靠挂到目标呢进程,进而去访问进程的PEB结构。我一般都采用的访问_FILE_OBJECT的方法,避免了线程的靠挂问题,而且访问peb的方法会存在一个问题:如果想要进行进程拦截,在进程未启动之前就阻止进程的启动,此时进程空间还未开辟,peb结构都不存在,只能去访问exe文件在ring0层的文件对象,通过文件对象来获得进程的完整路径。

      进程靠挂函数原型

    1 VOID KeStackAttachProcess (
    2     PKPROCESS  Process,
    3     PRKAPC_STATE  ApcState
    4     );

    访问目标进程的用户地址空间之后返回ring0运行调用函数

    VOID KeUnstackDetachProcess(
       PRKAPC_STATE  ApcState
        );

    kd> dt _eprocess

    +0x1b0 Peb              : Ptr32 _PEB    //X86 Peb在EProcess中的偏移量

    kd> dt _peb

    +0x00c Ldr              : Ptr32 _PEB_LDR_DATA        ;进程加载的模块链表

    关于进程加载模块链表是有三条链表

    InLoadOrderModuleList    //模块的加载顺序

    InMemoryOrderModuleList   // 模块在内存中的顺序

    InInitializationOrderModuleList   // 模块的初始化顺序

    进程的第一模块就是exe文件,对于exe的路径就是取InLoadOrderModuleList 中的第一模块的FullDllName。

    第二种方法,用_FILE_OBJECT 的方法

    以下为Windbg的调试过程,在虚拟机中打开calc.exe然后获得calc.exe的完整路径

    Win7 X64

    1 kd> !process 0 0
    2 
    3 PROCESS fffffa801a619b30
    4     SessionId: 1  Cid: 0b10    Peb: 7fffffd6000  ParentCid: 05fc
    5     DirBase: 5f017000  ObjectTable: fffff8a00296ac00  HandleCount:  79.
    6     Image: calc.exe

    kd> dt _eprocess fffffa801a619b30

    +0x268 SectionObject    : 0xfffff8a0`01ba1f30 Void


    kd> dt _section_object 0xfffff8a0`01ba1f30
    nt!_SECTION_OBJECT
    +0x000 StartingVa : (null)
    +0x008 EndingVa : 0xfffff880`03bd4ba8 Void
    +0x010 Parent : 0xfffff880`03bd4b90 Void
    +0x018 LeftChild : (null)
    +0x020 RightChild : 0xfffffa80`19e84300 Void
    +0x028 Segment : 0xfffff8a0`01b19850 _SEGMENT_OBJECT


      

    kd> dt _segment 0xfffff8a0`01b19850
    nt!_SEGMENT
    +0x000 ControlArea : 0xfffffa80`1a687d30 _CONTROL_AREA
    +0x008 TotalNumberOfPtes : 0xe3
    +0x00c SegmentFlags : _SEGMENT_FLAGS
    +0x010 NumberOfCommittedPages : 0
    +0x018 SizeOfSegment : 0xe3000
    +0x020 ExtendInfo : 0x00000000`ffbf0000 _MMEXTEND_INFO
    +0x020 BasedAddress : 0x00000000`ffbf0000 Void
    +0x028 SegmentLock : _EX_PUSH_LOCK
    +0x030 u1 : <unnamed-tag>
    +0x038 u2 : <unnamed-tag>
    +0x040 PrototypePte : 0xfffff8a0`01b19898 _MMPTE
    +0x048 ThePtes : [1] _MMPTE

    kd> dt _CONTROL_AREA 0xfffffa80`1a687d30
    nt!_CONTROL_AREA
    +0x000 Segment : 0xfffff8a0`01b19850 _SEGMENT
    +0x008 DereferenceList : _LIST_ENTRY [ 0x00000000`00000000 - 0xfffffa80`1a8a1018 ]
    +0x018 NumberOfSectionReferences : 1
    +0x020 NumberOfPfnReferences : 0x97
    +0x028 NumberOfMappedViews : 1
    +0x030 NumberOfUserReferences : 2
    +0x038 u : <unnamed-tag>
    +0x03c FlushInProgressCount : 0
    +0x040 FilePointer : _EX_FAST_REF       //与X86的不同,X86下FilePointer的类型为_FILE_OBJECT,X64加了一层封装

    kd> dt _EX_FAST_REF 0xfffffa80`1a687d30+0x040
    nt!_EX_FAST_REF
    +0x000 Object : 0xfffffa80`1a685073 Void         //真正的_FILE_OBJECT 最后一位要进行清0操作,  文件对象的最后一位必然为0
    +0x000 RefCnt : 0y0011
    +0x000 Value : 0xfffffa80`1a685073

    kd> dt _File_object 0xfffffa80`1a685070 //_File_Object 最后一位清0
    nt!_FILE_OBJECT
    +0x000 Type : 0n5
    +0x002 Size : 0n216
    +0x008 DeviceObject : 0xfffffa80`19376530 _DEVICE_OBJECT
    +0x010 Vpb : 0xfffffa80`19376470 _VPB
    +0x018 FsContext : 0xfffff8a0`000f5140 Void
    +0x020 FsContext2 : 0xfffff8a0`019715d0 Void
    +0x028 SectionObjectPointer : 0xfffffa80`19e5ec88 _SECTION_OBJECT_POINTERS
    +0x030 PrivateCacheMap : (null)
    +0x038 FinalStatus : 0n0
    +0x040 RelatedFileObject : (null)
    +0x048 LockOperation : 0 ''
    +0x049 DeletePending : 0 ''
    +0x04a ReadAccess : 0x1 ''
    +0x04b WriteAccess : 0 ''
    +0x04c DeleteAccess : 0 ''
    +0x04d SharedRead : 0x1 ''
    +0x04e SharedWrite : 0 ''
    +0x04f SharedDelete : 0x1 ''
    +0x050 Flags : 0x44042
    +0x058 FileName : _UNICODE_STRING "WindowsSystem32calc.exe"                                    //完整路径
    +0x068 CurrentByteOffset : _LARGE_INTEGER 0x0
    +0x070 Waiters : 0
    +0x074 Busy : 0
    +0x078 LastLock : (null)
    +0x080 Lock : _KEVENT
    +0x098 Event : _KEVENT
    +0x0b0 CompletionContext : (null)
    +0x0b8 IrpListLock : 0
    +0x0c0 IrpList : _LIST_ENTRY [ 0xfffffa80`1a685130 - 0xfffffa80`1a685130 ]
    +0x0d0 FileObjectExtension : (null)

    WinXP X86

    kd> !process 0 0

    PROCESS 8971d6f8 SessionId: 0 Cid: 0378 Peb: 7ffdc000 ParentCid: 0664
    DirBase: 0f8c02a0 ObjectTable: e23027a8 HandleCount: 44.
    Image: calc.exe


    kd> dt _eprocess 8971d6f8

    +0x138 SectionObject : 0xe22963d0 Void


    kd> dt _section_object 0xe22963d0
    nt!_SECTION_OBJECT
    +0x000 StartingVa : (null)
    +0x004 EndingVa : (null)
    +0x008 Parent : (null)
    +0x00c LeftChild : (null)
    +0x010 RightChild : (null)
    +0x014 Segment : 0xe18e4820 _SEGMENT_OBJECT

    kd> dt _segment 0xe18e4820
    nt!_SEGMENT
    +0x000 ControlArea : 0x89769478 _CONTROL_AREA
    +0x004 TotalNumberOfPtes : 0x1f
    +0x008 NonExtendedPtes : 0x1f
    +0x00c WritableUserReferences : 0
    +0x010 SizeOfSegment : 0x1f000
    +0x018 SegmentPteTemplate : _MMPTE
    +0x020 NumberOfCommittedPages : 0
    +0x024 ExtendInfo : (null)
    +0x028 SystemImageBase : (null)
    +0x02c BasedAddress : 0x01000000 Void
    +0x030 u1 : __unnamed
    +0x034 u2 : __unnamed
    +0x038 PrototypePte : 0xe18e4860 _MMPTE
    +0x040 ThePtes : [1] _MMPTE


    kd> dt _CONTROL_AREA 0x89769478
    nt!_CONTROL_AREA
    +0x000 Segment : 0xe18e4820 _SEGMENT
    +0x004 DereferenceList : _LIST_ENTRY [ 0x0 - 0x0 ]
    +0x00c NumberOfSectionReferences : 1
    +0x010 NumberOfPfnReferences : 0x1d
    +0x014 NumberOfMappedViews : 1
    +0x018 NumberOfSubsections : 4
    +0x01a FlushInProgressCount : 0
    +0x01c NumberOfUserReferences : 2
    +0x020 u : __unnamed
    +0x024 FilePointer : 0x8958a9b0 _FILE_OBJECT
    +0x028 WaitingForDeletion : (null)
    +0x02c ModifiedWriteCount : 0
    +0x02e NumberOfSystemCacheViews : 0


    kd> dt _FILE_OBJECT 0x8958a9b0
    nt!_FILE_OBJECT
    +0x000 Type : 0n5
    +0x002 Size : 0n112
    +0x004 DeviceObject : 0x899ab900 _DEVICE_OBJECT
    +0x008 Vpb : 0x8994c1d8 _VPB                               //卷参数块,由此得到所属卷设备,即盘符
    +0x00c FsContext : 0xe228f710 Void
    +0x010 FsContext2 : 0xe1f5ea90 Void
    +0x014 SectionObjectPointer : 0x894bbbe4 _SECTION_OBJECT_POINTERS
    +0x018 PrivateCacheMap : (null)
    +0x01c FinalStatus : 0n0
    +0x020 RelatedFileObject : (null)
    +0x024 LockOperation : 0 ''
    +0x025 DeletePending : 0 ''
    +0x026 ReadAccess : 0x1 ''
    +0x027 WriteAccess : 0 ''
    +0x028 DeleteAccess : 0 ''
    +0x029 SharedRead : 0x1 ''
    +0x02a SharedWrite : 0 ''
    +0x02b SharedDelete : 0x1 ''
    +0x02c Flags : 0x44042
    +0x030 FileName : _UNICODE_STRING "WINDOWSsystem32calc.exe"                            //完整路径
    +0x038 CurrentByteOffset : _LARGE_INTEGER 0x0
    +0x040 Waiters : 0
    +0x044 Busy : 0
    +0x048 LastLock : (null)
    +0x04c Lock : _KEVENT
    +0x05c Event : _KEVENT
    +0x06c CompletionContext : (null)

     结构体的定义

    ypedef struct _CONTROL_AREA64
    {
        PVOID64 Segment;
        PVOID64 p1;
        PVOID64 p2;
        ULONG64 NumberOfSectionReferences;
        ULONG64 NumberOfPfnReferences;
        ULONG64 NumberOfMappedViews;
        ULONG64 NumberOfUserReferences;
        union
        {
            ULONG LongFlags;
            ULONG Flags;
        } u;
        PVOID64 FilePointer;
    } CONTROL_AREA64, *PCONTROL_AREA64;
    
    typedef struct _CONTROL_AREA
    {
        PVOID Segment;
        LIST_ENTRY DereferenceList;
        ULONG NumberOfSectionReferences;
        ULONG NumberOfPfnReferences;
        ULONG NumberOfMappedViews;
        ULONG NumberOfSystemCacheViews;
        ULONG NumberOfUserReferences;
        union
        {
            ULONG LongFlags;
            ULONG Flags;
        } u;
        PFILE_OBJECT FilePointer;
    } CONTROL_AREA, *PCONTROL_AREA;
    
    
    typedef struct _SEGMENT64
    {
        PVOID64 ControlArea;
        ULONG TotalNumberOfPtes;
        ULONG NonExtendedPtes;
        ULONG Spare0;
    }SEGMENT64,*PSEGMENT64;
    
    typedef struct _SEGMENT
    {
        struct _CONTROL_AREA *ControlArea;
        ULONG TotalNumberOfPtes;
        ULONG NonExtendedPtes;
        ULONG Spare0;
    } SEGMENT, *PSEGMENT;
    
    
    typedef struct _SECTION_OBJECT
    {
        PVOID StartingVa;
        PVOID EndingVa;
        PVOID Parent;
        PVOID LeftChild;
        PVOID RightChild;
        PSEGMENT Segment;
    } SECTION_OBJECT, *PSECTION_OBJECT;
    
    
    typedef struct _SECTION_OBJECT64
    {
        PVOID64 StartingVa;
        PVOID64 EndingVa;
        PVOID64 Parent;
        PVOID64 LeftChild;
        PVOID64 RightChild;
        PVOID64 Segment;
    } SECTION_OBJECT64, *PSECTION_OBJECT64;
    BOOLEAN
    GetProcessPathBySectionObject(ULONG_PTR ulProcessID,WCHAR* wzProcessPath)
    {
        PEPROCESS         EProcess = NULL;
        PSECTION_OBJECT   SectionObject   = NULL;
        PSECTION_OBJECT64 SectionObject64 = NULL;
        PSEGMENT        Segment   = NULL;
        PSEGMENT64      Segment64 = NULL;
        PCONTROL_AREA   ControlArea = NULL;
        PCONTROL_AREA64 ControlArea64 = NULL;
        PFILE_OBJECT    FileObject  = NULL;
        BOOLEAN         bGetPath = FALSE;
    
        if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)ulProcessID, &EProcess)))
        {
    
            switch(WinVersion)
            {
            case WINDOWS_XP:   //x86 XP sp3
                {
                    SectionObjectOfEProcess  = 0x138;
                    if (SectionObjectOfEProcess!=0&&MmIsAddressValid((PVOID)((ULONG_PTR)EProcess + SectionObjectOfEProcess)))
                    {
                        SectionObject = *(PSECTION_OBJECT*)((ULONG_PTR)EProcess + SectionObjectOfEProcess);
                        if (SectionObject && MmIsAddressValid(SectionObject))
                        {
                            Segment = (PSEGMENT)SectionObject->Segment;
                            if (Segment && MmIsAddressValid(Segment))
                            {
                                ControlArea = Segment->ControlArea;
                                if (ControlArea && MmIsAddressValid(ControlArea))
                                {
                                    FileObject = ControlArea->FilePointer;
                                    if (FileObject&&MmIsAddressValid(FileObject))
                                    {
                                        bGetPath = GetPathByFileObject(FileObject, wzProcessPath);
                                        if (!bGetPath)
                                        {
                                            DbgPrint("SectionObject: 0x%08X, FileObject: 0x%08X
    ", SectionObject, FileObject);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
    
            case WINDOWS_7:  //Win 7 x64 sp1
                {    
                    SectionObjectOfEProcess = 0x268;           
                    if (SectionObjectOfEProcess!=0&&MmIsAddressValid((PVOID)((ULONG_PTR)EProcess + SectionObjectOfEProcess)))
                    {
                        SectionObject64 = *(PSECTION_OBJECT64*)((ULONG_PTR)EProcess + SectionObjectOfEProcess);
                        if (SectionObject64 && MmIsAddressValid(SectionObject64))
                        {
    
                            Segment64 = (PSEGMENT64)(SectionObject64->Segment);
                            if (Segment64 && MmIsAddressValid(Segment64))
                            {
                                ControlArea64 = (PCONTROL_AREA64)Segment64->ControlArea;
                                if (ControlArea64 && MmIsAddressValid(ControlArea64))
                                {
                                    FileObject = (PFILE_OBJECT)ControlArea64->FilePointer;
                                    if (FileObject&&MmIsAddressValid(FileObject))
                                    {
                                        FileObject = (PFILE_OBJECT)((ULONG_PTR)FileObject & 0xFFFFFFFFFFFFFFF0);
                                        bGetPath = GetPathByFileObject(FileObject, wzProcessPath);
                                        if (!bGetPath)
                                        {
                                            DbgPrint("SectionObject: 0x%08X, FileObject: 0x%08X
    ", SectionObject, FileObject);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
            }        
        }
        if (bGetPath==FALSE)
        {
            wcscpy(wzProcessPath,L"Unknow");
        }
    
        return bGetPath;    
    
    }

    获得文件对象以后,获得完整的路径

    //传入文件对象,返回完整路径

      1 BOOLEAN GetPathByFileObject(PFILE_OBJECT FileObject, WCHAR* wzPath)
      2 {
      3     BOOLEAN bGetPath = FALSE;
      4     CHAR szIoQueryFileDosDeviceName[] = "IoQueryFileDosDeviceName";
      5     CHAR szIoVolumeDeviceToDosName[] = "IoVolumeDeviceToDosName";
      6     CHAR szRtlVolumeDeviceToDosName[] = "RtlVolumeDeviceToDosName";
      7 
      8     POBJECT_NAME_INFORMATION ObjectNameInformation = NULL;
      9     __try
     10     {
     11         if (FileObject && MmIsAddressValid(FileObject) && wzPath)
     12         {
     13         
     14             if (NT_SUCCESS(IoQueryFileDosDeviceName(FileObject,&ObjectNameInformation)))   //注意该函数调用后要释放内存
     15             {
     16                 wcsncpy(wzPath,ObjectNameInformation->Name.Buffer,ObjectNameInformation->Name.Length);
     17 
     18                 bGetPath = TRUE;
     19 
     20                 ExFreePool(ObjectNameInformation);
     21             }
     22             
     23             
     24             if (!bGetPath)
     25             {
     26             
     27                 if (IoVolumeDeviceToDosName||RtlVolumeDeviceToDosName)
     28                 {
     29                     NTSTATUS  Status = STATUS_UNSUCCESSFUL;
     30                     ULONG_PTR ulRet= 0;
     31                     PVOID     Buffer = ExAllocatePool(PagedPool,0x1000);
     32 
     33                     if (Buffer)
     34                     {
     35                         // ObQueryNameString : DeviceHarddiskVolume1Program FilesVMwareVMware ToolsVMwareTray.exe
     36                         memset(Buffer, 0, 0x1000);
     37                         Status = ObQueryNameString(FileObject, (POBJECT_NAME_INFORMATION)Buffer, 0x1000, &ulRet);
     38                         if (NT_SUCCESS(Status))
     39                         {
     40                             POBJECT_NAME_INFORMATION Temp = (POBJECT_NAME_INFORMATION)Buffer;
     41                         
     42                             WCHAR szHarddiskVolume[100] = L"\Device\HarddiskVolume";
     43 
     44                             if (Temp->Name.Buffer!=NULL)
     45                             {
     46                                 if (Temp->Name.Length / sizeof(WCHAR) > wcslen(szHarddiskVolume) &&
     47                                     !_wcsnicmp(Temp->Name.Buffer, szHarddiskVolume, wcslen(szHarddiskVolume)))
     48                                 {
     49                                     // 如果是以 "\Device\HarddiskVolume" 这样的形式存在的,那么再查询其卷名。
     50                                     UNICODE_STRING uniDosName;
     51 
     52                                     if (NT_SUCCESS(IoVolumeDeviceToDosName(FileObject->DeviceObject, &uniDosName)))
     53                                     {
     54                                         if (uniDosName.Buffer!=NULL)
     55                                         {
     56                                         
     57                                             wcsncpy(wzPath, uniDosName.Buffer, uniDosName.Length);
     58                                             wcsncat(wzPath, Temp->Name.Buffer + wcslen(szHarddiskVolume) + 1, Temp->Name.Length - (wcslen(szHarddiskVolume) + 1));
     59                                             bGetPath = TRUE;
     60                                         }    
     61 
     62                                         ExFreePool(uniDosName.Buffer);
     63                                     }
     64 
     65                                     else if (NT_SUCCESS(RtlVolumeDeviceToDosName(FileObject->DeviceObject, &uniDosName)))
     66                                     {
     67                                         if (uniDosName.Buffer!=NULL)
     68                                         {
     69 
     70                                             wcsncpy(wzPath, uniDosName.Buffer, uniDosName.Length);
     71                                             wcsncat(wzPath, Temp->Name.Buffer + wcslen(szHarddiskVolume) + 1, Temp->Name.Length - (wcslen(szHarddiskVolume) + 1));
     72                                             bGetPath = TRUE;
     73                                         }    
     74 
     75                                         ExFreePool(uniDosName.Buffer);
     76                                     }
     77                                     
     78                                 }
     79                                 else
     80                                 {
     81                                     // 如果不是以 "\Device\HarddiskVolume" 这样的形式开头的,那么直接复制名称。
     82                                     
     83                                     wcsncpy(wzPath, Temp->Name.Buffer, Temp->Name.Length);
     84                                     bGetPath = TRUE;
     85                                 }
     86                             }
     87                         }
     88 
     89                         ExFreePool(Buffer);
     90                     }
     91                 }
     92             }
     93         }
     94     }
     95     __except(1)
     96     {
     97         DbgPrint("GetPathByFileObject Catch __Except
    ");
     98         bGetPath = FALSE;
     99     }
    100 
    101     return bGetPath;
    102 }
  • 相关阅读:
    解决问题方法论
    mac os x命令行查找文件
    Ubuntu 更改文件夹权限及chmod详细用法
    Unable to mount the CD/DVD image virtualbox解决方法
    macbook air电池保养方法
    安装mac os x时about a second remaining解决方法
    No qualifying bean of type 'org.springframework.scheduling.TaskScheduler' available
    java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver
    java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)解决方案
    使用springboot和easypoi进行的数据导出的小案例
  • 原文地址:https://www.cnblogs.com/lanrenxinxin/p/4388935.html
Copyright © 2020-2023  润新知