assembly - CS:覆盖访问 IDA 输出中的全局变量,如 mov eax、cs:x?
问题描述
我正在编写简单的程序然后分析它们。今天我写了这个:
#include <stdio.h>
int x;
int main(void){
printf("Enter X:\n");
scanf("%d",&x);
printf("You enter %d...\n",x);
return 0;
}
它被编译成这样:
push rbp
mov rbp, rsp
lea rdi, s ; "Enter X:"
call _puts
lea rsi, x
lea rdi, aD ; "%d"
mov eax, 0
call ___isoc99_scanf
mov eax, cs:x <- don't understand this
mov esi, eax
lea rdi, format ; "You enter %d...\n"
mov eax, 0
call _printf
mov eax, 0
pop rbp
retn
我不明白什么cs:x
意思。
我使用 Ubuntu x64、GCC 10.3.0 和 IDA pro 7.6。
解决方案
TL:DR:IDA 令人困惑地使用cs:
64 位代码来指示相对于 RIP 的寻址模式。
在 IDA中,这mov eax, x
意味着mov eax, DWORD [x]
从变量中读取 DWORD x
。
为完整起见,mov rax, OFFSET x
表示mov rax, x
(即放入x
in的地址rax
)。
在 64 位中,位移仍然是 32 位,因此,对于与位置无关的可执行文件,并不总是可以通过对其地址进行编码来寻址变量(因为它是 64 位并且它不适合 32 位字段)。在与位置无关的代码中,这是不可取的。
而是使用RIP 相对寻址。
在 NASM 中,RIP 相对寻址采用 形式mov eax, [REL x]
,在气体中是mov x(%rip), %eax
。
此外,在 NASM 中,如果DEFAULT REL
处于活动状态,则可以将指令缩短为mov eax, [x]
与 32 位语法相同的指令。
每个反汇编器都会以不同的方式反汇编一个 RIP 相关的操作数。正如您评论的那样,Ghidra 给出了mov eax, DWORD PTR [x]
.
IDAmov eax, cs:x
用来表示mov eax, [REL x]
/ mov x(%rip), %eax
。
;IDA listing, 64-bit code
mov eax, x ;This is mov eax, [x] in NASM and most likely wrong unless your exec is not PIE and always loaded <= 4GiB
mov eax, cs:x ;This is mov eax, [REL x] in NASM and idiomatic to 64-bit programs
简而言之,您几乎可以忽略cs:
64 位模式下变量的寻址方式。
当然,如上面的清单所示,使用或不使用 RIP 相对寻址会告诉您程序可以加载到任何地方或 4GiB 以下。
cs
IDA 显示的前缀让我大吃一惊。
我可以看到它在心理上可能类似于“代码”,因此类似于rip
寄存器,但我不认为 RIP 相对寻址意味着cs
段覆盖。
在 32 位模式下,代码段通常是只读的,所以类似的指令mov [cs:x], eax
会出错。
在这种情况下,将 acs:
放在操作数前面是错误的。
在 64-bit mode,段覆盖(除了fs
/ gs
)被忽略(并且代码段的读取位无论如何都会被忽略),因此 a 的存在cs:
并不重要,因为ds
并且cs
实际上无法区分。(即使是ss
ords
覆盖也不会更改非规范地址的 #GP 或 #SS 异常。)
可能 AGU 甚至不再为fs
or以外的段基址读取段影子寄存器gs
。(尽管即使在 32 位模式下,对于段基数 = 0 的正常情况,也有较低延迟的快速路径,因此硬件可能只是让它完成它的工作。)
在我看来仍然cs:
具有误导性-2E
在机器代码中仍然可以使用前缀字节作为填充。大多数工具仍将其称为 CS 前缀,尽管http://ref.x86asm.net/coder64.html在 64 位模式下将其称为“空前缀”。这里没有这样的字节,cs:
也不是暗示 RIP 相对寻址的明显或明确的方式。
推荐阅读
- php - 如何使用 php 参数绑定图像?
- php - 如何将 Sendinblue 与 PHPMailer 一起使用
- javascript - 清除文本字段时触发事件:Javascript
- python - Python elasticsearch-dsl动态查询
- ios - 找不到在捆绑包 NSBundle 中命名的故事板
- google-apps-script - 是否可以限制 Google 电子表格中的解冻行?
- html - 如何将 CSS 类标记为已弃用
- r - 如何创建具有显着差异和 2 个测量变量的多面箱线图?
- nscollectionview - NSCollectionView 作为 NSCollectionViewItem
- python - Pandas:比较行值并修改下一列的行值