zoukankan      html  css  js  c++  java
  • 通过PEB遍历当前进程中的模块(C语言实现)

    0x00 相关说明:

    Windows应用层如果要遍历当前进程所加载的模块可以使用WIN32API通过进程快照来实现

    通过PEB来遍历进程模块没有WIN32API的使用痕迹,在某些场合更加好用

    其中32位应用程序的 PEB 的地址可以通过 fs:[0x30]获取,fs:[0]为TEB结构的地址

    0x01 相关数据结构:

    下面的数据结构可以在windbg中使用命令查看(使用 dt <数据结构名称>)

    typedef  struct  _TEB {  //fs:[0]
         NT_TIB                  Tib;
         PVOID                   EnvironmentPointer;
         CLIENT_ID               Cid;
         PVOID                   ActiveRpcInfo;
         PVOID                   ThreadLocalStoragePointer;
         PPEB                    Peb;
         //......
    } TEB, * PTEB;

    typedef  struct  _PEB {  //fs:[0x30]
         BYTE InheritedAddressSpace;
         BYTE ReadImageFileExecOptions;
         BYTE BeingDebugged;
         BYTE BitField;
         PVOID Mutant;
         PVOID ImageBaseAddress;
         PPEB_LDR_DATA Ldr;
         //......
    } PEB, * PPEB;

    typedef  struct  _PEB_LDR_DATA {
         UINT Length;
         BYTE Initialized;
         PVOID SsHandle;
         LIST_ENTRY InLoadOrderModuleList;
         LIST_ENTRY InMemoryOrderModuleList;
         LIST_ENTRY InInitializationOrderModuleList;
         //......
    } PEB_LDR_DATA, * PPEB_LDR_DATA;

    typedef  struct  _LDR_DATA_TABLE_ENTRY {
         LIST_ENTRY  InLoadOrderLinks;
         LIST_ENTRY  InMemoryOrderModuleList;
         LIST_ENTRY  InInitializationOrderModuleList;
         PVOID  DllBase;
         PVOID  EntryPoint;
         ULONG  SizeOfImage;
         UNICODE_STRING FullDllName;
         UNICODE_STRING  BaseDllName;
         //......
    } _LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

    typedef  struct  _UNICODE_STRING {
         USHORT  Length;
         USHORT  MaximumLength;
         PWSTR  Buffer;
    } UNICODE_STRING, * PUNICODE_STRING;

    typedef  struct  _CLIENT_ID {
         PVOID UniqueProcess;
         PVOID UniqueThread;
    } CLIENT_ID, * PCLIENT_ID;

    0x02 实现原理:

    结构索引流程如下:

    1

    其中各个_LDR_DATA_TABLE_ENTRY结构的关系如下:(以3个模块为例)

    2

    其中 InLoadOrderLinks、InMemoryOrderLinks、InInitializationOrderLinks 均为:LIST_ENTRY

    0x03 代码实现:

    代码实现如下:(记得自行添加前面介绍的相关结构定义):

    int main(int argc, char* argv[])
    {
         PPEB pPEB = (PPEB)__readfsdword(0x30);
         PPEB_LDR_DATA pLdr = pPEB->Ldr;

        DWORD dwFixOffset=0;
         PLDR_DATA_TABLE_ENTRY pBase, pNext;

        printf("Enum InLoadOrderModuleList: ");
         dwFixOffset = 0;
         pBase = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pLdr->InLoadOrderModuleList.Flink) - dwFixOffset);
         pNext = pBase;
         do {
             wprintf_s(L"%s ", pNext->FullDllName.Buffer);
             pNext = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pNext->InLoadOrderLinks.Flink) - dwFixOffset);
         } while (pBase != pNext);
         printf("Enum InLoadOrderModuleList End! ");

        printf("Enum InMemoryOrderModuleList: ");
         dwFixOffset = (DWORD) & (pBase->InMemoryOrderLinks) - (DWORD)pBase;
         pBase = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pLdr->InMemoryOrderModuleList.Flink) - dwFixOffset);
         pNext = pBase;
         do {
             wprintf_s(L"%s ", pNext->FullDllName.Buffer);
             pNext = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pNext->InMemoryOrderLinks.Flink) - dwFixOffset);
         } while (pBase != pNext);
         printf("Enum InMemoryOrderModuleList End! ");

        printf("Enum InInitializationOrderModuleList: ");
         dwFixOffset = (DWORD) & (pBase->InInitializationOrderLinks) - (DWORD)pBase;
         pBase = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pLdr->InInitializationOrderModuleList.Flink) - dwFixOffset);
         pNext = pBase;
         do {
             wprintf_s(L"%s ", pNext->FullDllName.Buffer);
             pNext = (PLDR_DATA_TABLE_ENTRY)((DWORD)(pNext->InInitializationOrderLinks.Flink) - dwFixOffset);
         } while (pBase != pNext);
         printf("Enum InInitializationOrderModuleList End! ");


         system("pause");
         return 0;
    }

    代码执行结果:

    3

  • 相关阅读:
    Maven工程读取properties文件过程
    Nginx实现高可用(了解)
    使用Nginx实现负载均衡(tomcat集群之后实现交叉访问)
    使用Nginx实现反向代理过程(一台服务器部署两个网站)
    一台服务器,通过不同域名区分不同主机,配置步骤
    EditPlus5.0破解激活
    [通知] 博客停更
    [论文理解] 活体检测算法论文小结 (一)
    [CUDA] CUDA编程入门
    [学习笔记]《机器学习基础》 课程总结(一)
  • 原文地址:https://www.cnblogs.com/DarkBright/p/10865193.html
Copyright © 2011-2022 走看看