维基百科条约x86会 说"IP登记册无法访问的程序。"

直接装置的说明等文,并添加。

为什么不呢?背后的原因是什么这个?有什么技术限制?

有帮助吗?

解决方案

你不能直接访问它,因为没有合法的使用情况。具有任何任意的指令的更改 eip 会让的分支预测非常困难,且可能会打开一堆的安全问题。

你可以编辑 eip 使用 jmp, callret.你就不能直接从阅读或写信给 eip 使用正常运作

设置 eip 一个登记册作为简单的 jmp eax.你也可以做 push eax; ret, ,这推动的价值 eax 堆然后返回(即持久性有机污染物和跳).第三个选择是 call eax 这并呼叫地址在eax.

阅读可以做这样的:

call get_eip
  get_eip:
pop eax ; eax now contains the address of this instruction

其他提示

这可能是X86的可能设计。手臂做 公开其程序计数器以读/写为R15. 。不过,这是不寻常的。

它允许非常紧凑的函数序言/结语,并能够用单个指令推动或弹出多个寄存器: push {r5, lr} 进入,以及 pop {r5, pc} 返回。 (将链接寄存器的保存值弹出到程序计数器中)。

但是,它使高级 /级别的ARM实现降低了方便,并且用于AARCH64。


所以 有可能,但用尽了其中一个寄存器. 。 32位ARM具有16个整数寄存器(包括PC),因此寄存器编号需要4位用ARM机器代码进行编码。另一个登记册几乎总是被绑定为堆栈指针,因此ARM有14个通用整数登记册。 (可以将LR保存到堆栈中,因此可以并用作功能机构内部通用寄存器)。

现代X86的大部分是从8086继承的。它的设计使用相当紧凑的可变长度指令编码,只有8个寄存器,每个SRC和DST寄存器仅需要3位。

在最初的8086中,它们不是很通用,并且在16位模式下无法进行SP搭配的解决方案,因此基本上有2个寄存器(SP和BP)被绑住以堆叠堆栈的东西。这仅留下6个某种程度上的目的登记册,其中一个是PC而不是通用的登记册,将大大减少可用寄存器,从而大大增加了典型代码中的溢出/重新加载量。


AMD64添加了R8-R15和RIP相关的寻址模式。 lea rsi, [rip+whatever], ,以及用于直接访问静态数据和常数的RIP相关地址模式,您需要有效地与位置无关的代码。间接JMP说明完全足以写作。

通过允许使用任意说明读取或编写PC,实际上没有什么可获得的,因为您可以随时使用整数寄存器和间接跳跃来做同样的事情。 X86-64的R15与RIP相同,尤其是对于架构作为编译器目标的表演,这几乎是纯粹的弊端。 (到2000年,当设计AMD64时,手工编写的ASM怪异的东西已经非常罕见。)

因此,AMD64实际上是X86首次可以合理地获得像ARM这样的完全曝光的程序计数器,但是有很多很好的理由不这样做。

我认为他们意味着无法直接以其他寄存器访问的方式访问IP寄存器。程序员绝对可以写入IP,例如发出跳跃指令。

jmp 将设置 EIP 登记。

此代码将将EIP设置为00401000:

mov eax, 00401000
jmp eax ;set Eip to 00401000

并获得 EIP

call GetEIP
.
.
GetEIP:
mov eax, [esp]
ret
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top