zoukankan      html  css  js  c++  java
  • 枚举PEB获取进程模块列表

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


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


    1. typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);  
    2.   
    3. typedef ULONG   PPS_POST_PROCESS_INIT_ROUTINE;    
    4.   
    5. typedef struct _PEB_LDR_DATA {  
    6.     BYTE       Reserved1[8];  
    7.     PVOID      Reserved2[3];  
    8.     LIST_ENTRY InMemoryOrderModuleList;  
    9. } PEB_LDR_DATA, *PPEB_LDR_DATA;  
    10.   
    11. typedef struct _RTL_USER_PROCESS_PARAMETERS {  
    12.     BYTE           Reserved1[16];  
    13.     PVOID          Reserved2[10];  
    14.     UNICODE_STRING ImagePathName;  
    15.     UNICODE_STRING CommandLine;  
    16. } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;  
    17.   
    18. typedef struct _PEB {  
    19.     BYTE                          Reserved1[2];  
    20.     BYTE                          BeingDebugged;  
    21.     BYTE                          Reserved2[1];  
    22.     PVOID                         Reserved3[2];  
    23.     PPEB_LDR_DATA                 Ldr;  
    24.     PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;  
    25.     BYTE                          Reserved4[104];  
    26.     PVOID                         Reserved5[52];  
    27.     PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;  
    28.     BYTE                          Reserved6[128];  
    29.     PVOID                         Reserved7[1];  
    30.     ULONG                         SessionId;  
    31. } PEB, *PPEB;  
    32.   
    33. typedef struct _LDR_DATA_TABLE_ENTRY    
    34. {    
    35.     LIST_ENTRY InLoadOrderLinks;    
    36.     LIST_ENTRY InMemoryOrderLinks;    
    37.     LIST_ENTRY InInitializationOrderLinks;    
    38.     PVOID DllBase;    
    39.     PVOID EntryPoint;    
    40.     DWORD SizeOfImage;    
    41.     UNICODE_STRING FullDllName;    
    42.     UNICODE_STRING BaseDllName;    
    43.     DWORD Flags;    
    44.     WORD LoadCount;    
    45.     WORD TlsIndex;    
    46.     LIST_ENTRY HashLinks;    
    47.     PVOID SectionPointer;    
    48.     DWORD CheckSum;    
    49.     DWORD TimeDateStamp;    
    50.     PVOID LoadedImports;    
    51.     PVOID EntryPointActivationContext;    
    52.     PVOID PatchInformation;    
    53. }LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;    
    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;  


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


    1. NTSTATUS GetProcessModules(ULONG ulProcessId)  
    2. {  
    3.     NTSTATUS nStatus;  
    4.     //PEB结构指针  
    5.     PPEB pPEB = NULL;  
    6.   
    7.     //EPROCESS结构指针  
    8.     PEPROCESS  pEProcess = NULL;  
    9.   
    10.     //查找的函数名称  
    11.     UNICODE_STRING uniFunctionName;  
    12.       
    13.     //进程参数信息  
    14.     PRTL_USER_PROCESS_PARAMETERS pParam  = NULL;  
    15.   
    16.     //LDR数据结构  
    17.     PPEB_LDR_DATA pPebLdrData = NULL;    
    18.   
    19.     //LDR链表入口  
    20.     PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;    
    21.   
    22.     //链表头节点、尾节点  
    23.     PLIST_ENTRY pListEntryStart = NULL;  
    24.     PLIST_ENTRY pListEntryEnd = NULL;   
    25.   
    26.     //函数指针  
    27.     PFNPsGetProcessPeb  PsGetProcessPeb = NULL;  
    28.   
    29.     //保存APC状态  
    30.     KAPC_STATE KAPC ={0};  
    31.   
    32.     //是否已经附加到进程  
    33.     BOOLEAN bIsAttached = FALSE;  
    34.   
    35.     //获取进程的EPROCESS结构指针  
    36.     nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);  
    37.     if (!NT_SUCCESS(nStatus))  
    38.     {  
    39.         return STATUS_UNSUCCESSFUL;  
    40.     }  
    41.   
    42.     //查找函数地址  
    43.     RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");  
    44.     PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);  
    45.     if (PsGetProcessPeb == NULL)  
    46.     {  
    47.         KdPrint(("Get PsGetProcessPeb Failed~! "));  
    48.         return STATUS_UNSUCCESSFUL;  
    49.     }  
    50.   
    51.     //获取PEB指针  
    52.     pPEB = PsGetProcessPeb(pEProcess);  
    53.     if (pPEB == NULL)  
    54.     {  
    55.         KdPrint(("Get pPEB Failed~! "));  
    56.         return STATUS_UNSUCCESSFUL;  
    57.     }  
    58.   
    59.     //附加到进程  
    60.     KeStackAttachProcess(pEProcess, &KAPC);  
    61.   
    62.     bIsAttached = TRUE;  
    63.   
    64.     //指向LDR  
    65.     pPebLdrData = pPEB->Ldr;  
    66.   
    67.     //头节点、尾节点  
    68.     pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;  
    69.   
    70.   
    71.     //开始遍历_LDR_DATA_TABLE_ENTRY  
    72.     do    
    73.     {    
    74.         //通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构    
    75.         pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);    
    76.   
    77.         //输出DLL全路径  
    78.         KdPrint(("%wZ  ", &pLdrDataEntry->FullDllName));  
    79.   
    80.         pListEntryStart = pListEntryStart->Flink;    
    81.   
    82.     }while(pListEntryStart != pListEntryEnd);    
    83.   
    84.   
    85.     //Detach进程  
    86.     if (bIsAttached != FALSE)  
    87.     {  
    88.         KeUnstackDetachProcess(&KAPC);  
    89.     }  
    90.   
    91.     //减少引用计数  
    92.     if (pEProcess != NULL)  
    93.     {  
    94.         ObDereferenceObject(pEProcess);  
    95.         pEProcess = NULL;  
    96.     }  
    97.   
    98.     return STATUS_SUCCESS;  
    99. }  
    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~!
    "));
            return STATUS_UNSUCCESSFUL;
        }
    
        //获取PEB指针
        pPEB = PsGetProcessPeb(pEProcess);
        if (pPEB == NULL)
        {
            KdPrint(("Get pPEB Failed~!
    "));
            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 
    ", &pLdrDataEntry->FullDllName));
    
            pListEntryStart = pListEntryStart->Flink;  
    
        }while(pListEntryStart != pListEntryEnd);  
    
    
        //Detach进程
        if (bIsAttached != FALSE)
        {
            KeUnstackDetachProcess(&KAPC);
        }
    
        //减少引用计数
        if (pEProcess != NULL)
        {
            ObDereferenceObject(pEProcess);
            pEProcess = NULL;
        }
    
        return STATUS_SUCCESS;
    }


    下面是运行截图:



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

     

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


  • 相关阅读:
    2017-2018-2 20179205 《网络攻防》第十三周作业 国密算法实现
    2017-2018-2 20179205 《网络攻防技术与实践》第十二周作业 免杀技术
    2017-2018-2 20179205《网络攻防技术与实践》第十一周作业 SQL注入攻击与实践
    2017-2018-2 20179205《网络攻防技术与实践》第十周作业 缓冲区溢出攻防研究
    2017-2018-2 20179205《网络攻防技术与实践》第九周作业
    2017-2018-2 20179205 《网络攻防技术与实践》第八周作业
    2017-2018-2 20179205 《网络攻防技术与实践》第七周作业
    2017-2018-2 20179205《网络攻防技术与实践》Windows攻击实验
    2017-2018-2 20179205 《网络攻防技术与实践》第六周作业
    2017-2018-2 20179205 《网络攻防技术与实践》第五周作业
  • 原文地址:https://www.cnblogs.com/kuangke/p/5761429.html
Copyright © 2011-2022 走看看