看流星社区

 找回密码
 注册账号
查看: 2194|回复: 0

c++ 32位 64位 获得进程peb的方法

[复制链接]

该用户从未签到

发表于 2018-2-27 12:49:21 | 显示全部楼层 |阅读模式

基于上一篇文章,大概了解了peb的获取方法,但是那个方法只能获得当前进程的PEB,不能获得其他的进程的PEB。根据那个思想,获得其他进程PEB则需要注入,得到进程信息,然后进程间通信,将信息返回来,经过考虑,这个方法太复杂。

下面介绍的方法是 用了一个未公开的函数NtQueryInformationProcess,获得进程信息,然后去读对方进程ReadProcessMemory。

结构体是使用的一个模板,从别处借鉴的


  1. #pragma once

  2. #include <Windows.h>
  3. #include <Strsafe.h>
  4. #include <wchar.h>
  5. #include <vector>

  6. #define NT_SUCCESS(x) ((x) >= 0)

  7. #define ProcessBasicInformation 0
  8. typedef
  9. NTSTATUS(WINAPI *pfnNtWow64QueryInformationProcess64)
  10. (HANDLE ProcessHandle, UINT32 ProcessInformationClass,
  11.     PVOID ProcessInformation, UINT32 ProcessInformationLength,
  12.     UINT32* ReturnLength);

  13. typedef
  14. NTSTATUS(WINAPI *pfnNtWow64ReadVirtualMemory64)
  15. (HANDLE ProcessHandle, PVOID64 BaseAddress,
  16.     PVOID BufferData, UINT64 BufferLength,
  17.     PUINT64 ReturnLength);

  18. typedef
  19. NTSTATUS(WINAPI *pfnNtQueryInformationProcess)
  20. (HANDLE ProcessHandle, ULONG ProcessInformationClass,
  21.     PVOID ProcessInformation, UINT32 ProcessInformationLength,
  22.     UINT32* ReturnLength);

  23. template <typename T>
  24. struct _UNICODE_STRING_T
  25. {
  26.     WORD Length;
  27.     WORD MaximumLength;
  28.     T Buffer;
  29. };

  30. template <typename T>
  31. struct _LIST_ENTRY_T
  32. {
  33.     T Flink;
  34.     T Blink;
  35. };

  36. template <typename T, typename NGF, int A>
  37. struct _PEB_T
  38. {
  39.     typedef T type;

  40.     union
  41.     {
  42.         struct
  43.         {
  44.             BYTE InheritedAddressSpace;
  45.             BYTE ReadImageFileExecOptions;
  46.             BYTE BeingDebugged;
  47.             BYTE BitField;
  48.         };
  49.         T dummy01;
  50.     };
  51.     T Mutant;
  52.     T ImageBaseAddress;
  53.     T Ldr;
  54.     T ProcessParameters;
  55.     T SubSystemData;
  56.     T ProcessHeap;
  57.     T FastPebLock;
  58.     T AtlThunkSListPtr;
  59.     T IFEOKey;
  60.     T CrossProcessFlags;
  61.     T UserSharedInfoPtr;
  62.     DWORD SystemReserved;
  63.     DWORD AtlThunkSListPtr32;
  64.     T ApiSetMap;
  65.     T TlsExpansionCounter;
  66.     T TlsBitmap;
  67.     DWORD TlsBitmapBits[2];
  68.     T ReadOnlySharedMemoryBase;
  69.     T HotpatchInformation;
  70.     T ReadOnlyStaticServerData;
  71.     T AnsiCodePageData;
  72.     T OemCodePageData;
  73.     T UnicodeCaseTableData;
  74.     DWORD NumberOfProcessors;
  75.     union
  76.     {
  77.         DWORD NtGlobalFlag;
  78.         NGF dummy02;
  79.     };
  80.     LARGE_INTEGER CriticalSectionTimeout;
  81.     T HeapSegmentReserve;
  82.     T HeapSegmentCommit;
  83.     T HeapDeCommitTotalFreeThreshold;
  84.     T HeapDeCommitFreeBlockThreshold;
  85.     DWORD NumberOfHeaps;
  86.     DWORD MaximumNumberOfHeaps;
  87.     T ProcessHeaps;
  88.     T GdiSharedHandleTable;
  89.     T ProcessStarterHelper;
  90.     T GdiDCAttributeList;
  91.     T LoaderLock;
  92.     DWORD OSMajorVersion;
  93.     DWORD OSMinorVersion;
  94.     WORD OSBuildNumber;
  95.     WORD OSCSDVersion;
  96.     DWORD OSPlatformId;
  97.     DWORD ImageSubsystem;
  98.     DWORD ImageSubsystemMajorVersion;
  99.     T ImageSubsystemMinorVersion;
  100.     T ActiveProcessAffinityMask;
  101.     T GdiHandleBuffer[A];
  102.     T PostProcessInitRoutine;
  103.     T TlsExpansionBitmap;
  104.     DWORD TlsExpansionBitmapBits[32];
  105.     T SessionId;
  106.     ULARGE_INTEGER AppCompatFlags;
  107.     ULARGE_INTEGER AppCompatFlagsUser;
  108.     T pShimData;
  109.     T AppCompatInfo;
  110.     _UNICODE_STRING_T<T> CSDVersion;
  111.     T ActivationContextData;
  112.     T ProcessAssemblyStorageMap;
  113.     T SystemDefaultActivationContextData;
  114.     T SystemAssemblyStorageMap;
  115.     T MinimumStackCommit;
  116.     T FlsCallback;
  117.     _LIST_ENTRY_T<T> FlsListHead;
  118.     T FlsBitmap;
  119.     DWORD FlsBitmapBits[4];
  120.     T FlsHighIndex;
  121.     T WerRegistrationData;
  122.     T WerShipAssertPtr;
  123.     T pContextData;
  124.     T pImageHeaderHash;
  125.     T TracingFlags;
  126.     T CsrServerReadOnlySharedMemoryBase;
  127. };

  128. typedef _PEB_T<DWORD, DWORD64, 34> _PEB32;
  129. typedef _PEB_T<DWORD64, DWORD, 30> _PEB64;

  130. typedef struct _STRING_32
  131. {
  132.     WORD Length;
  133.     WORD MaximumLength;
  134.     UINT32 Buffer;
  135. } STRING32, *PSTRING32;

  136. typedef struct _STRING_64
  137. {
  138.     WORD Length;
  139.     WORD MaximumLength;
  140.     UINT64 Buffer;
  141. } STRING64, *PSTRING64;

  142. typedef struct _RTL_DRIVE_LETTER_CURDIR_32
  143. {
  144.     WORD Flags;
  145.     WORD Length;
  146.     ULONG TimeStamp;
  147.     STRING32 DosPath;
  148. } RTL_DRIVE_LETTER_CURDIR32, *PRTL_DRIVE_LETTER_CURDIR32;

  149. typedef struct _RTL_DRIVE_LETTER_CURDIR_64
  150. {
  151.     WORD Flags;
  152.     WORD Length;
  153.     ULONG TimeStamp;
  154.     STRING64 DosPath;
  155. } RTL_DRIVE_LETTER_CURDIR64, *PRTL_DRIVE_LETTER_CURDIR64;

  156. typedef struct _UNICODE_STRING_32
  157. {
  158.     WORD Length;
  159.     WORD MaximumLength;
  160.     UINT32 Buffer;
  161. } UNICODE_STRING32, *PUNICODE_STRING32;

  162. typedef struct _UNICODE_STRING_64
  163. {
  164.     WORD Length;
  165.     WORD MaximumLength;
  166.     UINT64 Buffer;
  167. } UNICODE_STRING64, *PUNICODE_STRING64;


  168. typedef struct _CURDIR_32
  169. {
  170.     UNICODE_STRING32 DosPath;
  171.     UINT32 Handle;
  172. } CURDIR32, *PCURDIR32;

  173. typedef struct _RTL_USER_PROCESS_PARAMETERS_32
  174. {
  175.     ULONG MaximumLength;
  176.     ULONG Length;
  177.     ULONG Flags;
  178.     ULONG DebugFlags;
  179.     UINT32 ConsoleHandle;
  180.     ULONG ConsoleFlags;
  181.     UINT32 StandardInput;
  182.     UINT32 StandardOutput;
  183.     UINT32 StandardError;
  184.     CURDIR32 CurrentDirectory;
  185.     UNICODE_STRING32 DllPath;
  186.     UNICODE_STRING32 ImagePathName;
  187.     UNICODE_STRING32 CommandLine;
  188.     UINT32 Environment;
  189.     ULONG StartingX;
  190.     ULONG StartingY;
  191.     ULONG CountX;
  192.     ULONG CountY;
  193.     ULONG CountCharsX;
  194.     ULONG CountCharsY;
  195.     ULONG FillAttribute;
  196.     ULONG WindowFlags;
  197.     ULONG ShowWindowFlags;
  198.     UNICODE_STRING32 WindowTitle;
  199.     UNICODE_STRING32 DesktopInfo;
  200.     UNICODE_STRING32 ShellInfo;
  201.     UNICODE_STRING32 RuntimeData;
  202.     RTL_DRIVE_LETTER_CURDIR32 CurrentDirectores[32];
  203.     ULONG EnvironmentSize;
  204. } RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32;


  205. typedef struct _CURDIR_64
  206. {
  207.     UNICODE_STRING64 DosPath;
  208.     UINT64 Handle;
  209. } CURDIR64, *PCURDIR64;

  210. typedef struct _RTL_USER_PROCESS_PARAMETERS_64
  211. {
  212.     ULONG MaximumLength;
  213.     ULONG Length;
  214.     ULONG Flags;
  215.     ULONG DebugFlags;
  216.     UINT64 ConsoleHandle;
  217.     ULONG ConsoleFlags;
  218.     UINT64 StandardInput;
  219.     UINT64 StandardOutput;
  220.     UINT64 StandardError;
  221.     CURDIR64 CurrentDirectory;
  222.     UNICODE_STRING64 DllPath;
  223.     UNICODE_STRING64 ImagePathName;
  224.     UNICODE_STRING64 CommandLine;
  225.     UINT64 Environment;
  226.     ULONG StartingX;
  227.     ULONG StartingY;
  228.     ULONG CountX;
  229.     ULONG CountY;
  230.     ULONG CountCharsX;
  231.     ULONG CountCharsY;
  232.     ULONG FillAttribute;
  233.     ULONG WindowFlags;
  234.     ULONG ShowWindowFlags;
  235.     UNICODE_STRING64 WindowTitle;
  236.     UNICODE_STRING64 DesktopInfo;
  237.     UNICODE_STRING64 ShellInfo;
  238.     UNICODE_STRING64 RuntimeData;
  239.     RTL_DRIVE_LETTER_CURDIR64 CurrentDirectores[32];
  240.     ULONG EnvironmentSize;
  241. } RTL_USER_PROCESS_PARAMETERS64, *PRTL_USER_PROCESS_PARAMETERS64;

  242. typedef struct _PROCESS_BASIC_INFORMATION64 {
  243.     NTSTATUS ExitStatus;
  244.     UINT32 Reserved0;
  245.     UINT64 PebBaseAddress;
  246.     UINT64 AffinityMask;
  247.     UINT32 BasePriority;
  248.     UINT32 Reserved1;
  249.     UINT64 UniqueProcessId;
  250.     UINT64 InheritedFromUniqueProcessId;
  251. } PROCESS_BASIC_INFORMATION64;

  252. typedef struct _PROCESS_BASIC_INFORMATION32 {
  253.     NTSTATUS ExitStatus;
  254.     UINT32 PebBaseAddress;
  255.     UINT32 AffinityMask;
  256.     UINT32 BasePriority;
  257.     UINT32 UniqueProcessId;
  258.     UINT32 InheritedFromUniqueProcessId;
  259. } PROCESS_BASIC_INFORMATION32;
