当前位置 主页 > 网站技术 > 代码类 >

    利用C++ R3层断链实现模块隐藏功能

    栏目:代码类 时间:2019-11-14 21:04

    一、模块隐藏的实现原理

      普通API查找模块实现思路:其通过查询在R3中的PEB(Process Environment Block 进程环境块)与TEB(Thread Environment Block 进程环境块)来找到一个双向链表,通过遍历双向链表中某一成员(字符串)来查找全部模块。

      模块隐藏实现思路:在R3层的模块隐藏,我们需要做的就是将其该链表断链,将某一模块从这个双向链表中摘除,这样再调用传统的API时就会搜索不到。

    二、结构体成员详细介绍

    <1> TEB结构体 -- 内存地址为 fs:[0] 处。

    使用Windbg的 "dt _TEB"命令来查看TEB结构体

    kd> dt _TEB 
    ntdll!_TEB
     +0x000 NtTib : _NT_TIB
     +0x01c EnvironmentPointer : Ptr32 Void
     +0x020 ClientId : _CLIENT_ID
     +0x028 ActiveRpcHandle : Ptr32 Void
     +0x02c ThreadLocalStoragePointer : Ptr32 Void
     +0x030 ProcessEnvironmentBlock : Ptr32 _PEB
     +0x034 LastErrorValue : Uint4B

    1. 属性介绍 

      1.1)_NT_TIB:重点两个属性,栈顶与栈大小。

       http://www.nirsoft.net/kernel_struct/vista/NT_TIB.html

      1.2) _CLIENT_ID: 存储该进程ID与当前主线程ID。

      https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tsts/a11e7129-685b-4535-8d37-21d4596ac057?redirectedfrom=MSDN

      1.3) _PEB:进程环境块 ,记住其在 TEB 偏移 0x30处即可。

    2. 通过olldbg查看该结构体

      2.1) 打开任意进程,在寄存器窗口找到 fs:[0],查看其内存地址。

        

      2.2) 在内存窗口使用命令 "db 5E7000" 跳转到该内存,使用地址格式(长型-地址)显示。

        

    <2> PEB结构体 -- fs:[0x30]

    使用 Windbg 指令 dt _PEB 查看 PEB结构体,重点关注最后一个 进程加载信息表。

    kd> dt _PEB
    ntdll!_PEB
     +0x000 InheritedAddressSpace : UChar
     +0x001 ReadImageFileExecOptions : UChar
     +0x002 BeingDebugged : UChar
     +0x003 BitField : UChar
     +0x003 ImageUsesLargePages : Pos 0, 1 Bit
     +0x003 IsProtectedProcess : Pos 1, 1 Bit
     +0x003 IsLegacyProcess : Pos 2, 1 Bit
     +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
     +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
     +0x003 SpareBits : Pos 5, 3 Bits
     +0x004 Mutant : Ptr32 Void
     +0x008 ImageBaseAddress : Ptr32 Void
     +0x00c Ldr : Ptr32 _PEB_LDR_DATA // PEB_LOADER_DATA 进程加载信息表

    1. 查看 _PEB_LDR_DATA 进程加载信息表 的结构体

      1.1)重点关注 0x00c处的指针,其指向 _PEB_LDR_DATA 这个结构体,在这个结构体中 0x00c、0x014、0x01c 分别表示 模块加载顺序 / 加载后在内存中的顺序 / 模块初始化的顺序。

    kd > dt _PEB_LDR_DATA
     ntdll!_PEB_LDR_DATA
     + 0x000 Length : Uint4B
     + 0x004 Initialized : UChar
     + 0x008 SsHandle : Ptr32 Void
     + 0x00c InLoadOrderModuleList : _LIST_ENTRY // 模块加载顺序
     + 0x014 InMemoryOrderModuleList : _LIST_ENTRY // 加载后在内存中的顺序
     + 0x01c InInitializationOrderModuleList : _LIST_ENTRY // 模块初始化的顺序
     + 0x024 EntryInProgress : Ptr32 Void
     + 0x028 ShutdownInProgress : UChar
     + 0x02c ShutdownThreadId : Ptr32 Void