6

I want to get the PEB from the "notepad.exe" process. Does someone know how to do it?

I tried the GetModuleHandle API, but it doesn't return a valid pointer (it return zero every time) because I have to be the caller process of that module.

For that reason, I want to know how to get it to work with EnumProcessModules or CreateToolhelp32Snapshot.

riQQ
  • 9,878
  • 7
  • 49
  • 66
Daas Cook
  • 377
  • 1
  • 6
  • 10

1 Answers1

12

Matt Pietrek described how to do that in a 1994 Under the Hood column. It was about how to get the environment variables of another process, where the first step is to get a pointer to the PEB. To do that, he says, call NtQueryInformationProcess. The PROCESS_BASIC_INFORMATION structure it fills contains the base address of the PEB structure. (You'll need to use ReadProcessMemory to read it since the address will be in the context of the external process's address space, not yours.)

To call NtQueryInformationProcess, you'll need a handle to the process. If you started the process yourself (by calling CreateProcess), then you already have a handle. Otherwise, you'll need to find the process ID and then call OpenProcess. To get the process ID, search for the process you want with EnumProcesses or Process32First/Process32Next. (I prefer the latter because it provides more information with less work.)

user1354557
  • 2,413
  • 19
  • 29
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • 5
    It should be noted that a WOW64 process has two PEB's and that complicates things a little bit IIRC – Anders Mar 29 '11 at 14:31
  • 1
    @Anders is correct. `ZwQueryInformationProcess` returns the PEB that matches the bitness of the _calling_ process. In the case where a 32-bit (WOW64) process attempts to retrieve the PEB of a native 64-bit process, `PROCESS_BASIC_INFORMATION.PebBaseAddress` is NULL, since native 64-bit processes have no 32-bit PEB. Also note that the 32-bit and 64-bit PEBs have different structure offsets, so this method would have to be modified for a 64-bit process to successfully read from a 32-bit PEB. – user1354557 Mar 07 '13 at 23:07
  • 1
    There is a comment in the [`NtQueryInformationProcess()`](https://msdn.microsoft.com/en-us/library/ms684280.aspx) documentation that says: "*... when querying a process running under wow64 ... the PebBaseAddress returned is actually for the 64-bit modules loaded under wow64 ... **the PEB which pertains to 32-bit modules can be found by taking the PebBaseAddress and subtracting one page (0x1000) from its value**...*" – Remy Lebeau Jan 12 '16 at 06:00
  • 1
    Apparently that will not work from Windows 8 onward anymore, but [this code](https://groups.google.com/forum/#!topic/dynamorio-users/wf0tcp420m0) provides an alternative that retrieves the 32bit PEB address from the 32bit TEB. – Remy Lebeau Jan 12 '16 at 06:13