复制代码



实现方法:

  1. #include "stdafx.h"
  2. #include "PEB.h"
  3. #include <iostream>

  4. using namespace std;

  5. int main()
  6. {
  7.     HANDLE m_ProcessHandle;
  8.     int PID;
  9.     cout << "输入PID:";
  10.     cin >> PID;

  11.     m_ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);

  12.     BOOL bSource = FALSE;
  13.     BOOL bTarget = FALSE;
  14.     //判断自己的位数
  15.     IsWow64Process(GetCurrentProcess(), &bSource);
  16.     //判断目标的位数
  17.     IsWow64Process(m_ProcessHandle, &bTarget);

  18.     if(bTarget == FALSE && bSource == TRUE)
  19.     {
  20.         HMODULE NtdllModule = GetModuleHandle(L"ntdll.dll");
  21.         pfnNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfnNtWow64QueryInformationProcess64)GetProcAddress(NtdllModule, "NtWow64QueryInformationProcess64");
  22.         pfnNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(NtdllModule, "NtWow64ReadVirtualMemory64");

  23.         PROCESS_BASIC_INFORMATION64 pbi = { 0 };
  24.         UINT64 ReturnLength = 0;

  25.         NTSTATUS Status = NtWow64QueryInformationProcess64(m_ProcessHandle, ProcessBasicInformation, &pbi, (UINT32)sizeof(pbi), (UINT32*)&ReturnLength);

  26.         if (NT_SUCCESS(Status))
  27.         {

  28.             _PEB64* Peb = (_PEB64*)malloc(sizeof(_PEB64));
  29.             RTL_USER_PROCESS_PARAMETERS64* ProcessParameters = (RTL_USER_PROCESS_PARAMETERS64*)malloc(sizeof(RTL_USER_PROCESS_PARAMETERS64));
  30.             Status = NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)pbi.PebBaseAddress,
  31.                 (_PEB64*)Peb, sizeof(_PEB64), &ReturnLength);


  32.             cout << "PebBaseAddress:" << hex << pbi.PebBaseAddress << endl;
  33.             cout << "Ldr:" << hex << Peb->Ldr << endl;
  34.             cout << "ImageBaseAddress:" << hex << Peb->ImageBaseAddress << endl;
  35.         }
  36.     }

  37.     //自己是32  目标是32
  38.     else if (bTarget == TRUE && bSource == TRUE)
  39.     {
  40.         HMODULE NtdllModule = GetModuleHandle(L"ntdll.dll");
  41.         pfnNtQueryInformationProcess NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(NtdllModule,
  42.             "NtQueryInformationProcess");
  43.         PROCESS_BASIC_INFORMATION32 pbi = { 0 };
  44.         UINT32  ReturnLength = 0;
  45.         NTSTATUS Status = NtQueryInformationProcess(m_ProcessHandle,
  46.             ProcessBasicInformation, &pbi, (UINT32)sizeof(pbi), (UINT32*)&ReturnLength);
  47.         if (NT_SUCCESS(Status))
  48.         {
  49.             _PEB32* Peb = (_PEB32*)malloc(sizeof(_PEB32));
  50.             ReadProcessMemory(m_ProcessHandle, (PVOID)pbi.PebBaseAddress, (_PEB32*)Peb, sizeof(_PEB32), NULL);
  51.             printf("PEB:%x\r\n", pbi.PebBaseAddress);
  52.             printf("LdrAddress:%x\r\n", ((_PEB32*)Peb)->Ldr);
  53.             printf("ImageBaseAddress:%x\r\n", ((_PEB32*)Peb)->ImageBaseAddress);
  54.         }
  55.     }

  56.     return 0;
  57. }
复制代码


有了PEB 则可以获得进程的各种信息,比如:模块、完整路径、命令行、环境变量、默认堆等等,参照结构体可得。

如何对PEB结构体不是很清楚,可以用windeg调试一下,attach到进程,然后使用!peb命令。
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-28 17:51

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表