通过PEB枚举进程模块_x86_x64

抄的,原文很详细的说明了原理
作者:沉疴
出处:https://www.cnblogs.com/lsh123/p/8295774.html

.h

#pragma once
#include <windows.h>
#include <winternl.h>
#include <ntstatus.h>
#include <TlHelp32.h>
#include <Psapi.h>
#include <vector>
using namespace std;
 
 
enum MODULE_TYPE
{
    MODULE_X86,
    MODULE_X64,
};
struct _PROCESS_MODULE_INFORMATION_
{
    ULONG64   ModuleBase;                                //操作系统中可能存在64位与32位的程序
    size_t    ModuleSize;
    WCHAR     ModuleFullPathData[MAX_PATH];
    MODULE_TYPE ModuleType;
};
template <typename T>
struct _LIST_ENTRY_
{
    T Flink;
    T Blink;
};
 
template <typename T>
struct _UNICODE_STRING_
{
    WORD BufferLength;
    WORD MaximumLength;
    T BufferData;
};
 
 
 
template <typename T, typename NGF, int A>
struct _PEB_
{
    typedef T type;
 
    union
    {
        struct
        {
            BYTE InheritedAddressSpace;
            BYTE ReadImageFileExecOptions;
            BYTE BeingDebugged;
            BYTE BitField;
        };
        T dummy01;
    };
    T Mutant;
    T ImageBaseAddress;
    T Ldr;
    T ProcessParameters;
    T SubSystemData;
    T ProcessHeap;
    T FastPebLock;
    T AtlThunkSListPtr;
    T IFEOKey;
    T CrossProcessFlags;
    T UserSharedInfoPtr;
    DWORD SystemReserved;
    DWORD AtlThunkSListPtr32;
    T ApiSetMap;
    T TlsExpansionCounter;
    T TlsBitmap;
    DWORD TlsBitmapBits[2];
    T ReadOnlySharedMemoryBase;
    T HotpatchInformation;
    T ReadOnlyStaticServerData;
    T AnsiCodePageData;
    T OemCodePageData;
    T UnicodeCaseTableData;
    DWORD NumberOfProcessors;
    union
    {
        DWORD NtGlobalFlag;
        NGF dummy02;
    };
    LARGE_INTEGER CriticalSectionTimeout;
    T HeapSegmentReserve;
    T HeapSegmentCommit;
    T HeapDeCommitTotalFreeThreshold;
    T HeapDeCommitFreeBlockThreshold;
    DWORD NumberOfHeaps;
    DWORD MaximumNumberOfHeaps;
    T ProcessHeaps;
    T GdiSharedHandleTable;
    T ProcessStarterHelper;
    T GdiDCAttributeList;
    T LoaderLock;
    DWORD OSMajorVersion;
    DWORD OSMinorVersion;
    WORD OSBuildNumber;
    WORD OSCSDVersion;
    DWORD OSPlatformId;
    DWORD ImageSubsystem;
    DWORD ImageSubsystemMajorVersion;
    T ImageSubsystemMinorVersion;
    T ActiveProcessAffinityMask;
    T GdiHandleBuffer[A];
    T PostProcessInitRoutine;
    T TlsExpansionBitmap;
    DWORD TlsExpansionBitmapBits[32];
    T SessionId;
    ULARGE_INTEGER AppCompatFlags;
    ULARGE_INTEGER AppCompatFlagsUser;
    T pShimData;
    T AppCompatInfo;
    _UNICODE_STRING_<T> CSDVersion;
    T ActivationContextData;
    T ProcessAssemblyStorageMap;
    T SystemDefaultActivationContextData;
    T SystemAssemblyStorageMap;
    T MinimumStackCommit;
    T FlsCallback;
    _LIST_ENTRY_<T> FlsListHead;
    T FlsBitmap;
    DWORD FlsBitmapBits[4];
    T FlsHighIndex;
    T WerRegistrationData;
    T WerShipAssertPtr;
    T pContextData;
    T pImageHeaderHash;
    T TracingFlags;
    T CsrServerReadOnlySharedMemoryBase;
};
typedef _PEB_<DWORD, DWORD64, 34> _PEB32_;
typedef _PEB_<DWORD64, DWORD, 30> _PEB64_;
template<typename T>
struct _PEB_T
{
    typedef typename std::conditional<std::is_same<T, DWORD>::value, _PEB32_, _PEB64_>::type type;
};
 
