0

I'm currently trying to retrieve the Image Base Address of a suspended 32-bits process.

I successfully retrieved the PEB VA by using (*CTX).Ebx - 0x1000 (where CTX is the CONTEXT structure retrieved with GetThreadContext()), it's in correlation with the data I got from some process analysis tools.

The problem is that the field ImageBaseAddress at offset 0x08 is equal to 0xffffffff. I verified and all the other fields are okay, if for example I create the process in debug mode the BeingDebugged byte is set to 1 etc...

And if I look with some tools where the Image of the PE is loaded I see that it's at 0x880000, unfortunately that data isn't present in the PEB.

So I basically tried to create a "normal" process that isn't suspended but I have the same problem.

All the fiels of the PEB are fine, the process too, there's just that 32-bits integer at offset 0x08 that is equal to 0xffffffff for some mysterious reasons.

(P.S.: I know that the PEB isn't documented and that it is not a great idea to depend of it as it's fields might change in the future but I really need to get the Image Base Address of a suspended process from it's PEB).

Thanks.

  • What is `CTX` in this situation? – Remy Lebeau Dec 29 '19 at 17:15
  • 1
    you need get *PEB* base address via `PROCESS_BASIC_INFORMATION` - `NtQueryInformationProcess(, ProcessBasicInformation)`. but not from `Ebx`. the data in peb of course correct – RbMm Dec 29 '19 at 17:23
  • Oh excuse me, CTX is just the context structure retrieved from GetThreadContext (how did I forgot to tell that). I edited the question – Aleister Crowley Dec 29 '19 at 17:46
  • @AleisterCrowley - this is wrong by design way, use context. use `NtQueryInformationProcess(, ProcessBasicInformation)` – RbMm Dec 29 '19 at 17:48
  • But the question isn't how I got the PEB VA, it's valid, even if I simply dump the PEB structure with some process analysis tools, the field I'm talking about is still "corrupted". And no, you can get the PEB base address of a process at EBX after using GetThreadContext. – Aleister Crowley Dec 29 '19 at 17:49
  • this is bad way (in all sense) get peb address of process. and `ImageBaseAddress` not corrupted in peb. answer - was error in your code. util you not show your code - impossible say more – RbMm Dec 29 '19 at 17:55
  • If the PEB you are accessing is in another process, you can't just access it directly, you must use `ReadProcessMemory()` to read it. See [pointer to baseAddress through CONTEXT.Ebx+8](https://stackoverflow.com/questions/12808516/) – Remy Lebeau Dec 29 '19 at 19:09
  • ...I actually know that the PEB of another process isn't present in my own address space thanks. I actually use `ReadProcessMemory()` for sure. My program is perfectly working as all the other forensic tools I used to dump the PEB of those processes. The thing is that the field `ImageBaseAddress` at offset 0x8 is equal to `0xffffffff`. You maybe need some screeshots or others ? – Aleister Crowley Dec 29 '19 at 21:10
  • 1
    @AleisterCrowley - ImageBaseAddress not 0xffffffff in the PEB – RbMm Dec 29 '19 at 21:15
  • 1
    @AleisterCrowley yes, we need screenshots showing what you are seeing, as well as your actual code that is accessing the PEB – Remy Lebeau Dec 30 '19 at 02:25

1 Answers1

0

Use NtQueryInformationProcess with the ProcessBasicInformation, the resulting PROCESS_BASIC_INFORMATION structure will contain the correct peb address.

typedef NTSTATUS(__stdcall* tNtQueryInformationProcess)
(
    HANDLE ProcessHandle,
    PROCESSINFOCLASS ProcessInformationClass,
    PVOID ProcessInformation,
    ULONG ProcessInformationLength,
    PULONG ReturnLength
    );

PEB GetPEBExternal(HANDLE hProc)
{
    PROCESS_BASIC_INFORMATION pbi;
    PEB peb = { 0 };

    tNtQueryInformationProcess NtQueryInformationProcess =
        (tNtQueryInformationProcess)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess");

    NTSTATUS status = NtQueryInformationProcess(hProc, ProcessBasicInformation, &pbi, sizeof(pbi), 0);

    if (NT_SUCCESS(status))
    {
        ReadProcessMemory(hProc, pbi.PebBaseAddress, &peb, sizeof(peb), 0);
    }

    return peb;
}

PEB peb = GetPEBExternal(hProc);

std::cout << "0x" << std::hex << peb.ImageBaseAddress << std::endl;

Use the PEB definition from x64dbg source code, it's the best source for undocumented structures in my experience.

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59