访问 x64 TEB C++ 和汇编
Posted
技术标签:
【中文标题】访问 x64 TEB C++ 和汇编【英文标题】:Access x64 TEB C++ & Assembly 【发布时间】:2014-03-25 06:19:51 【问题描述】:在 32 位汇编中,我可以访问 TEB
结构的 ProcessEnvironmentBlock
。从那里我访问TEB
结构的Ldr
。
这里描述了这种技术:http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
在 32 位汇编中执行此操作的代码是:
void* ptr = NULL;
__asm
mov eax, FS:[0x18]
mov eax, [eax + 0x30] //Offset of PEB
mov eax, [eax + 0x0C] //Offset of LDR in PEB structure
mov eax, _ptr
;
std::cout<<ptr<<"\n";
TEB 结构可以在这里看到:http://msdn.moonsols.com/win7rtm_x64/TEB.html 并且可以在这里看到PEB结构:http://msdn.moonsols.com/win7rtm_x64/PEB.html
以上适用于 32 位代码。
但是,我还想编写在 x64 机器上工作的代码。我查看了 x64 版本的结构并写道:
__asm
mov rax, GS:[0x30]
mov rax, [rax + 0x60]
mov rax, [rax + 0x18]
mov rax, _ptr
;
这可以使用 Winnt.h
NtCurrentTeb()
来完成,但我想使用汇编。
但是,它根本无法工作。任何想法为什么?
【问题讨论】:
您是否追踪到NtCurrentTeb
并检查偏移量以确保它们实际上是正确的?
失败意味着_ptr
的值与NTCurrentTeb
不同。我会追踪它并再次检查。我相当肯定我做对了。
您是从 64 位进程还是 32 位进程(WOW)读取 TEB?
x64。我知道出了什么问题。这是我的语法。如果我使用 AT&T 语法而不是 intel 语法,则相同的代码可以正常工作。所以我肯定做错了什么:***.com/questions/21974224/…
mov rax, _ptr
将_ptr
的值移动到rax
,而不是相反。如果那是您的实际代码 _ptr
仍应包含空指针值。
【参考方案1】:
为了实现这一点,您必须在 Visual Studio 中创建一个 .asm 文件,如 here 所述。
要访问使用 Visual Studio 编译的 x64 中的 TEB/PEB,您可以使用以下代码:
GetTEBAsm64 proc
push rbx
xor rbx,rbx
xor rax,rax
mov rbx, qword ptr gs:[00000030h]
mov rax, rbx
pop rbx
ret
GetTEBAsm64 endp
GetPEBAsm64 proc
push rbx
xor rbx,rbx
xor rax,rax
mov rbx, qword ptr gs:[00000060h]
mov rax, rbx
pop rbx
ret
GetPEBAsm64 endp
然后简单地使用它们:
PTEB pTeb = GetTEBAsm64();
PPEB pPeb = GetPEBAsm64();
专业提示:
您可以定义您自己的这些结构的“版本” (PTEB/PPEB),以在其中包含或多或少的信息。
【讨论】:
【参考方案2】:Visual Studio 不允许 X64 C++ 的内联汇编程序。不支持 __asm 关键字。您可以在单独的文件中编写汇编程序并将其链接,或者您可以使用内在函数做您需要做的事情。
【讨论】:
【参考方案3】:如果你使用 Visual Studio,你可以使用 Intrinsics!
[x86] __readfsbyte __readfsdword __readfsqword __readfsword
[x64] __readgsbyte __readgsdword __readgsqword __readgsword
祝你好运~
【讨论】:
以上是关于访问 x64 TEB C++ 和汇编的主要内容,如果未能解决你的问题,请参考以下文章