看流星社区

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

C++ 获取x64和x86程序PEB,及环境变量。

[复制链接]

该用户从未签到

发表于 2018-2-28 11:38:04 | 显示全部楼层 |阅读模式

本程序可完美获得x64和x86程序PEB,及环境变量等信息。

程序首先用OpenProcess打开目标进程,然后用Ntddl.dll导入表中微软未公开函数NtWow64QueryInformationProcess64(NtQueryInformationProcess)、NtWow64ReadVirtualMemory64(ReadProcessMemory)来获得目标进程信息。


  1. // EnumPEB.cpp : 定义控制台应用程序的入口点。

  2. #include "stdafx.h"
  3. #include<Windows.h>
  4. #include<iostream>
  5. #include <Strsafe.h>
  6. using namespace std;

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

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

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

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

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

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

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

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

  129. template <typename T>
  130. struct _STRING_T
  131. {
  132.         WORD Length;
  133.         WORD MaximumLength;
  134.         T    Buffer;
  135. };

  136. template <typename T>
  137. struct _RTL_DRIVE_LETTER_CURDIR_T
  138. {
  139.         WORD         Flags;
  140.         WORD         Length;
  141.         ULONG        TimeStamp;
  142.         _STRING_T<T> DosPath;
  143. };

  144. template <typename T>
  145. struct _CURDIR_T
  146. {
  147.         _UNICODE_STRING_T<T> DosPath;
  148.         T                                 Handle;
  149. };

  150. template <typename T>
  151. struct _RTL_USER_PROCESS_PARAMETERS_T
  152. {
  153.         ULONG MaximumLength;
  154.         ULONG Length;
  155.         ULONG Flags;
  156.         ULONG DebugFlags;
  157.         T ConsoleHandle;
  158.         ULONG  ConsoleFlags;
  159.         T StandardInput;
  160.         T StandardOutput;
  161.         T StandardError;
  162.         _CURDIR_T<T> CurrentDirectory;
  163.         _UNICODE_STRING_T<T> DllPath;
  164.         _UNICODE_STRING_T<T> ImagePathName; //进程完整路径
  165.         _UNICODE_STRING_T<T> CommandLine;   //进程命令行
  166.         T Environment;             //环境变量(地址)
  167.         ULONG StartingX;
  168.         ULONG StartingY;
  169.         ULONG CountX;
  170.         ULONG CountY;
  171.         ULONG CountCharsX;
  172.         ULONG CountCharsY;
  173.         ULONG FillAttribute;
  174.         ULONG WindowFlags;
  175.         ULONG ShowWindowFlags;
  176.         _UNICODE_STRING_T<T> WindowTitle;
  177.         _UNICODE_STRING_T<T> DesktopInfo;
  178.         _UNICODE_STRING_T<T> ShellInfo;
  179.         _UNICODE_STRING_T<T> RuntimeData;
  180.         _RTL_DRIVE_LETTER_CURDIR_T<T> CurrentDirectores[32];
  181.         ULONG EnvironmentSize;
  182. };

  183. typedef _PEB_T<DWORD, DWORD64, 34> _PEB32;
  184. typedef _PEB_T<DWORD64, DWORD, 30> _PEB64;
  185. typedef _RTL_USER_PROCESS_PARAMETERS_T<UINT32> _RTL_USER_PROCESS_PARAMETERS32;
  186. typedef _RTL_USER_PROCESS_PARAMETERS_T<UINT64> _RTL_USER_PROCESS_PARAMETERS64;

  187. typedef struct _PROCESS_BASIC_INFORMATION64 {
  188.         NTSTATUS ExitStatus;
  189.         UINT32 Reserved0;
  190.         UINT64 PebBaseAddress;
  191.         UINT64 AffinityMask;
  192.         UINT32 BasePriority;
  193.         UINT32 Reserved1;
  194.         UINT64 UniqueProcessId;
  195.         UINT64 InheritedFromUniqueProcessId;
  196. } PROCESS_BASIC_INFORMATION64;

  197. typedef struct _PROCESS_BASIC_INFORMATION32 {
  198.         NTSTATUS ExitStatus;
  199.         UINT32 PebBaseAddress;
  200.         UINT32 AffinityMask;
  201.         UINT32 BasePriority;
  202.         UINT32 UniqueProcessId;
  203.         UINT32 InheritedFromUniqueProcessId;
  204. } PROCESS_BASIC_INFORMATION32;


  205. typedef struct _PEB_INFO {
  206.         UINT64 ImageBaseAddress;  //进程加载基地址
  207.         UINT64 Ldr;               //模块加载基地址
  208.         UINT64 ProcessHeap;       //进程默认堆
  209.         UINT64 ProcessParameters; //进程信息
  210.         UINT64 Environment;       //环境变量
  211. }PEBInfo,*PPEBInfo;

  212. int main()
  213. {
  214.         printf("输入进程ID\r\n");
  215.         UINT32 ProcessID;
  216.         cin >> ProcessID;
  217.         HANDLE ProcessHandle = NULL;
  218.         //获得进程句柄
  219.         ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
  220.         PEBInfo PebInfo = {0};
  221.         BOOL bSource = FALSE;
  222.         BOOL bTarget = FALSE;
  223.         //判断自己的位数
  224.         IsWow64Process(GetCurrentProcess(), &bSource);
  225.         //判断目标的位数
  226.         IsWow64Process(ProcessHandle, &bTarget);

  227.         //自己是32  目标64
  228.         if (bTarget == FALSE && bSource == TRUE)
  229.         {
  230.                 HMODULE NtdllModule = GetModuleHandle("ntdll.dll");
  231.                 pfnNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfnNtWow64QueryInformationProcess64)GetProcAddress(NtdllModule,
  232.                         "NtWow64QueryInformationProcess64");
  233.         
  234.                 pfnNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(NtdllModule, "NtWow64ReadVirtualMemory64");
  235.                 PROCESS_BASIC_INFORMATION64 pbi = { 0 };
  236.                 UINT64 ReturnLength = 0;
  237.                 NTSTATUS Status = NtWow64QueryInformationProcess64(ProcessHandle, ProcessBasicInformation,
  238.                         &pbi, (UINT32)sizeof(pbi), (UINT32*)&ReturnLength);

  239.                 if (NT_SUCCESS(Status))
  240.                 {
  241.                         
  242.                         _PEB64* Peb = (_PEB64*)malloc(sizeof(_PEB64));
  243.                         Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)pbi.PebBaseAddress,
  244.                                 (_PEB64*)Peb, sizeof(_PEB64), &ReturnLength);        
  245.                         _RTL_USER_PROCESS_PARAMETERS64 Parameters64;
  246.                         Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Peb->ProcessParameters,
  247.                                 &Parameters64, sizeof(_RTL_USER_PROCESS_PARAMETERS64), &ReturnLength);

  248.                         BYTE* Environment = new BYTE[Parameters64.EnvironmentSize * 2];
  249.                         Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Parameters64.Environment, Environment, Parameters64.EnvironmentSize, NULL);
  250.                         //赋值
  251.                         PebInfo.ImageBaseAddress = Peb->ImageBaseAddress;
  252.                         PebInfo.Ldr = Peb->Ldr;
  253.                         PebInfo.ProcessHeap = Peb->ProcessHeap;
  254.                         PebInfo.ProcessParameters = Peb->ProcessParameters;
  255.                         PebInfo.Environment = Parameters64.Environment;

  256.                         printf("ImageBaseAddress:0x%x\r\n", PebInfo.ImageBaseAddress);
  257.                         printf("Ldr:0x%x\r\n", PebInfo.Ldr);
  258.                         printf("ProcessHeap:0x%x\r\n", PebInfo.ProcessHeap);
  259.                         printf("ProcessParameters:0x%x\r\n", PebInfo.ProcessParameters);
  260.                         printf("Environment:0x%x\r\n", PebInfo.Environment);
  261.                         while (Environment != NULL)
  262.                         {
  263.                                 char* v1 = NULL;
  264.                                 int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)Environment, -1, NULL, 0, NULL, FALSE);
  265.                                 v1 = new char[DataLength + 1];
  266.                                 WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)Environment, -1, v1, Parameters64.EnvironmentSize * 2, NULL, FALSE);
  267.                                 printf("%s\r\n", v1);
  268.                                 // 指针移动到字符串末尾  
  269.                                 while (*(WCHAR*)Environment != '\0')
  270.                                         Environment += 2;
  271.                                 Environment += 2;
  272.                                 // 是否是最后一个字符串  
  273.                                 if (*Environment == '\0')
  274.                                         break;
  275.                         }
  276.                         BYTE* CommandLine = new BYTE[Parameters64.CommandLine.Length];
  277.                         Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Parameters64.CommandLine.Buffer, CommandLine, Parameters64.CommandLine.Length, NULL);
  278.                         if (CommandLine != NULL)
  279.                         {
  280.                                 char* v1 = NULL;
  281.                                 int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)CommandLine, -1, NULL, 0, NULL, FALSE);
  282.                                 v1 = new char[DataLength];
  283.                                 WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)CommandLine, -1, v1, Parameters64.CommandLine.Length, NULL, FALSE);
  284.                                 printf("CommandLine:%s\r\n", v1);
  285.                         }
  286.                         BYTE* ImagePathName = new BYTE[Parameters64.ImagePathName.Length];
  287.                         Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Parameters64.ImagePathName.Buffer, ImagePathName, Parameters64.ImagePathName.Length, NULL);
  288.                         if (ImagePathName != NULL)
  289.                         {
  290.                                 char* v1 = NULL;
  291.                                 int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)ImagePathName, -1, NULL, 0, NULL, FALSE);
  292.                                 v1 = new char[DataLength];
  293.                                 WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)ImagePathName, -1, v1, Parameters64.ImagePathName.Length, NULL, FALSE);
  294.                                 printf("ImagePathName:%s\r\n", v1);
  295.                         }
  296.                 }
  297.                
  298.         }
  299.         //自己是32  目标是32
  300.         else if (bTarget == TRUE && bSource == TRUE)
  301.         {
  302.                 HMODULE NtdllModule = GetModuleHandle("ntdll.dll");
  303.                 pfnNtQueryInformationProcess NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(NtdllModule,
  304.                         "NtQueryInformationProcess");
  305.                 PROCESS_BASIC_INFORMATION32 pbi = { 0 };
  306.                 UINT32  ReturnLength = 0;
  307.                 NTSTATUS Status = NtQueryInformationProcess(ProcessHandle,
  308.                         ProcessBasicInformation, &pbi, (UINT32)sizeof(pbi), (UINT32*)&ReturnLength);

  309.                 if (NT_SUCCESS(Status))
  310.                 {
  311.                         _PEB32* Peb = (_PEB32*)malloc(sizeof(_PEB32));
  312.                         Status  = ReadProcessMemory(ProcessHandle, (PVOID)pbi.PebBaseAddress, (_PEB32*)Peb, sizeof(_PEB32), NULL);

  313.                         _RTL_USER_PROCESS_PARAMETERS32 Parameters32;

  314.                         Status = ReadProcessMemory(ProcessHandle, (PVOID)Peb->ProcessParameters, &Parameters32, sizeof(_RTL_USER_PROCESS_PARAMETERS32), NULL);
  315.                         BYTE* Environment = new BYTE[Parameters32.EnvironmentSize*2];
  316.                         Status = ReadProcessMemory(ProcessHandle, (PVOID)Parameters32.Environment, Environment, Parameters32.EnvironmentSize, NULL);

  317.                         //赋值
  318.                         PebInfo.ImageBaseAddress = Peb->ImageBaseAddress;
  319.                         PebInfo.Ldr = Peb->Ldr;
  320.                         PebInfo.ProcessHeap = Peb->ProcessHeap;
  321.                         PebInfo.ProcessParameters = Peb->ProcessParameters;
  322.                         PebInfo.Environment = Parameters32.Environment;
  323.                         printf("ImageBaseAddress:0x%x\r\n", PebInfo.ImageBaseAddress);
  324.                         printf("Ldr:0x%x\r\n", PebInfo.Ldr);
  325.                         printf("ProcessHeap:0x%x\r\n", PebInfo.ProcessHeap);
  326.                         printf("ProcessParameters:0x%x\r\n", PebInfo.ProcessParameters);
  327.                         printf("Environment:0x%x\r\n", PebInfo.Environment);
  328.                         while (Environment !=NULL)
  329.                         {
  330.                                 char* v1 = NULL;
  331.                                 int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)Environment, -1, NULL, 0, NULL, FALSE);
  332.                                 v1 = new char[DataLength + 1];
  333.                                 WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)Environment, -1, v1, Parameters32.EnvironmentSize * 2, NULL, FALSE);
  334.                                 printf("%s\r\n", v1);
  335.                                 // 指针移动到字符串末尾  
  336.                                 while (*(WCHAR*)Environment != '\0')
  337.                                         Environment +=2;
  338.                                 Environment += 2;
  339.                                 // 是否是最后一个字符串  
  340.                                 if (*Environment == '\0')
  341.                                         break;
  342.                         }
  343.                         
  344.                         BYTE* CommandLine = new BYTE[Parameters32.CommandLine.Length];
  345.                         Status = ReadProcessMemory(ProcessHandle, (PVOID)Parameters32.CommandLine.Buffer, CommandLine, Parameters32.CommandLine.Length, NULL);
  346.                         if (CommandLine != NULL)
  347.                         {
  348.                                 char* v1 = NULL;
  349.                                 int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)CommandLine, -1, NULL, 0, NULL, FALSE);
  350.                                 v1 = new char[DataLength];
  351.                                 WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)CommandLine, -1, v1, Parameters32.CommandLine.Length, NULL, FALSE);
  352.                                 printf("CommandLine:%s\r\n", v1);
  353.                         }
  354.                         BYTE* ImagePathName = new BYTE[Parameters32.ImagePathName.Length];
  355.                         Status = ReadProcessMemory(ProcessHandle, (PVOID)Parameters32.ImagePathName.Buffer, ImagePathName, Parameters32.ImagePathName.Length, NULL);
  356.                         if (ImagePathName != NULL)
  357.                         {
  358.                                 char* v1 = NULL;
  359.                                 int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)ImagePathName, -1, NULL, 0, NULL, FALSE);
  360.                                 v1 = new char[DataLength];
  361.                                 WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)ImagePathName, -1, v1, Parameters32.ImagePathName.Length, NULL, FALSE);
  362.                                 printf("ImagePathName:%s\r\n", v1);
  363.                         }
  364.                 }
  365.         }        
  366. }
复制代码
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

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

GMT+8, 2024-4-25 13:54

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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