首页
社区
课程
招聘
[原创]四种获取目标进程导入DLL模块地址的方法
发表于: 2023-12-14 01:06 10867

[原创]四种获取目标进程导入DLL模块地址的方法

2023-12-14 01:06
10867

本人在校大学生一枚,技术不太行,各位师傅将就看看。

tlhelp32.h头文件中,提供了CreateToolhelp32SnapshotAPI,可以获取获取指定进程以及这些进程使用的堆、模块和线程的快照。

在进程快照信息中,包含着进程导入模块的信息。因此,我们可以有如下实现思路:

按照微软官方的建议,使用EnumProcessModules函数枚举进程模块可以确定哪些进程加载了特定的DLL。这个函数在psapi.h中。以下是微软给出的实例代码。

PEB +0x00c成员Ldr指向_PEB_LDR_DATA结构,此结构的第三成员InMemoryOrderModuleList包含进程的已加载模块的双向链表的头部。列表中的每个项目都是指向LDR_DATA_TABLE_ENTRY结构的指针。

因此,这种方法的思路如下:

贴一个大佬的获取PEB代码(原谅我实在忘了在哪找到的,知道的朋友请留言一下)

对目标进程进行DLL注入,Hook GetMoudleHandleLoadlibary等函数,让目标进程自己调用,进行IPC通信。

PEB (winternl.h) - Win32 应用 |Microsoft 学习

PEB_LDR_DATA (winternl.h) - Win32 应用 |Microsoft 学习

PEB及LDR链 - bokernb - 博客园 (cnblogs.com)

远程获取进程DLL模块地址_获取进程模块-CSDN博客

CreateToolhelp32Snapshot 函数 (tlhelp32.h) - Win32 apps | Microsoft Learn

枚举进程的所有模块 - Win32 apps | Microsoft Learn

HANDLE CreateToolhelp32Snapshot(
  [in] DWORD dwFlags,
  [in] DWORD th32ProcessID
);
HANDLE CreateToolhelp32Snapshot(
  [in] DWORD dwFlags,
  [in] DWORD th32ProcessID
);
#include <iostream>
#include <Windows.h>
#include <Tlhelp32.h>
#include <tchar.h>
#include <string>
#include <stdio.h>
 
HMODULE GetProcessModuleHandle(DWORD pid, CONST TCHAR* moduleName) {    // 根据 PID 、模块名(需要写后缀,如:".dll"),获取模块入口地址
    MODULEENTRY32 moduleEntry;
    HANDLE handle = NULL;
    moudleInfoHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); //  获取进程快照的打开句柄,包含模块信息(TH32CS_SNAPMODULE指定)
    if (!moudleInfoHandle) {
        CloseHandle(moudleInfoHandle);
        return NULL;
    }
    ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
    moduleEntry.dwSize = sizeof(MODULEENTRY32);
    if (!Module32First(moudleInfoHandle, &moduleEntry)) {
        CloseHandle(moudleInfoHandle);
        return NULL;
    }
    do {
        if (_tcscmp(moduleEntry.szModule, moduleName) == 0) {
            CloseHandle(moudleInfoHandle);
            return moduleEntry.hModule;
        }
    } while (Module32Next(moudleInfoHandle, &moduleEntry));
    CloseHandle(moudleInfoHandle);
    return 0;
}
 
int main() {
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  // 进程快照句柄
    PROCESSENTRY32 process = {
        sizeof(PROCESSENTRY32)
    };  // 存放进程快照的结构体
 
    //  遍历进程
    while (Process32Next(hProcessSnap, &process)) {
        // 找到目标进程
        std::string s_szExeFile = process.szExeFile; // char* 转 string
        if (s_szExeFile == "xxx.exe") {
            HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
            if (hProcess)
            {
                HMODULE hMod = GetProcessModuleHandle(process.th32ProcessID, "xxx.dll");
                if (hMod)
                {
                    auto fnAddress = GetProcAddress(hMod, "xxFunc");
                     
                    std::cout << fnAddress <<"        "<< GetLastError();
                }
            }
        }
    }
}
#include <iostream>
#include <Windows.h>
#include <Tlhelp32.h>
#include <tchar.h>
#include <string>
#include <stdio.h>
 
