• 【旧文章搬运】从PEB获取内存中模块列表


    原文发表于百度空间,2008-7-25
    ==========================================================================

    PEB中的Ldr部分包含有当前进程所加载的模块信息.
    lkd> dt _peb
    ntdll!_PEB
       +0x000 InheritedAddressSpace : UChar
       +0x001 ReadImageFileExecOptions : UChar
       +0x002 BeingDebugged    : UChar
       +0x003 SpareBool        : UChar
       +0x004 Mutant           : Ptr32 Void
       +0x008 ImageBaseAddress : Ptr32 Void
       +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
    .....
    其结构定义如下:

    typedef struct _PEB_LDR_DATA
    {
    ULONG Length;
    BOOLEAN Initialized;
    PVOID SsHandle; 
    LIST_ENTRY InLoadOrderModuleList; //按加载顺序
    LIST_ENTRY InMemoryOrderModuleList; //按内存顺序
    LIST_ENTRY InInitializationOrderModuleList; //按初始化顺序
    } PEB_LDR_DATA,*PPEB_LDR_DATA;

    另一个重要结构就是存储每个模块信息的LDR_MODULE部分,其定义如下:

    typedef struct _LDR_MODULE
    {
    LIST_ENTRY          InLoadOrderModuleList;
    LIST_ENTRY          InMemoryOrderModuleList; 
    LIST_ENTRY          InInitializationOrderModuleList; 
    void*               BaseAddress; 
    void*               EntryPoint;   
    ULONG               SizeOfImage;
    UNICODE_STRING      FullDllName;
    UNICODE_STRING      BaseDllName;
    ULONG               Flags;
    SHORT               LoadCount;
    SHORT               TlsIndex;
    HANDLE              SectionHandle;
    ULONG               CheckSum;
    ULONG               TimeDateStamp;
    } LDR_MODULE, *PLDR_MODULE;

    这两者的关系呢,引用别人的两张图来说明一下吧,看了图应该一目了然.

    第二张图太大了,放个缩略图吧.
    结构搞清楚之后,要遍历就很简单了,主要就是遍历一个双向环状链表.

    PEB_LDR_DATA *pPEBLDR;
    LDR_MODULE *pLdrMod;
    LIST_ENTRY *pListEntry,*pStart;
    void *p,*BaseAddress,*FullDllName;
    _asm
    {
       mov eax,fs:[0x30] //TEB->PEB
       mov eax,[eax+0xC] //PEB->Ldr
       mov pPEBLDR,eax
    }
    printf("PEB_LDR_DATA:0x%08x
    ",pPEBLDR);
    printf("LDR->Length:0x%08x
    ",pPEBLDR->Length);
    printf("LDR->InLoadOrderModuleList:		0x%08x
    ",pPEBLDR->InLoadOrderModuleList);
    printf("LDR->InMemoryOrderModuleList:		0x%08x
    ",pPEBLDR->InMemoryOrderModuleList);
    printf("LDR->InInitializationOrderModuleList:	0x%08x
    ",pPEBLDR->InInitializationOrderModuleList);
    //遍历双链表
    pListEntry=(LIST_ENTRY*)(PUCHAR)&(pPEBLDR->InLoadOrderModuleList);
    pStart=pListEntry;
    printf("BaseAddress		FullDllName
    ====================================
    ");
    do 
    {
       pListEntry=pListEntry->Flink;
       pLdrMod=(LDR_MODULE*)pListEntry;
       printf("0x%08x		",pLdrMod->BaseAddress);
       wprintf(L"%s
    ",pLdrMod->FullDllName.Buffer);
      
    } while(pListEntry!=pStart);

    效果图:

  • 相关阅读:
    算术操作、张量转换、矩阵运算、归约计算
    CNN与RNN
    基本使用与常用函数
    RNN与LSTM
    CNN训练算法与正则化
    CNN的层级结构
    激活函数
    反向传播与参数更新
    Pipline
    模型存储
  • 原文地址:https://www.cnblogs.com/achillis/p/10179607.html
Copyright © 2020-2023  润新知