template<typename T>
struct _PEB_LDR_DATA_
{
    unsigned long Length;
    unsigned char Initialized;
    T SsHandle;
    _LIST_ENTRY_<T> InLoadOrderModuleList;
    _LIST_ENTRY_<T> InMemoryOrderModuleList;
    _LIST_ENTRY_<T> InInitializationOrderModuleList;
    T EntryInProgress;
    unsigned char ShutdownInProgress;
    T ShutdownThreadId;
};
 
 
template<typename T>
struct _LDR_DATA_TABLE_ENTRY_
{
    _LIST_ENTRY_<T> InLoadOrderLinks;
    _LIST_ENTRY_<T> InMemoryOrderLinks;
    _LIST_ENTRY_<T> InInitializationOrderLinks;
    T DllBase;
    T EntryPoint;
    unsigned long SizeOfImage;
    _UNICODE_STRING_<T> FullDllName;
    _UNICODE_STRING_<T> BaseDllName;
    unsigned long Flags;
    unsigned short LoadCount;
    unsigned short TlsIndex;
    _LIST_ENTRY_<T> HashLinks;
    unsigned long TimeDateStamp;
    T EntryPointActivationContext;
    T PatchInformation;
};
template<typename T>
struct _PROCESS_BASIC_INFORMATION_
{
    NTSTATUS ExitStatus;
    ULONG    Reserved0;
    T        PebBaseAddress;
    T        AffinityMask;
    LONG     BasePriority;
    ULONG    Reserved1;
    T        UniqueProcessId;
    T        InheritedFromUniqueProcessId;
};
 
 
 
 
 
typedef decltype(&NtQueryInformationProcess) LPFN_NTQUERYINFORMATIONPROCESS;
 
 
 
typedef NTSTATUS(NTAPI *LPFN_NTWOW64QUERYINFORMATIONPROCESS64)(
    IN  HANDLE ProcessHandle,
    IN  ULONG  ProcessInformationClass,
    OUT PVOID  ProcessInformation,
    IN  ULONG  ProcessInformationLength,
    OUT PULONG ReturnLength OPTIONAL);
 
typedef NTSTATUS(NTAPI *LPFN_NTWOW64READVIRTUALMEMORY64)(
    IN  HANDLE   ProcessHandle,
    IN  ULONG64  BaseAddress,
    OUT PVOID    BufferData,
    IN  ULONG64  BufferLength,
    OUT PULONG64 ReturnLength OPTIONAL);
struct _PROCESS_INFORMATION_
{
    ULONG  ProcessID;
    char   ImageNameData[MAX_PATH];
    char   ProcessFullPathData[MAX_PATH];
};
typedef struct
{
    DWORD ExitStatus;
    DWORD PebBaseAddress;
    DWORD AffinityMask;
    DWORD BasePriority;
    ULONG UniqueProcessId;
    ULONG InheritedFromUniqueProcessId;
}   __PROCESS_BASIC_INFORMATION__;
 
typedef LONG(__stdcall *PROCNTQSIP)(HANDLE, UINT, PVOID, ULONG, PULONG);
 
 
 
SIZE_T SeEnumProcessModuleList(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo);
SIZE_T SeEnumModuleInfoByPeb(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo);
template<typename T>
SIZE_T EnumModuleInfoByPeb(HANDLE ProcessHandle, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo);
ULONG64 GetPeb(HANDLE ProcessHandle, _PEB64_* Peb);
ULONG32 GetPeb(HANDLE ProcessHandle, _PEB32_* Peb);
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64* ReturnLength);
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD64 BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64 *ReturnLength);

