Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在x86汇编中获得无堆栈的eip_Assembly_X86 - Fatal编程技术网

Assembly 如何在x86汇编中获得无堆栈的eip

Assembly 如何在x86汇编中获得无堆栈的eip,assembly,x86,Assembly,X86,我想根据eip设置esp,所以我不能使用堆栈。没有堆栈,如何获取eip的值。不,在x86-32中是不可能的。EIP仅通过调用指令或中断/陷阱从CPU泄漏。所有这些方法都将以某种方式使用堆栈 (相比之下,x86-64允许您相对于rip来lea)如果无法更改ESP,则必须在不可能中断的上下文中执行,例如,某些中断例程或上下文切换代码,或者ESP中存在垃圾。(在后一种情况下,我建议您修改代码,以便ESP始终指向可用于堆栈的区域;这在实践中并不难安排,并且在使用垃圾ESP时可以防止代码中出现非常奇怪的错

我想根据
eip
设置
esp
,所以我不能使用堆栈。没有堆栈,如何获取
eip
的值。

不,在x86-32中是不可能的。EIP仅通过
调用
指令或中断/陷阱从CPU泄漏。所有这些方法都将以某种方式使用堆栈


(相比之下,x86-64允许您相对于
rip
lea

如果无法更改ESP,则必须在不可能中断的上下文中执行,例如,某些中断例程或上下文切换代码,或者ESP中存在垃圾。(在后一种情况下,我建议您修改代码,以便ESP始终指向可用于堆栈的区域;这在实践中并不难安排,并且在使用垃圾ESP时可以防止代码中出现非常奇怪的错误)

在这种情况下,您可以将所需的EIP值编码为mov立即指令操作数。您可以在汇编程序中编写以下内容以“获取EIP”:


如果您不是在汇编程序中编写,您可以使用$B8“mov”生成上述的二进制等价物操作码,提供正确的寄存器值,并在immediate32值中填入mov指令的放置位置。

某些上下文可能会有所帮助。为什么不能使用堆栈?如果使用绝对代码模型,则可以从偏移量中询问编译器或calcolate。@RossRidge:我想知道grub2加载的地址是哪个内核到。我不知道堆栈可以放在哪里以及使用了哪个内存区域。所以我想在代码附近设置堆栈。但是
eip
未知。@GJ:我不知道可以使用哪个地址。所以我只能使用相对地址。这仍然没有意义。为什么没有一个有效的堆栈供您使用?在wh中在上下文中,您的代码是否实际运行?它是一个引导扇区、一个GRUB2模块、一个普通的Linux进程吗?我认为您犯了一个错误,没有问您真正的问题。最终您要完成什么?为什么您甚至需要知道内核加载了什么地址?实际上,当用户进程收到中断时,状态是推送到内核上(环0)堆栈。因此用户ESP很可能是垃圾,事情仍然会运行。@NayukiMinase:假设中断向量配置为在环0中执行,但这当然是最常见的configuration@NayukiMinase:嗯。有趣的是,一个老家伙学到了一个新的细节。教训:总是检查参考手册。好的,ESP可以继续了n完全垃圾和调用解决方案将不起作用,因为您可以推送到垃圾位置。实际上,我在x86机器代码中进行了大量上下文切换;我总是坚持将ESP点插入某个可用作堆栈的有效区域以避免此问题。(这意味着我也不必担心此问题!).OP应该澄清他的情况。@Ira Baxter:没问题,这没什么好尴尬的。我之所以能发表这一评论,是因为我经历了编写内核模式中断处理程序的繁琐过程,阅读了《英特尔手册》,并仔细剖析了CPU推到内核堆栈上的结构。=)@NayukiMinase:没有尴尬,只是年纪大了,太依赖我的背景而不是参考文档:-{事实上,我希望我的可切换线程能够在用户空间中运行,而不会出现不好的意外,这就是始终安全的堆栈特技。这部分是为了避免必须知道内核陷阱是如何工作的,但主要是为了完全避免很久以前我开始使用可切换线程时得到的建议,即“好吧,你应该修改内核代码来做到这一点…”(哎呀!)我同情你的痛苦,很高兴我躲开了。
   mov   ecx, offset $    ; different assemblers use different syntax for "current address"
   mov   ecx, offset L1
L1: ...