如何使用汇编程序 (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
只有两条评论。
不需要 push/pop rax
因为它是 Windows 上的暂存器或易失性寄存器,请参阅 caller/callee saved registers。特别是,rax
将为您的函数保留 return 值。
调用 GetModuleHandle() and compare it with your own assembly code. You'll probably encounter something like this implementation 时单步执行机器代码通常很有帮助。
Get_Ldr_Addr 没有保存您的结果。
你不应该通过 push 和 pop 来保护 rax 因为 rax 是 return 值
如果您不介意 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 的回答,但我更喜欢简单的 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;
}
我正在尝试使用汇编程序获取当前进程的 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
只有两条评论。
不需要 push/pop rax
因为它是 Windows 上的暂存器或易失性寄存器,请参阅 caller/callee saved registers。特别是,rax
将为您的函数保留 return 值。
调用 GetModuleHandle() and compare it with your own assembly code. You'll probably encounter something like this implementation 时单步执行机器代码通常很有帮助。
Get_Ldr_Addr 没有保存您的结果。
你不应该通过 push 和 pop 来保护 rax 因为 rax 是 return 值
如果您不介意 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 的回答,但我更喜欢简单的 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;
}