我试图用汇编程序获取当前进程的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
答案 0 :(得分:3)
如果你不介意C.在Microsoft Visual Studio 2015中工作。 使用&#34; __ readgsqword()&#34;本征的。
#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;
答案 1 :(得分:2)
只有两条评论。
无需推/弹rax
因为它是Windows上的临时或易失性寄存器,请参阅caller/callee saved registers。特别是,rax
将保存函数的返回值。
当您致电GetModuleHandle()并将其与您自己的汇编代码进行比较时,通常会帮助您逐步完成机器代码。您可能会遇到类似this implementation的内容。
答案 2 :(得分:1)
Get_Ldr_Addr没有保存您的结果。
你不应该通过推送和弹出来保护rax,因为rax是返回值