簡體   English   中英

如何使用匯編程序(x64 OS)獲取進程環境塊(PEB)地址?

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

我正在嘗試使用匯編程序獲取當前進程的 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() 得到了不同的地址!

問題是什么? 不應該是一樣的嗎?

問:如果函數是外部函數,它會檢查調用它的進程的PEB或函數的dll(假設是一個dll)?

Tnx

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

僅兩個評論。

不需要推送/彈出rax因為它是Windows上的臨時寄存器或易失性寄存器,請參閱調用者/被調用者保存的寄存器 特別是, rax將保存函數的返回值。

當您調用GetModuleHandle()並將其與您自己的匯編代碼進行比較時,通常有助於單步執行機器代碼。 您可能會遇到類似這樣的實現

Get_Ldr_Addr沒有保存您的結果。

您不應該通過推和彈出來保護rax,因為rax是返回值

我喜歡 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