- 注册时间
- 2021-4-16
- 最后登录
- 2024-7-7
- 在线时间
- 4 小时
编程入门
- 龙马币
- 32
|
基于上一篇文章,大概了解了peb的获取方法,但是那个方法只能获得当前进程的PEB,不能获得其他的进程的PEB。根据那个思想,获得其他进程PEB则需要注入,得到进程信息,然后进程间通信,将信息返回来,经过考虑,这个方法太复杂。
下面介绍的方法是 用了一个未公开的函数NtQueryInformationProcess,获得进程信息,然后去读对方进程ReadProcessMemory。
结构体是使用的一个模板,从别处借鉴的
- #pragma once
- #include <Windows.h>
- #include <Strsafe.h>
- #include <wchar.h>
- #include <vector>
- #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;<a id="e_postbg" adv="1" title="帖子背景">Background</a>
- 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;
复制代码
实现方法:
- #include "stdafx.h"
- #include "PEB.h"
- #include <iostream>
- using namespace std;
- int main()
- {
- HANDLE m_ProcessHandle;
- int PID;
- cout << "输入PID:";
- cin >> PID;
- m_ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
- BOOL bSource = FALSE;
- BOOL bTarget = FALSE;
- //判断自己的位数
- IsWow64Process(GetCurrentProcess(), &bSource);
- //判断目标的位数
- IsWow64Process(m_ProcessHandle, &bTarget);
- if(bTarget == FALSE && bSource == TRUE)
- {
- HMODULE NtdllModule = GetModuleHandle(L"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);
- cout << "PebBaseAddress:" << hex << pbi.PebBaseAddress << endl;
- cout << "Ldr:" << hex << Peb->Ldr << endl;
- cout << "ImageBaseAddress:" << hex << Peb->ImageBaseAddress << endl;
- }
- }
- //自己是32 目标是32
- else if (bTarget == TRUE && bSource == TRUE)
- {
- HMODULE NtdllModule = GetModuleHandle(L"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);
- printf("PEB:%x\r\n", pbi.PebBaseAddress);
- printf("LdrAddress:%x\r\n", ((_PEB32*)Peb)->Ldr);
- printf("ImageBaseAddress:%x\r\n", ((_PEB32*)Peb)->ImageBaseAddress);
- }
- }
- return 0;
- }
复制代码
有了PEB 则可以获得进程的各种信息,比如:模块、完整路径、命令行、环境变量、默认堆等等,参照结构体可得。
如何对PEB结构体不是很清楚,可以用windeg调试一下,attach到进程,然后使用!peb命令。 |
|