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

新手上路,请多包涵

我正在尝试使用汇编程序获取当前进程的 PEB 地址。

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

asm 文件:

 .code

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

end

但是我从 GetModuleHandle(0) 和 Get_Ldr_Addr() 得到不同的地址!

问题是什么?不应该是一样的吗?

问:如果函数是外部的,它会检查调用它的进程或函数的dll(假设是dll)的PEB?

肿瘤坏死因子

原文由 Oriel Cochavi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 902
2 个回答

就两条评论。

无需推送/弹出 rax 因为它是 Windows 上的临时或易失性寄存器,请参阅 调用者/被调用者保存的寄存器。特别是, rax 将保存您的函数的返回值。

当您调用 GetModuleHandle() 并将其与您自己的汇编代码进行比较时,它通常有助于单步执行机器代码。您可能会遇到类似 这样的实现

原文由 Jens 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果您不介意 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;

原文由 Sirmabus 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题