简体   繁体   中英

How to get the Process Environment Block (PEB) address using assembler (x64 OS)?

I'm trying to get PEB address of the current process with assembler.

the cpp file:

#include <iostream>
//#include <windows.h>

extern "C" int* __ptr64 Get_Ldr_Addr();

int main(int argc, char **argv)
{
    std::cout << "asm     " << Get_Ldr_Addr() << "\n";
    //std::cout <<"peb     "<< GetModuleHandle(0) << "\n";

    return 0;
}

the asm file:

.code

Get_Ldr_Addr proc
    push rax
    mov rax, GS:[30h]
    mov rax, [rax + 60h]
    pop rax
    ret
Get_Ldr_Addr endp

end

But I get different addresses from the GetModuleHandle(0) and the Get_Ldr_Addr()!

what is the problem? doesn't is suppose to be the same?

Q: If the function is external, it will check the PEB of the process that called it or of the function's dll (it suppose to be a dll)?

Tnx

If you don't mind C. Works in Microsoft Visual Studio 2015. Uses the "__readgsqword()" intrinsic.

#include <winnt.h>
#include <winternl.h>

// Thread Environment Block (TEB)
#if defined(_M_X64) // x64
PTEB tebPtr = reinterpret_cast<PTEB>(__readgsqword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#else // x86
PTEB tebPtr = reinterpret_cast<PTEB>(__readfsdword(reinterpret_cast<DWORD_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#endif

// Process Environment Block (PEB)
PPEB pebPtr = tebPtr->ProcessEnvironmentBlock;

Just two comments.

No need to push/pop rax because it's a scratch or volatile register on Windows, see the caller/callee saved registers . In particular, rax will hold the return value for your function.

It often helps to step through the machine code when you call GetModuleHandle() and compare it with your own assembly code. You'll probably encounter something like this implementation .

Get_Ldr_Addr didnt save your result.

you should not protect rax by push and pop because rax is the return value

I like Sirmabus' answer but I much prefer it with simple C casts and the offsetof macro:

PPEB get_peb()
{
#if defined(_M_X64) // x64
    PTEB tebPtr = (PTEB)__readgsqword(offsetof(NT_TIB, Self));
#else // x86
    PTEB tebPtr = (PTEB)__readfsdword(offsetof(NT_TIB, Self));
#endif
    return tebPtr->ProcessEnvironmentBlock;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM