简体   繁体   English

如何使用汇编程序(x64 OS)获取进程环境块(PEB)地址?

[英]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.我正在尝试使用汇编程序获取当前进程的 PEB 地址。

the cpp file: cpp文件:

#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: asm 文件:

.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()!但是我从 GetModuleHandle(0) 和 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)?问:如果函数是外部函数,它会检查调用它的进程的PEB或函数的dll(假设是一个dll)?

Tnx Tnx

If you don't mind C. Works in Microsoft Visual Studio 2015. Uses the "__readgsqword()" intrinsic. 如果您不介意C.可以在Microsoft Visual Studio 2015中使用。使用内在的“ __readgsqword()”。

#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 . 不需要推送/弹出rax因为它是Windows上的临时寄存器或易失性寄存器,请参阅调用者/被调用者保存的寄存器 In particular, rax will hold the return value for your function. 特别是, rax将保存函数的返回值。

It often helps to step through the machine code when you call GetModuleHandle() and compare it with your own assembly code. 当您调用GetModuleHandle()并将其与您自己的汇编代码进行比较时,通常有助于单步执行机器代码。 You'll probably encounter something like this implementation . 您可能会遇到类似这样的实现

Get_Ldr_Addr didnt save your result. Get_Ldr_Addr没有保存您的结果。

you should not protect rax by push and pop because rax is the return value 您不应该通过推和弹出来保护rax,因为rax是返回值

I like Sirmabus' answer but I much prefer it with simple C casts and the offsetof macro:我喜欢 Sirmabus 的回答,但我更喜欢简单的 C 强制转换和 offsetof 宏:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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