获得目标进程PEB,并获得进程各种信息

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

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

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

#include "stdafx.h"
#include<Windows.h>
#include<iostream>
#include <Strsafe.h>
using namespace std;

#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;
};

template <typename T>
struct _STRING_T
{
	WORD Length;
	WORD MaximumLength;
	T    Buffer;
};

template <typename T>
struct _RTL_DRIVE_LETTER_CURDIR_T
{
	WORD         Flags;
	WORD         Length;
	ULONG        TimeStamp;
	_STRING_T<T> DosPath;
};

template <typename T>
struct _CURDIR_T
{
	_UNICODE_STRING_T<T> DosPath;
	T			         Handle;
};

template <typename T>
struct _RTL_USER_PROCESS_PARAMETERS_T
{
	ULONG MaximumLength;
	ULONG Length;
	ULONG Flags;
	ULONG DebugFlags;
	T ConsoleHandle;
	ULONG  ConsoleFlags;
	T StandardInput;
	T StandardOutput;
	T StandardError;
	_CURDIR_T<T> CurrentDirectory;
	_UNICODE_STRING_T<T> DllPath;
	_UNICODE_STRING_T<T> ImagePathName; //进程完整路径
	_UNICODE_STRING_T<T> CommandLine;   //进程命令行
	T Environment;             //环境变量(地址)
	ULONG StartingX;
	ULONG StartingY;
	ULONG CountX;
	ULONG CountY;
	ULONG CountCharsX;
	ULONG CountCharsY;
	ULONG FillAttribute;
	ULONG WindowFlags;
	ULONG ShowWindowFlags;
	_UNICODE_STRING_T<T> WindowTitle;
	_UNICODE_STRING_T<T> DesktopInfo;
	_UNICODE_STRING_T<T> ShellInfo;
	_UNICODE_STRING_T<T> RuntimeData;
	_RTL_DRIVE_LETTER_CURDIR_T<T> CurrentDirectores[32];
	ULONG EnvironmentSize;
};

typedef _PEB_T<DWORD, DWORD64, 34> _PEB32;
typedef _PEB_T<DWORD64, DWORD, 30> _PEB64;
typedef _RTL_USER_PROCESS_PARAMETERS_T<UINT32> _RTL_USER_PROCESS_PARAMETERS32;
typedef _RTL_USER_PROCESS_PARAMETERS_T<UINT64> _RTL_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;


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