HMODULE GetProcessModuleHandle(DWORD pid, CONST TCHAR* moduleName) {    // 根据 PID 、模块名(需要写后缀,如:".dll"),获取模块入口地址
    MODULEENTRY32 moduleEntry;
    HANDLE handle = NULL;
    moudleInfoHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); //  获取进程快照的打开句柄,包含模块信息(TH32CS_SNAPMODULE指定)
    if (!moudleInfoHandle) {
        CloseHandle(moudleInfoHandle);
        return NULL;
    }
    ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
    moduleEntry.dwSize = sizeof(MODULEENTRY32);
    if (!Module32First(moudleInfoHandle, &moduleEntry)) {
        CloseHandle(moudleInfoHandle);
        return NULL;
    }
    do {
        if (_tcscmp(moduleEntry.szModule, moduleName) == 0) {
            CloseHandle(moudleInfoHandle);
            return moduleEntry.hModule;
        }
    } while (Module32Next(moudleInfoHandle, &moduleEntry));
    CloseHandle(moudleInfoHandle);
    return 0;
}
 
int main() {
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  // 进程快照句柄
    PROCESSENTRY32 process = {
        sizeof(PROCESSENTRY32)
    };  // 存放进程快照的结构体
 
    //  遍历进程
    while (Process32Next(hProcessSnap, &process)) {
        // 找到目标进程
        std::string s_szExeFile = process.szExeFile; // char* 转 string
        if (s_szExeFile == "xxx.exe") {
            HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
            if (hProcess)
            {
                HMODULE hMod = GetProcessModuleHandle(process.th32ProcessID, "xxx.dll");
                if (hMod)
                {
                    auto fnAddress = GetProcAddress(hMod, "xxFunc");
                     
                    std::cout << fnAddress <<"        "<< GetLastError();
                }
            }
        }
    }
}
BOOL EnumProcessModules(
  [in]  HANDLE  hProcess,
  [out] HMODULE *lphModule,
  [in]  DWORD   cb,
  [out] LPDWORD lpcbNeeded
);
BOOL EnumProcessModules(
  [in]  HANDLE  hProcess,
  [out] HMODULE *lphModule,
  [in]  DWORD   cb,
  [out] LPDWORD lpcbNeeded
);
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
 
// 为了确保正确解析符号,需要将 Psapi.lib 添加到 TARGETLIBS,并使用 -DPSAPI_VERSION=1 编译
 
int PrintModules( DWORD processID )
{
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;
 
    // 打印进程标识符。
 
    printf( "\n进程 ID:%u\n", processID );
 
    // 获取进程的句柄。
 
    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                            PROCESS_VM_READ,
                            FALSE, processID );
    if (NULL == hProcess)
        return 1;
    // 获取此进程中所有模块的列表。
 
    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            TCHAR szModName[MAX_PATH];
 
            // 获取模块文件的完整路径。
 
            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,sizeof(szModName) / sizeof(TCHAR)))
            {
                // 打印模块名和句柄值。
 
                _tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
            }
        }
    }
 
    // 释放对进程的句柄。
 
    CloseHandle( hProcess );
 
    return 0;
}
 
int main( void )
{
 
    DWORD aProcesses[1024];
    DWORD cbNeeded;
    DWORD cProcesses;
    unsigned int i;
 
    // 获取进程标识符的列表。
 
    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return 1;
 
    // 计算返回了多少个进程标识符。
 
    cProcesses = cbNeeded / sizeof(DWORD);
 
    // 打印每个进程的模块名称。
 
    for ( i = 0; i < cProcesses; i++ )
    {
        PrintModules( aProcesses[i] );
    }
 
    return 0;
}
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
 
// 为了确保正确解析符号,需要将 Psapi.lib 添加到 TARGETLIBS,并使用 -DPSAPI_VERSION=1 编译
 
int PrintModules( DWORD processID )
{
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;
 
    // 打印进程标识符。
 
    printf( "\n进程 ID:%u\n", processID );
 
    // 获取进程的句柄。
 
    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                            PROCESS_VM_READ,
                            FALSE, processID );
    if (NULL == hProcess)
        return 1;
    // 获取此进程中所有模块的列表。
 
    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            TCHAR szModName[MAX_PATH];
 
            // 获取模块文件的完整路径。
 
            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,sizeof(szModName) / sizeof(TCHAR)))
            {
                // 打印模块名和句柄值。
 
                _tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
            }
        }
    }
 
    // 释放对进程的句柄。
 
    CloseHandle( hProcess );
 
    return 0;
}
 
