枚举PEB获取进程模块列表

枚举进程模块的方法有很多种,常见的有枚举PEB和内存搜索法,今天,先来看看实现起来最简单的枚举PEB实现获取进程模块列表。


首先,惯例是各种繁琐的结构体定义。需要包含 ntifs.h 和 WinDef.h, 此处不再列出,各位看官根据情况自行添加。


typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);

typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;  

typedef struct _PEB_LDR_DATA {
    BYTE       Reserved1[8];
    PVOID      Reserved2[3];
    LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
    BYTE           Reserved1[16];
    PVOID          Reserved2[10];
    UNICODE_STRING ImagePathName;
    UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB {
    BYTE                          Reserved1[2];
    BYTE                          BeingDebugged;
    BYTE                          Reserved2[1];
    PVOID                         Reserved3[2];
    PPEB_LDR_DATA                 Ldr;
    PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
    BYTE                          Reserved4[104];
    PVOID                         Reserved5[52];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE                          Reserved6[128];
    PVOID                         Reserved7[1];
    ULONG                         SessionId;
} PEB, *PPEB;

typedef struct _LDR_DATA_TABLE_ENTRY  
{  
    LIST_ENTRY InLoadOrderLinks;  
    LIST_ENTRY InMemoryOrderLinks;  
    LIST_ENTRY InInitializationOrderLinks;  
    PVOID DllBase;  
    PVOID EntryPoint;  
    DWORD SizeOfImage;  
    UNICODE_STRING FullDllName;  
    UNICODE_STRING BaseDllName;  
    DWORD Flags;  
    WORD LoadCount;  
    WORD TlsIndex;  
    LIST_ENTRY HashLinks;  
    PVOID SectionPointer;  
    DWORD CheckSum;  
    DWORD TimeDateStamp;  
    PVOID LoadedImports;  
    PVOID EntryPointActivationContext;  
    PVOID PatchInformation;  
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;  


下面进入真正的实现代码:


NTSTATUS GetProcessModules(ULONG ulProcessId)
{
    NTSTATUS nStatus;
    //PEB结构指针
    PPEB pPEB = NULL;

    //EPROCESS结构指针
    PEPROCESS  pEProcess = NULL;

    //查找的函数名称
    UNICODE_STRING uniFunctionName;
    
    //进程参数信息
    PRTL_USER_PROCESS_PARAMETERS pParam  = NULL;

    //LDR数据结构
    PPEB_LDR_DATA pPebLdrData = NULL;  

    //LDR链表入口
    PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;  

    //链表头节点、尾节点
    PLIST_ENTRY pListEntryStart = NULL;
    PLIST_ENTRY pListEntryEnd = NULL; 

    //函数指针
    PFNPsGetProcessPeb  PsGetProcessPeb = NULL;

    //保存APC状态
    KAPC_STATE KAPC ={0};

    //是否已经附加到进程
    BOOLEAN bIsAttached = FALSE;

    //获取进程的EPROCESS结构指针
    nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);
    if (!NT_SUCCESS(nStatus))
    {
        return STATUS_UNSUCCESSFUL;
    }

    //查找函数地址
    RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");
    PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);
    if (PsGetProcessPeb == NULL)
    {
        KdPrint(("Get PsGetProcessPeb Failed~!\n"));
        return STATUS_UNSUCCESSFUL;
    }

    //获取PEB指针
    pPEB = PsGetProcessPeb(pEProcess);
    if (pPEB == NULL)
    {
        KdPrint(("Get pPEB Failed~!\n"));
        return STATUS_UNSUCCESSFUL;
    }

    //附加到进程
    KeStackAttachProcess(pEProcess, &KAPC);

    bIsAttached = TRUE;

    //指向LDR
    pPebLdrData = pPEB->Ldr;

    //头节点、尾节点
    pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;


    //开始遍历_LDR_DATA_TABLE_ENTRY
    do  
    {  
        //通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构  
        pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);  

        //输出DLL全路径
        KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));

        pListEntryStart = pListEntryStart->Flink;  

    }while(pListEntryStart != pListEntryEnd);  


    //Detach进程
    if (bIsAttached != FALSE)
    {
        KeUnstackDetachProcess(&KAPC);
    }

    //减少引用计数
    if (pEProcess != NULL)
    {
        ObDereferenceObject(pEProcess);
        pEProcess = NULL;
    }

    return STATUS_SUCCESS;
}


下面是运行截图:

枚举PEB获取进程模块列表_第1张图片


本帖为原创,转帖请说明出处,谢谢合作。

本帖地址:http://blog.csdn.net/sonsie007/article/details/22622177


你可能感兴趣的:(驱动,PEB,进程模块)