直接读取程序计数器 [英] Reading program counter directly

查看:35
本文介绍了直接读取程序计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Intel CPU 上的程序计数器是否可以在内核模式或其他模式下直接读取(即无需技巧")?

Can the program counter on Intel CPUs can be read directly (that is without 'tricks') in kernel mode or some other mode?

推荐答案

不,EIP/IP 不能直接访问,但在依赖位置的代码中,它是一个链接时间常数,因此您可以使用附近(或远处)符号作为即时.

No, EIP / IP cannot be accessed directly, but in position-dependent code it's a link-time constant so you can use a nearby (or distant) symbol as an immediate.

   mov eax, nearby_label    ; in position-dependent code
nearby_label:

<小时>

要在与位置无关的 32 位代码中获取 EIP 或 IP:


To get EIP or IP in position-independent 32-bit code:

        call _here
_here:  pop eax
; eax now holds the PC.

在比 Pentium Pro(或可能是 PIII)更新的 CPU 上,使用 rel32=0 调用 rel32 是特殊情况,不会影响返回地址预测器堆栈.因此,这在现代 x86 上既高效又紧凑,并且是 clang 用于 32 位位置无关代码的方法.

On CPUs newer than Pentium Pro (or PIII probably), call rel32 with rel32=0 is special-cased to not affect the return-address predictor stack. So this is efficient as well as compact on modern x86, and is what clang uses for 32-bit position-independent code.

在旧的 32 位 Pentium Pro CPU 上,这会使调用/返回预测器堆栈不平衡,因此更喜欢调用实际返回的函数,以避免在最多 15 个左右的未来 ret 父函数中的说明.(除非您不打算返回,或者很少返回无关紧要.)不过,返回地址预测器堆栈会恢复.

On old 32-bit Pentium Pro CPUs, this would unbalance the call/return predictor stack, so prefer calling a function that does actually return, to avoid branch mispredicts on up to 15 or so future ret instructions in your parent functions. (Unless you're not going to return, or so rarely that it doesn't matter.) The return-address predictors stack will recover, though.

get_retaddr_ppro:
    mov  eax, [esp]
    ret                ; keeps the return-address predictor stack balanced
                       ; even on CPUs where  call +0 isn't a no-op.

<小时>

在 x86-64 模式下,可以使用相对于 RIP 的 lea 直接读取 RIP.


In x86-64 mode, RIP can be read directly using a RIP-relative lea.

default rel           ; NASM directive: use RIP-relative by default

lea  rax, [_here]     ; RIP + 0
_here:

MASM 或 GNU .intel_syntax:lea rax, [rip]

MASM or GNU .intel_syntax: lea rax, [rip]

AT&T 语法:lea 0(%rip), %rax

AT&T syntax: lea 0(%rip), %rax

这篇关于直接读取程序计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