int main( void )
{
 
    DWORD aProcesses[1024];
    DWORD cbNeeded;
    DWORD cProcesses;
    unsigned int i;
 
    // 获取进程标识符的列表。
 
    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return 1;
 
    // 计算返回了多少个进程标识符。
 
    cProcesses = cbNeeded / sizeof(DWORD);
 
    // 打印每个进程的模块名称。
 
    for ( i = 0; i < cProcesses; i++ )
    {
        PrintModules( aProcesses[i] );
    }
 
    return 0;
}
typedef struct _LDR_DATA_TABLE_ENTRY {
    PVOID Reserved1[2];
    LIST_ENTRY InMemoryOrderLinks;
    PVOID Reserved2[2];
    PVOID DllBase;
    PVOID EntryPoint;
    PVOID Reserved3;
    UNICODE_STRING FullDllName;
    BYTE Reserved4[8];
    PVOID Reserved5[3];
    union {
        ULONG CheckSum;
        PVOID Reserved6;
    };
    ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _LDR_DATA_TABLE_ENTRY {
    PVOID Reserved1[2];
    LIST_ENTRY InMemoryOrderLinks;
    PVOID Reserved2[2];
    PVOID DllBase;
    PVOID EntryPoint;
    PVOID Reserved3;
    UNICODE_STRING FullDllName;
    BYTE Reserved4[8];
    PVOID Reserved5[3];
    union {
        ULONG CheckSum;
        PVOID Reserved6;
    };
    ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
#include "stdafx.h"
 
#include <iostream>
#include <windows.h>
#include <subauth.h>
 
#pragma region 依赖
 
#define NT_SUCCESS(x) ((x) >= 0)
#define ProcessBasicInformation 0
 
typedef
NTSTATUS(WINAPI *pfnNtWow64QueryInformationProcess64)
(HANDLE ProcessHandle, UINT32 ProcessInformationClass,
    PVOID ProcessInformation, UINT32 ProcessInformationLength,
    UINT32* ReturnLength);
  
typedef
NTSTATUS(WINAPI *pfnNtWow64ReadVirtualMemory64)
(HANDLE ProcessHandle, PVOID64 BaseAddress,
    PVOID BufferData, UINT64 BufferLength,
    PUINT64 ReturnLength);
  
typedef
NTSTATUS(WINAPI *pfnNtQueryInformationProcess)
(HANDLE ProcessHandle, ULONG ProcessInformationClass,
    PVOID ProcessInformation, UINT32 ProcessInformationLength,
    UINT32* ReturnLength);
  
template <typename T>
struct _UNICODE_STRING_T
{
    WORD Length;
    WORD MaximumLength;
    T Buffer;
};
  
template <typename T>
struct _LIST_ENTRY_T
{
    T Flink;
    T Blink;
};
  
template <typename T, typename NGF, int A>
struct _PEB_T
{
    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<T> CSDVersion;
    T ActivationContextData;
    T ProcessAssemblyStorageMap;
    T SystemDefaultActivationContextData;
    T SystemAssemblyStorageMap;
    T MinimumStackCommit;
    T FlsCallback;
    _LIST_ENTRY_T<T> FlsListHead;
    T FlsBitmap;
    DWORD FlsBitmapBits[4];
    T FlsHighIndex;
    T WerRegistrationData;
    T WerShipAssertPtr;
    T pContextData;
    T pImageHeaderHash;
    T TracingFlags;
    T CsrServerReadOnlySharedMemoryBase;
};
  
typedef _PEB_T<DWORD, DWORD64, 34> _PEB32;
typedef _PEB_T<DWORD64, DWORD, 30> _PEB64;
  
typedef struct _STRING_32
{
    WORD Length;
    WORD MaximumLength;
    UINT32 Buffer;
} STRING32, *PSTRING32;
  
typedef struct _STRING_64
{
    WORD Length;
    WORD MaximumLength;
    UINT64 Buffer;
} STRING64, *PSTRING64;
  
typedef struct _RTL_DRIVE_LETTER_CURDIR_32
{
    WORD Flags;
    WORD Length;
    ULONG TimeStamp;
    STRING32 DosPath;
} RTL_DRIVE_LETTER_CURDIR32, *PRTL_DRIVE_LETTER_CURDIR32;
  
typedef struct _RTL_DRIVE_LETTER_CURDIR_64
{
    WORD Flags;
    WORD Length;
    ULONG TimeStamp;
    STRING64 DosPath;
} RTL_DRIVE_LETTER_CURDIR64, *PRTL_DRIVE_LETTER_CURDIR64;
  
typedef struct _UNICODE_STRING_32
{
    WORD Length;
    WORD MaximumLength;
    UINT32 Buffer;
} UNICODE_STRING32, *PUNICODE_STRING32;
  
typedef struct _UNICODE_STRING_64
{
    WORD Length;
    WORD MaximumLength;
    UINT64 Buffer;
} UNICODE_STRING64, *PUNICODE_STRING64;
  
  
typedef struct _CURDIR_32
{
    UNICODE_STRING32 DosPath;
    UINT32 Handle;
} CURDIR32, *PCURDIR32;
  
typedef struct _RTL_USER_PROCESS_PARAMETERS_32
{
    ULONG MaximumLength;
    ULONG Length;
    ULONG Flags;
    ULONG DebugFlags;
    UINT32 ConsoleHandle;
    ULONG ConsoleFlags;
    UINT32 StandardInput;
    UINT32 StandardOutput;
    UINT32 StandardError;
    CURDIR32 CurrentDirectory;
    UNICODE_STRING32 DllPath;
    UNICODE_STRING32 ImagePathName;
    UNICODE_STRING32 CommandLine;
    UINT32 Environment;
    ULONG StartingX;
    ULONG StartingY;
    ULONG CountX;
    ULONG CountY;
    ULONG CountCharsX;
    ULONG CountCharsY;
    ULONG FillAttribute;
    ULONG WindowFlags;
    ULONG ShowWindowFlags;
    UNICODE_STRING32 WindowTitle;
    UNICODE_STRING32 DesktopInfo;
    UNICODE_STRING32 ShellInfo;
    UNICODE_STRING32 RuntimeData;
    RTL_DRIVE_LETTER_CURDIR32 CurrentDirectores[32];
    ULONG EnvironmentSize;
} RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32;
  
  
typedef struct _CURDIR_64
{
    UNICODE_STRING64 DosPath;
    UINT64 Handle;
} CURDIR64, *PCURDIR64;
  
typedef struct _RTL_USER_PROCESS_PARAMETERS_64
{
    ULONG MaximumLength;
    ULONG Length;
    ULONG Flags;
    ULONG DebugFlags;
    UINT64 ConsoleHandle;
    ULONG ConsoleFlags;
    UINT64 StandardInput;
    UINT64 StandardOutput;
    UINT64 StandardError;
    CURDIR64 CurrentDirectory;
    UNICODE_STRING64 DllPath;
    UNICODE_STRING64 ImagePathName;
    UNICODE_STRING64 CommandLine;
    UINT64 Environment;
    ULONG StartingX;
    ULONG StartingY;
    ULONG CountX;
    ULONG CountY;
    ULONG CountCharsX;
    ULONG CountCharsY;
    ULONG FillAttribute;
    ULONG WindowFlags;
    ULONG ShowWindowFlags;
    UNICODE_STRING64 WindowTitle;
    UNICODE_STRING64 DesktopInfo;
    UNICODE_STRING64 ShellInfo;
    UNICODE_STRING64 RuntimeData;
    RTL_DRIVE_LETTER_CURDIR64 CurrentDirectores[32];
    ULONG EnvironmentSize;
} RTL_USER_PROCESS_PARAMETERS64, *PRTL_USER_PROCESS_PARAMETERS64;
  
  
  
typedef struct _PROCESS_BASIC_INFORMATION64 {
    NTSTATUS ExitStatus;
    UINT32 Reserved0;
    UINT64 PebBaseAddress;
    UINT64 AffinityMask;
    UINT32 BasePriority;
    UINT32 Reserved1;
    UINT64 UniqueProcessId;
    UINT64 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION64;
  
typedef struct _PROCESS_BASIC_INFORMATION32 {
    NTSTATUS ExitStatus;
    UINT32 PebBaseAddress;
    UINT32 AffinityMask;
    UINT32 BasePriority;
    UINT32 UniqueProcessId;
    UINT32 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION32;
 
#pragma endregion
 
int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE m_ProcessHandle =
        OpenProcess(
            PROCESS_ALL_ACCESS,     // 所有权限
            FALSE,                  // 不继承句柄
            8016                    // 进程ID,此处为了方便直接写死
        );
  
    BOOL bSource = FALSE;           // 判断自身进程是否为 64位
    BOOL bTarget = FALSE;           // 判断目标进程是否为 64位
    IsWow64Process(
        GetCurrentProcess(),        // 进程句柄
        &bSource                    // 用来接收返回值的变量,64位 FLASE | 32位 TRUE
        );
    IsWow64Process(
        m_ProcessHandle,            // 进程句柄
        &bTarget                    // 用来接收返回值的变量,64位 FLASE | 32位 TRUE
        );
 
    // 目标 64位,自身 32位
    if(bTarget == FALSE && bSource == TRUE)
    {
        // 获取 ntdll.dll 模块句柄
        HMODULE NtdllModule = GetModuleHandle("ntdll.dll");
 
        pfnNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfnNtWow64QueryInformationProcess64)GetProcAddress(NtdllModule,"NtWow64QueryInformationProcess64");
        pfnNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(NtdllModule,"NtWow64ReadVirtualMemory64");
        PROCESS_BASIC_INFORMATION64 pbi = {0};
        UINT64 ReturnLength = 0;
        NTSTATUS Status = NtWow64QueryInformationProcess64(m_ProcessHandle,ProcessBasicInformation,&pbi,(UINT32)sizeof(pbi),(UINT32*)&ReturnLength);
  
        if (NT_SUCCESS(Status)){
            _PEB64* Peb = (_PEB64*)malloc(sizeof(_PEB64));
            RTL_USER_PROCESS_PARAMETERS64* ProcessParameters = (RTL_USER_PROCESS_PARAMETERS64*)malloc(sizeof(RTL_USER_PROCESS_PARAMETERS64));
            Status = NtWow64ReadVirtualMemory64(m_ProcessHandle,(PVOID64)pbi.PebBaseAddress,(_PEB64*)Peb,sizeof(_PEB64),&ReturnLength);
             
            std::cout << "PEB地址:" << std::hex << pbi.PebBaseAddress << std::endl;
            //cout << "Ldr:" << hex << Peb->Ldr << endl;
            //cout << "ImageBaseAddress:" << hex << Peb->ImageBaseAddress << endl;
        }
    }
  
    // 目标 32位,自身 32位
    else if (bTarget == TRUE && bSource == TRUE)
    {
        HMODULE NtdllModule = GetModuleHandle("ntdll.dll");
        pfnNtQueryInformationProcess NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(NtdllModule,"NtQueryInformationProcess");
        PROCESS_BASIC_INFORMATION32 pbi = {0};
        UINT32  ReturnLength = 0;
        NTSTATUS Status = NtQueryInformationProcess(m_ProcessHandle,ProcessBasicInformation,&pbi,(UINT32)sizeof(pbi),(UINT32*)&ReturnLength);
         
        if (NT_SUCCESS(Status)){
            _PEB32* Peb = (_PEB32*)malloc(sizeof(_PEB32));
            ReadProcessMemory(m_ProcessHandle, (PVOID)pbi.PebBaseAddress,(_PEB32*)Peb,sizeof(_PEB32),NULL);
            
            std::cout << "PEB地址:" << std::hex << pbi.PebBaseAddress << std::endl;
            //printf("LdrAddress:%x\r\n", ((_PEB32*)Peb)->Ldr);
            //printf("ImageBaseAddress:%x\r\n", ((_PEB32*)Peb)->ImageBaseAddress);
        }
    }
 
    getchar();
    return 0;
}
#include "stdafx.h"
 
#include <iostream>
#include <windows.h>
#include <subauth.h>
 
#pragma region 依赖
 
#define NT_SUCCESS(x) ((x) >= 0)
#define ProcessBasicInformation 0
 
typedef
NTSTATUS(WINAPI *pfnNtWow64QueryInformationProcess64)
(HANDLE ProcessHandle, UINT32 ProcessInformationClass,
    PVOID ProcessInformation, UINT32 ProcessInformationLength,
    UINT32* ReturnLength);
  
typedef
NTSTATUS(WINAPI *pfnNtWow64ReadVirtualMemory64)
(HANDLE ProcessHandle, PVOID64 BaseAddress,
    PVOID BufferData, UINT64 BufferLength,
    PUINT64 ReturnLength);
  
typedef
NTSTATUS(WINAPI *pfnNtQueryInformationProcess)
(HANDLE ProcessHandle, ULONG ProcessInformationClass,
    PVOID ProcessInformation, UINT32 ProcessInformationLength,
    UINT32* ReturnLength);
  
template <typename T>
struct _UNICODE_STRING_T
{
    WORD Length;
    WORD MaximumLength;
    T Buffer;
};
  
template <typename T>
struct _LIST_ENTRY_T
{
    T Flink;
    T Blink;
};
  
template <typename T, typename NGF, int A>
struct _PEB_T
{
    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;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 7527
活跃值: (5362)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
还有一种ZwQueryVirtualMemory查询MemoryBasicInformation->MEM_IMAGE,再ZwQueryVirtualMemory查询MemorySectionName->MEMORY_SECTION_NAME
2023-12-14 02:38
0
雪    币: 3004
活跃值: (30861)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2023-12-14 09:16
1
雪    币: 4492
活跃值: (5119)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
第二种和第三种实际上是同一种
2023-12-14 13:02
0
雪    币: 2903
活跃值: (2839)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
高手,谢谢大佬分享
2023-12-14 14:37
0
游客
登录 | 注册 方可回帖
返回
//