首页
社区
课程
招聘
[笔记]Hook NtMapViewOfSection 获取加载模块的全路径
发表于: 2015-7-10 14:39 5691

[笔记]Hook NtMapViewOfSection 获取加载模块的全路径

2015-7-10 14:39
5691
Hook NtMapViewOfSection 获取加载模块的全路径

实际使用中,LoadImageNotifyRoutine得到加载模块的路径是不包含盘符的;
原因很清楚,IDA ntoskrnl NtMapViewOfSection,可以看到最后调用NotifyRoutine时,仅仅是使用PFILE_OBJECT->FileName作为参数,PFILE_OBJECT->FileName是不包含盘符的,盘符需要从PFILE_OBJECT->DeviceObject来拿。

这个获取路径是:SectionHandle->SectionObject->ControlArea->FileObject;

需要注意的是,ControlArea里有个Flags,
if (g_vOSVer <= OS_2003)
        Flags = *(PULONG)(pControlArea + 32);
    else
        Flags = *(PULONG)(pControlArea + 28);

if ( Flags & 0x400 || !(Flags & 0x20) )
    这种不是加载image,需要忽略。

当 (g_vOSVer > OS_2003) 时,ControlArea->FileObject位置没变,但内容有所变化,实际就是低3bits变成了引用计数,需要
        pFileObject = (PFILE_OBJECT)((ULONG)pFileObject & 0xFFFFFFF8);

通过PFILE_OBJECT->DeviceObject获取盘符,也有好几种办法,貌似有ZwCreateFile X:来比较;
也有
status=ZwOpenSymbolicLinkObject(&hLink,
      GENERIC_READ,
      &VolumeOA);
status=ZwQuerySymbolicLinkObject(hLink,
      &usLinkObject,
      &Retlen);
来获取的。
此外还有IoVolumeDeviceToDosName(pFileObject->DeviceObject, &dosName)来获取。
IoVolumeDeviceToDosName实际是往L"\\Device\\MountPointManager"发送请求来得到盘符。

PFILE_OBJECT->DeviceObject应该是卷设备,可以在windbg里!object 0xXXXXXXXX来看它的名字,
比如C:实际对应HarddiskVolume1,用DeviceTree可以看到设备之间的关系。

Win7 x64:
  微软不按套路来,在SectionObject->Segment  本来是 _SEGMENT_OBJECT 结构,结果填了一个 _Segment 结构指针。

typedef union _D_EX_FAST_REF {

    PVOID object;       // +0x000 Object           : Ptr64 Void
    ULONG64 RefCnt : 4; // +0x000 RefCnt           : Pos 0, 4 Bits
    ULONG64 Value;      // +0x000 Value            : Uint8B

} D_EX_FAST_REF, *PD_EX_FAST_REF;

typedef struct _D_CONTROL_AREA {

    PVOID Segment;                       // +0x000 Segment                   : Ptr64 _SEGMENT
    LIST_ENTRY DereferenceList;          // +0x008 DereferenceList           : _LIST_ENTRY
    ULONG_PTR NumberOfSectionReferences; // +0x018 NumberOfSectionReferences : Uint8B
    ULONG_PTR NumberOfPfnReferences;     // +0x020 NumberOfPfnReferences     : Uint8B
    ULONG_PTR NumberOfMappedView;        // +0x028 NumberOfMappedViews       : Uint8B
    ULONG_PTR NumberOfUserReferences;    // +0x030 NumberOfUserReferences    : Uint8B
    ULONG u;                             // +0x038 u                         : <unnamed-tag>
    ULONG FlushInProgressCount;          // +0x03c FlushInProgressCount      : Uint4B
    D_EX_FAST_REF FilePointer;           // +0x040 FilePointer               : _EX_FAST_REF
    LONG ControlAreaLock;                // +0x048 ControlAreaLock           : Int4B
    ULONG ModifiedWriteCount;            // +0x04c ModifiedWriteCount        : Uint4B
    ULONG StartingFrame;                 // +0x04c StartingFrame             : Uint4B
    PVOID WaitingForDeletion;            // +0x050 WaitingForDeletion        : Ptr64 _MI_SECTION_CREATION_GATE
    ULONG64 u2[2];                       // +0x058 u2                        : <unnamed-tag>
    LONG64 LockedPage;                   // +0x068 LockedPages               : Int8B
    LIST_ENTRY ViewList;                 // +0x070 ViewList                  : _LIST_ENTRY

} D_CONTROL_AREA, *PD_CONTROL_AREA;

typedef struct _D_SEGMENT_OBJECT {

    PVOID BaseAddress;       // +0x000 BaseAddress       : Ptr64 Void
    ULONG TotalNumberOfPte;  // +0x008 TotalNumberOfPtes : Uint4B
    LARGE_INTEGER SizeOfSegment; // +0x010 SizeOfSegment : _LARGE_INTEGER
    ULONG NonExtendedPtes;   // +0x018 NonExtendedPtes   : Uint4B
    ULONG ImageCommitment;   // +0x01c ImageCommitment   : Uint4B
    PVOID ControlArea;       // +0x020 ControlArea       : Ptr64 _CONTROL_AREA
    PVOID Subsection;        // +0x028 Subsection        : Ptr64 _SUBSECTION
    PVOID MmSectionFlags;    // +0x030 MmSectionFlags    : Ptr64 _MMSECTION_FLAGS
    PVOID MmSubSectionFlags; // +0x038 MmSubSectionFlags : Ptr64 _MMSUBSECTION_FLAGS

} D_SEGMENT_OBJECT, *PD_SEGMENT_OBJECT;

typedef struct _D_SECTION_OBJECT {

    PVOID StartingVa;
    PVOID EndingVa;
    PVOID Parent;
    PVOID LeftChild;
    PVOID RightChild;
    PD_SEGMENT_OBJECT Segment;

} D_SECTION_OBJECT, *PD_SECTION_OBJECT;

PD_CONTROL_AREA pControlArea =
*(PD_CONTROL_AREA *)(((PD_SECTION_OBJECT)pSectionObject)->Segment);

    if ( !MmIsAddressValid(pControlArea) )
    {
        goto L_Error;
    }

    // MM_PhysicalMemory  = 0x400
    // MM_Image           = 0x20
    ULONG Flags = pControlArea->u;
    if ( (Flags & 0x400) || !(Flags & 0x20) )  // 这种不是加载image
    {
        goto L_Error;
    }

pFileObject = (PFILE_OBJECT)pControlArea->FilePointer.object;
pFileObject = (PFILE_OBJECT)((ULONG_PTR)pFileObject & 0xFFFFFFFFFFFFFFF0);

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2015-7-10 14:52
0
雪    币: 478
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
真好人,收藏了
2015-7-10 21:03
0
游客
登录 | 注册 方可回帖
返回
//