int main()
{
	printf("输入进程ID
");
	UINT32 ProcessID;
	cin >> ProcessID;
	HANDLE ProcessHandle = NULL;
	//获得进程句柄
	ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
	PEBInfo PebInfo = {0};
	BOOL bSource = FALSE;
	BOOL bTarget = FALSE;
	//判断自己的位数
	IsWow64Process(GetCurrentProcess(), &bSource);
	//判断目标的位数
	IsWow64Process(ProcessHandle, &bTarget);

	//自己是32  目标64
	if (bTarget == FALSE && bSource == TRUE)
	{
		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(ProcessHandle, ProcessBasicInformation,
			&pbi, (UINT32)sizeof(pbi), (UINT32*)&ReturnLength);

		if (NT_SUCCESS(Status))
		{
			
			_PEB64* Peb = (_PEB64*)malloc(sizeof(_PEB64));
			Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)pbi.PebBaseAddress,
				(_PEB64*)Peb, sizeof(_PEB64), &ReturnLength);	
			_RTL_USER_PROCESS_PARAMETERS64 Parameters64;
			Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Peb->ProcessParameters,
				&Parameters64, sizeof(_RTL_USER_PROCESS_PARAMETERS64), &ReturnLength);

			BYTE* Environment = new BYTE[Parameters64.EnvironmentSize * 2];
			Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Parameters64.Environment, Environment, Parameters64.EnvironmentSize, NULL);
			//赋值
			PebInfo.ImageBaseAddress = Peb->ImageBaseAddress;
			PebInfo.Ldr = Peb->Ldr;
			PebInfo.ProcessHeap = Peb->ProcessHeap;
			PebInfo.ProcessParameters = Peb->ProcessParameters;
			PebInfo.Environment = Parameters64.Environment;

			printf("ImageBaseAddress:0x%x
", PebInfo.ImageBaseAddress);
			printf("Ldr:0x%x
", PebInfo.Ldr);
			printf("ProcessHeap:0x%x
", PebInfo.ProcessHeap);
			printf("ProcessParameters:0x%x
", PebInfo.ProcessParameters);
			printf("Environment:0x%x
", PebInfo.Environment);
			while (Environment != NULL)
			{
				char* v1 = NULL;
				int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)Environment, -1, NULL, 0, NULL, FALSE);
				v1 = new char[DataLength + 1];
				WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)Environment, -1, v1, Parameters64.EnvironmentSize * 2, NULL, FALSE);
				printf("%s
", v1);
				// 指针移动到字符串末尾  
				while (*(WCHAR*)Environment != '')
					Environment += 2;
				Environment += 2;
				// 是否是最后一个字符串  
				if (*Environment == '')
					break;
			}
			BYTE* CommandLine = new BYTE[Parameters64.CommandLine.Length];
			Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Parameters64.CommandLine.Buffer, CommandLine, Parameters64.CommandLine.Length, NULL);
			if (CommandLine != NULL)
			{
				char* v1 = NULL;
				int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)CommandLine, -1, NULL, 0, NULL, FALSE);
				v1 = new char[DataLength];
				WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)CommandLine, -1, v1, Parameters64.CommandLine.Length, NULL, FALSE);
				printf("CommandLine:%s
", v1);
			}
			BYTE* ImagePathName = new BYTE[Parameters64.ImagePathName.Length];
			Status = NtWow64ReadVirtualMemory64(ProcessHandle, (PVOID64)Parameters64.ImagePathName.Buffer, ImagePathName, Parameters64.ImagePathName.Length, NULL);
			if (ImagePathName != NULL)
			{
				char* v1 = NULL;
				int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)ImagePathName, -1, NULL, 0, NULL, FALSE);
				v1 = new char[DataLength];
				WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)ImagePathName, -1, v1, Parameters64.ImagePathName.Length, NULL, FALSE);
				printf("ImagePathName:%s
", v1);
			}
		}
		
	}
	//自己是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(ProcessHandle,
			ProcessBasicInformation, &pbi, (UINT32)sizeof(pbi), (UINT32*)&ReturnLength);

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

			_RTL_USER_PROCESS_PARAMETERS32 Parameters32;

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

			//赋值
			PebInfo.ImageBaseAddress = Peb->ImageBaseAddress;
			PebInfo.Ldr = Peb->Ldr;
			PebInfo.ProcessHeap = Peb->ProcessHeap;
			PebInfo.ProcessParameters = Peb->ProcessParameters;
			PebInfo.Environment = Parameters32.Environment;
			printf("ImageBaseAddress:0x%x
", PebInfo.ImageBaseAddress);
			printf("Ldr:0x%x
", PebInfo.Ldr);
			printf("ProcessHeap:0x%x
", PebInfo.ProcessHeap);
			printf("ProcessParameters:0x%x
", PebInfo.ProcessParameters);
			printf("Environment:0x%x
", PebInfo.Environment);
			while (Environment !=NULL)
			{
				char* v1 = NULL;
				int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)Environment, -1, NULL, 0, NULL, FALSE);
				v1 = new char[DataLength + 1];
				WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)Environment, -1, v1, Parameters32.EnvironmentSize * 2, NULL, FALSE);
				printf("%s
", v1);
				// 指针移动到字符串末尾  
				while (*(WCHAR*)Environment != '')
					Environment +=2;
				Environment += 2;
				// 是否是最后一个字符串  
				if (*Environment == '')
					break;
			}
			
			BYTE* CommandLine = new BYTE[Parameters32.CommandLine.Length];
			Status = ReadProcessMemory(ProcessHandle, (PVOID)Parameters32.CommandLine.Buffer, CommandLine, Parameters32.CommandLine.Length, NULL);
			if (CommandLine != NULL)
			{
				char* v1 = NULL;
				int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)CommandLine, -1, NULL, 0, NULL, FALSE);
				v1 = new char[DataLength];
				WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)CommandLine, -1, v1, Parameters32.CommandLine.Length, NULL, FALSE);
				printf("CommandLine:%s
", v1);
			}
			BYTE* ImagePathName = new BYTE[Parameters32.ImagePathName.Length];
			Status = ReadProcessMemory(ProcessHandle, (PVOID)Parameters32.ImagePathName.Buffer, ImagePathName, Parameters32.ImagePathName.Length, NULL);
			if (ImagePathName != NULL)
			{
				char* v1 = NULL;
				int DataLength = WideCharToMultiByte(CP_ACP, NULL, (WCHAR*)ImagePathName, -1, NULL, 0, NULL, FALSE);
				v1 = new char[DataLength];
				WideCharToMultiByte(CP_OEMCP, NULL, (WCHAR*)ImagePathName, -1, v1, Parameters32.ImagePathName.Length, NULL, FALSE);
				printf("ImagePathName:%s
", v1);
			}
		}
	}	
}


原文地址:https://www.cnblogs.com/Toring/p/6628272.html