.cpp

BOOL EnumDllLoaderedProcess(vector<_PROCESS_INFORMATION_>  ProcessInfo, string DllName)
{
    OnInitMember();
    vector<_PROCESS_INFORMATION_>::iterator i;
    string DllFullPath;
    int j = 0;
    for (i = ProcessInfo.begin(); i != ProcessInfo.end(); i++)
    {
        ULONG ProcessID = i->ProcessID;
        vector<_PROCESS_MODULE_INFORMATION_>ProcessModuleInfomationVector;
        SeEnumProcessModuleList(ProcessID, ProcessModuleInfomationVector);
        int index = 0;
        vector<_PROCESS_MODULE_INFORMATION_>::iterator m;
 
        for (m = ProcessModuleInfomationVector.begin(); m != ProcessModuleInfomationVector.end(); m++)
        {
 
            DllFullPath = SeUtf16ToUtf8(m->ModuleFullPathData);
            index = DllFullPath.find(DllName);
            if (index == -1)
            {
                continue;
            }
            else
            {
                printf("%s", i->ProcessFullPathData);
                printf("-----------------------------\n\n");
                break;
            }
        }
 
 
 
    }
    return TRUE;
}
 
SIZE_T SeEnumProcessModuleList(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo)
{
    SeEnumModuleInfoByPeb(ProcessID, ProcessModuleInfo);
 
    return ProcessModuleInfo.size();
}
SIZE_T SeEnumModuleInfoByPeb(ULONG ProcessID, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo)
{
    HANDLE ProcessHandle = NULL;
    BOOL   IsWow64 = FALSE;
    ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessID);
    int a = GetLastError();
    if (ProcessHandle == NULL)
    {
        goto Error;
    }
    IsWow64Process(ProcessHandle, &IsWow64);
 
    if (IsWow64 == TRUE)
    {
        EnumModuleInfoByPeb<DWORD>(ProcessHandle, ProcessModuleInfo);
    }
    else
    {
        EnumModuleInfoByPeb<DWORD64>(ProcessHandle, ProcessModuleInfo);
    }
