基于上一篇文章,大概了解了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[];
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[];
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[];
T FlsHighIndex;
T WerRegistrationData;
T WerShipAssertPtr;
T pContextData;
T pImageHeaderHash;
T TracingFlags;
T CsrServerReadOnlySharedMemoryBase;
}; typedef _PEB_T<DWORD, DWORD64, > _PEB32;
typedef _PEB_T<DWORD64, DWORD, > _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[];
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[];
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;

实现方法:

// 枚举PEB.cpp : 定义控制台应用程序的入口点。
// #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 = { };
UINT64 ReturnLength = ; 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 = { };
UINT32 ReturnLength = ;
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 ;
}

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

如何对PEB结构体不是很清楚,可以用windeg调试一下,attach到进程,然后使用!peb命令。

32位 64位 获得进程peb的方法的更多相关文章

  1. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑

    自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问题.相信有很多人并不是很清楚32位程序与64位程序的区别,以及Program Files (x86),Program Files的区别 ...

  2. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑(很详细,还有自动动手编程探测dll)

    阅读目录 dll文件不匹配导致数据库无法启动 究竟是System32还是SysWow64 区分dll文件32位64位的程序让我倍感迷惑 再次判断究竟是System32还是SysWow64——意想不到的 ...

  3. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑【转发】

    原文地址:http://www.cnblogs.com/hbccdf/archive/2014/03/09/3590916.html 自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问 ...

  4. 最新Internet Download Manager (IDMan) 6.25 Build 20 32位 64位注册破解补丁

    0x00 IDMan介绍 Internet Download Manager提升你的下载速度最多达5倍,安排下载时程,或续传一半的软件.Internet Download Manager的续传功能可以 ...

  5. 笔记:C语言数据类型在32位与64位机器上的字节数

    读<深入理解计算机系统> 第二章 信息的表示与处理 32位与64位的典型值,单位字节 声明 32位机器 64位机器 char 1 1 short int int 4 4 long int ...

  6. [转]oracle odp.net 32位/64位版本的问题

    本文转自:http://www.cnblogs.com/yjmyzz/archive/2011/04/19/2020793.html 如果你的机器上安装了odp.net,且确信machine.conf ...

  7. Win7 下用 VS2015 编译最新 openssl(1.0.2j)包含32、64位debug和release版本的dll、lib(8个版本)

    Win7 64位系统下通过VS2015编译好的最新的OpenSSL(1.0.2j)所有八个版本的链接库, 包含以下八个版本: 1.32位.debug版LIB: 2.32位.release版LIB: 3 ...

  8. GCC下32位与64位机器类型变量所占字节数

    GCC下32位与64位机器类型变量所占字节数 在C语言中,编译器一般根据自身硬件针对类型变量来选择合适的字节大小,下面列举一下在GCC编译器下32位机器与64位机器各个类型变量所占字节数目: C语言 ...

  9. VC9、VC11、VC14、VC15库 32位 64位 免费下载

    VC9.VC11.VC14.VC15库 32位 64位 免费下载 更新版本的PHP是用VC11,VC14或VC15(分别为Visual Studio 2012,2015或2017编译器)构建的,并且包 ...

  10. SQLite在.NET中自适应32位/64位系统

    如果一个.NET应用要自适应32位/64位系统,只需要在项目的“目标平台”设置为“Any CPU”.但是如果应用中使用了SQLite,情况就不同了. SQLite的.NET开发包来自是System.D ...

随机推荐

  1. Oracle运算符收录(易忘记,但是又很重要的运算符)

    Create Table Test6( id ), name ), age ), sex ) ) 1. ||   符 字符串连接字符串,注意:文字和日期一定嵌入在单引号里面 select ID,Nam ...

  2. Centos 7网卡设置

    #yum install net-tools.x86_64 #cd /etc/sysconfig/network-scripts/ #mv ifcfg-eno16780032 ifcfg-eth0 手 ...

  3. 在本地用命令行创建一个git仓库,并推送到远程

    首先,进入的gitStore目录下(没有的话自己创建一个) 1.git init 在gitStore目录下 初始化一个git仓库 2.git add 复制一个文件到gitStore目录下,然后执行gi ...

  4. NOI 2018 酱油记

    转眼离 NOI 2018 已经过了一个星期了,退役的我还是随便来水水吧. 语法.错字之类的可能会很多,但是我也不拘这点小节了. 恭喜 yww, zjt, sk 进队,zwl, myh au , yay ...

  5. 架构实战项目心得(四):使用Nexus配置Maven私有仓库

    一.安装配置Nexus 1.  下载nexus https://www.sonatype.com/download-oss-sonatype 2.  解压:tar -zxfnexus-3.5.2-01 ...

  6. Firebird execute block 批处理

    火鸟的批处理,效率好高,使用简单. execute block as declare variable i ; begin ) do begin :i = :i + ; insert into m_u ...

  7. Reactjs事件处理的三种写法

    目录 前言 1. 在回调函数中使用箭头函数 2. 在构造器中绑定this 3. 使用类字段语法 事件参数的传递. 总结 前言 Reactjs中事件处理,与DOM元素处理类似,但也有一些不同的语法. R ...

  8. .NET Unity IOC框架使用实例

    1.IOC简介 IOC(Inversion of Control), 控制反转 DI (Dependency Injection),依赖注入 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在 ...

  9. springboot+mybatis实现动态切换数据源

    前几天有个需求,需要使用不同的数据源,例如某业务要用A数据源,另一个业务要用B数据源.我上网收集了一些资料整合了一下,虽然最后这个需求不了了之了,但是多数据源动态切换还是蛮好用的,所以记录一下,或许以 ...

  10. python2文件转换为exe可执行文件

    windows下py文件的运行需要安装python,如果是exe文件就可以直接运行 1. 直接在命令行用pip安装 pyinstaller pip install pyinstaller 2 在命令行 ...