Debian NASM获得文件在这里意味着什么?
我在这里专门从9.2节开始阅读本节: 我已经读了一整天了,我想确保在继续之前我了解这里发生的事情。我相信他们说我们需要执行位置无关的代码,因为在使用共享库时,访问某些全局库时的重新定位不能硬编码。为此,我们使用全局偏移表 我仍然相信他们会说:Debian NASM获得文件在这里意味着什么?,debian,nasm,relocation,Debian,Nasm,Relocation,我在这里专门从9.2节开始阅读本节: 我已经读了一整天了,我想确保在继续之前我了解这里发生的事情。我相信他们说我们需要执行位置无关的代码,因为在使用共享库时,访问某些全局库时的重新定位不能硬编码。为此,我们使用全局偏移表 我仍然相信他们会说: call .get_GOT .get_GOT: pop ebx add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc 通过
call .get_GOT
.get_GOT:
pop ebx
add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc
通过首先将值ebx推到堆栈上实现使用GOT,其中.get_GOT将GOT的位置放置在相对于rip寄存器的位置,并在ebx中返回它
这就是我认为我理解正确的全部。如果有人能澄清这件事发生了什么
add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc
我将不胜感激。另外,请将其分成关于add指令中整个第二个操作数部分的部分。谢谢。我在理解所有上下文方面有些困难 调用x相当于PUSH-RIP,JMP-x 下一条指令就是当前的RIP 注意:此代码是链接器的提要,因此链接器将读取代码并输入正确的调用地址,但NASM在汇编时无法知道此类地址 最后一条指令是ADD:我们将EBX添加到一个常量。是,将在装配时计算一个常数 我们缺乏足够的详细信息,但正如您所见,我们从RIP(在ebx中)添加了一个偏移量 $$计算到当前节的开头 对于wrt运算符:,本节可能会更好地解释您正在查找的代码
我对NASM的信任度太高,无法继续下去。这是一件疯狂的事情,不知何故,它仍然是一件事。。。我看到的每一个地方都解释得很糟糕 我将使用64位寄存器来回答,因为现在世界是64位的,指针是64位的 在呼叫和推送之后,
rbx
包含.get\u get
的地址。这是因为调用将rip
推送到堆栈上,并且rip
始终指向当前指令(通常是下一条指令)后面的地址。因此,pop将.get\u get
的绝对地址移动到rbx
。到目前为止,一切顺利
\u GLOBAL\u OFFSET\u TABLE是一个符号(位于ELF文件的符号表中),定义为指向GOT的开始。为什么不直接使用mov-rbx、\u-GLOBAL\u-OFFSET\u-TABLE\u
?由于历史的原因。。。或者至少输给了我。此指令在我的(64位)机器上运行良好。同样,$
是一个定义为指向当前节开头的符号
资料来源:
现在,让我们做一些地址数学
add ebx, _GLOBAL_OFFSET_TABLE_ + $$ - .get_GOT wrt ..gotpc
= .get_GOT + _GLOBAL_OFFSET_TABLE_ + $$ - .get_GOT wrt ..gotpc
请注意,我们有.get\u-get-.get\u-get
。我们可以摆脱它
= .get_GOT + _GLOBAL_OFFSET_TABLE_ + $$ - .get_GOT wrt ..gotpc
= _GLOBAL_OFFSET_TABLE_ + $$ wrt ..gotpc
现在,让我们看看wrt..gotpc
的定义
参考使用wrt..gotpc标记全局偏移表基的符号,将给出从当前节开始到全局偏移表的距离。(((GLOBAL_OFFSET_TABLE))是用于引用GOT的标准符号名。)因此,您需要向结果中添加$$以获取GOT的实际地址
资料来源:
基于此,我们可以将表达式\u GLOBAL\u OFFSET\u TABLE\uwrt..gotpc
替换为表达式\u GLOBAL\u OFFSET\u TABLE-$
。(这可能是积极的,因为GOT很可能位于比程序更高的地址中。)这说明了需要添加NASM手册中提到的$
我们代替
= _GLOBAL_OFFSET_TABLE_ + $$ wrt ..gotpc
= $$ + _GLOBAL_OFFSET_TABLE_ wrt ..gotpc
= $$ + (_GLOBAL_OFFSET_TABLE_ - $$)
= _GLOBAL_OFFSET_TABLE_
瞧!希望这有帮助