Error:
    if (ProcessHandle != NULL)
    {
        CloseHandle(ProcessHandle);
        ProcessHandle = NULL;
    }
    return ProcessModuleInfo.size();
}
template<typename T>
SIZE_T EnumModuleInfoByPeb(HANDLE ProcessHandle, vector<_PROCESS_MODULE_INFORMATION_>& ProcessModuleInfo)
{
    typename _PEB_T<T>::type Peb = { { { 0 } } };
    _PEB_LDR_DATA_<T> PebLdrData = { 0 };
 
    ProcessModuleInfo.clear();
 
 
    if (GetPeb(ProcessHandle, &Peb) != 0 && SeReadProcessMemory(ProcessHandle,
        Peb.Ldr, &PebLdrData, sizeof(PebLdrData), 0) == TRUE)
    {
        for (T CheckPtr = PebLdrData.InLoadOrderModuleList.Flink;
            CheckPtr != (Peb.Ldr + FIELD_OFFSET(_PEB_LDR_DATA_<T>, InLoadOrderModuleList));
            SeReadProcessMemory(ProcessHandle, static_cast<ULONG64>(CheckPtr), &CheckPtr, sizeof(CheckPtr), 0))
        {
            _PROCESS_MODULE_INFORMATION_ v1;
            wchar_t ModuleFullPathData[MAX_PATH] = { 0 };
            _LDR_DATA_TABLE_ENTRY_<T> LdrDataTableEntry = { { 0 } };
 
            SeReadProcessMemory(ProcessHandle, CheckPtr, &LdrDataTableEntry, sizeof(LdrDataTableEntry), 0);
            SeReadProcessMemory(ProcessHandle, LdrDataTableEntry.FullDllName.BufferData, ModuleFullPathData,
                LdrDataTableEntry.FullDllName.BufferLength, 0);
 
            v1.ModuleBase = LdrDataTableEntry.DllBase;
            v1.ModuleSize = LdrDataTableEntry.SizeOfImage;
            wmemcpy(v1.ModuleFullPathData, ModuleFullPathData, MAX_PATH);
            printf("%ls\n", v1.ModuleFullPathData);
 
            v1.ModuleType = std::is_same<T, DWORD>::value ? MODULE_X86 : MODULE_X64;
 
            ProcessModuleInfo.emplace_back(v1);
        }
    }
 
    return ProcessModuleInfo.size();
}
ULONG64 GetPeb(HANDLE ProcessHandle, _PEB64_* Peb)
{
    _PROCESS_BASIC_INFORMATION_<DWORD64> ProcessBasicInfo = { 0 };
    ULONG ReturnLength = 0;
    if (NT_SUCCESS(__NtWow64QueryInformationProcess64(ProcessHandle, ProcessBasicInformation, &ProcessBasicInfo,
        (ULONG)sizeof(ProcessBasicInfo), &ReturnLength)) && Peb)
    {
        __NtWow64ReadVirtualMemory64(ProcessHandle, ProcessBasicInfo.PebBaseAddress, Peb, sizeof(_PEB64_), NULL);
    }
 
    return ProcessBasicInfo.PebBaseAddress;
}
ULONG32 GetPeb(HANDLE ProcessHandle, _PEB32_* Peb)
{
    PROCESS_BASIC_INFORMATION ProcessBasicInfo = { 0 };
    ULONG ReturnLength = 0;
 
 
    if (NT_SUCCESS(__NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &ProcessBasicInfo,
        (ULONG)sizeof(ProcessBasicInfo), &ReturnLength)) && Peb)
    {
        ReadProcessMemory(ProcessHandle, ProcessBasicInfo.PebBaseAddress, Peb, sizeof(_PEB32_), NULL);
    }
    return reinterpret_cast<ULONG32>(ProcessBasicInfo.PebBaseAddress);
}
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64* ReturnLength)
{
    return ReadProcessMemory(ProcessHandle, reinterpret_cast<LPVOID>(BaseAddress), BufferData,
        BufferLength, reinterpret_cast<SIZE_T*>(ReturnLength));
 
}
BOOL SeReadProcessMemory(HANDLE ProcessHandle, DWORD64 BaseAddress, LPVOID BufferData, size_t BufferLength, DWORD64 *ReturnLength)
{
    if (__NtWow64ReadVirtualMemory64(ProcessHandle,
        BaseAddress, BufferData, BufferLength, ReturnLength) != STATUS_SUCCESS)
    {
        return FALSE;
    }
 
    return TRUE;
}
 
 
BOOL OnInitMember()
{
    HMODULE NtdllModuleBase = NULL;
    NtdllModuleBase = GetModuleHandle("Ntdll.dll");
    if (NtdllModuleBase == NULL)
    {
        return FALSE;
    }
    __NtWow64QueryInformationProcess64 = (LPFN_NTWOW64QUERYINFORMATIONPROCESS64)GetProcAddress(NtdllModuleBase,
        "NtWow64QueryInformationProcess64");
    __NtWow64ReadVirtualMemory64 = (LPFN_NTWOW64READVIRTUALMEMORY64)GetProcAddress(NtdllModuleBase,
        "NtWow64ReadVirtualMemory64");
    __NtQueryInformationProcess = (LPFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(NtdllModuleBase,
        "NtQueryInformationProcess");
    if (__NtWow64QueryInformationProcess64 == NULL || __NtWow64ReadVirtualMemory64 == NULL || __NtQueryInformationProcess == NULL)
    {
        return FALSE;
    }
    return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值