assembly - CS : override on access to global variables in IDA output, 像 mov eax, cs :x?

标签 assembly x86-64 disassembly ida addressing-mode

我正在编写简单的程序,然后对其进行分析。 今天我写了这个:

#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],这反过来意味着从变量 x 中读取一个 DWORD。
为了完整起见,mov rax, OFFSET x 表示mov rax, x(即将x的地址放入rax ).

在 64 位中,位移仍然是 32 位的,因此,对于位置无关的可执行文件,并不总是可以通过对其地址进行编码来寻址变量(因为它是 64 位的,不适合 32 位的 field )。而在与位置无关的代码中,这是不可取的。
相反,RIP-relative addressing被使用。

在 NASM 中,RIP 相对寻址的形式为 mov eax, [REL x],在 gas 中为 mov x(%rip), %eax。< br/> 此外,在 NASM 中,如果 DEFAULT REL 处于事件状态,则指令可以缩短为 mov eax, [x],这与 32 位语法相同。

每个反汇编器都会以不同的方式反汇编 RIP 相关的操作数。正如您评论的那样,Ghidra 给出了mov eax, DWORD PTR [x]
IDA 使用 mov 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 位模式下变量的寻址方式。
当然,如上面的 list 所示,使用或不使用 RIP 相对寻址告诉您程序可以加载到任何地方或略低于 4GiB。


IDA 显示的 cs 前缀让我失望。

我可以看出它在心理上类似于“代码”,因此类似于 rip 寄存器,但我认为 RIP 相对寻址并不意味着 cs 段覆盖。

在32位模式下,代码段通常是只读的,所以像mov [cs:x], eax这样的指令会报错。
在这种情况下,将 cs: 放在操作数前面是错误的。

在 64 位模式下,段覆盖(fs/gs 除外)被忽略(以及代码的读取位segment 无论如何都会被忽略),所以 cs: 的存在并不重要,因为 dscs 实际上是无法区分的。 (即使 ssds 覆盖也不会更改非规范地址的 #GP 或 #SS 异常。)
可能 AGU 甚至不再为 fsgs 以外的段基址读取段影子寄存器。 (虽然即使在 32 位模式下,对于段基数 = 0 的正常情况也有一条延迟较低的快速路径,因此硬件可能只是让它完成它的工作。)

在我看来 cs: 仍然具有误导性 - 2E 前缀字节在机器代码中仍然可能作为填充。尽管http://ref.x86asm.net/coder64.html,大多数工具仍将其称为 CS 前缀。在 64 位模式下称其为“空前缀”。这里没有这样的字节,cs: 不是暗示 RIP 相对寻址的明显或明确的方式。

关于assembly - CS : override on access to global variables in IDA output, 像 mov eax, cs :x?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68702174/

相关文章:

java - 了解 Dalvik 代码的反汇编?

optimization - 利用 64 位寄存器的最酷的多操作技巧? (无 SIMD/SSE/AVX)

assembly - PIC汇编函数调用

macos - 在 Mac OSX 上使用 NASM 和 ld

c++ - GCC 手册中提到的 "C++ ABI Specification"是什么?

c# - 如何从DLL中恢复分部类的信息?

c++ - pcmpestri指令写出类似strpos的函数?

assembly - Ivy 桥上RDRAND的耗竭特性是什么?

assembly - yasm:预期为 `,' 并具有立即值

java - 使用 Javassist 获取字节码的参数