gpt4 book ai didi

c - 这个程序如何知道存储这个字符串的确切位置?

转载 作者:太空狗 更新时间:2023-10-29 17:06:15 25 4
gpt4 key购买 nike

我用 Radare2 反汇编了一个 C 程序。在这个程序中有许多对 scanf 的调用,如下所示:

0x000011fe      488d4594       lea rax, [var_6ch]
0x00001202 4889c6 mov rsi, rax
0x00001205 488d3df35603. lea rdi, [0x000368ff] ; "%d" ; const char *format
0x0000120c b800000000 mov eax, 0
0x00001211 e86afeffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
0x00001216 8b4594 mov eax, dword [var_6ch]
0x00001219 83f801 cmp eax, 1 ; rsi ; "ELF\x02\x01\x01"
0x0000121c 740a je 0x1228

此处 scanf 具有从 lea rdi, [0x000368ff] 行传递给它的字符串 "%d" 的地址。我假设 0x000368ff 是可执行文件中 "%d" 的位置,因为如果我在 Debug模式下重新启动 Radare2 (r2 -d ./exec) 然后 lea rdi, [0x000368ff] 被替换为 lea rdi, [someMemoryAddress]

如果 lea rdi, [0x000368ff] 是硬编码在文件中的,那么指令在运行时如何更改为实际内存地址?

最佳答案

Radare 在骗你,你看到的不是真正的指令,它已经为你简化了。

真正的指令是:

0x00001205    488d3df3560300    lea rdi, qword [rip + 0x356f3]
0x0000120c b800000000 mov eax, 0

这是一个典型的位置独立lea .要使用的字符串存储在二进制文件中的偏移量 0x000368ff 处,但由于可执行文件与位置无关,因此需要在运行时计算实际地址。由于下一条指令位于偏移量 0x0000120c,您知道,无论二进制文件加载到内存中的哪个位置,您想要的地址都将是 rip + (0x000368ff - 0x0000120c) = rip + 0x356f3,这就是你在上面看到的。

在进行静态分析时,由于Radare不知道二进制文件在内存中的基地址,所以简单计算0x0000120c + 0x356f3 = 0x000368ff。这使得逆向工程更容易,但可能会造成混淆,因为真正的指令是不同的。


例如,下面的程序:

int main(void) {
puts("Hello world!");
}

编译后产生:

  6b4:   48 8d 3d 99 00 00 00    lea    rdi,[rip+0x99] 
6bb: e8 a0 fe ff ff call 560 <puts@plt>

所以 rip + 0x99 = 0x6bb + 0x99 = 0x754,如果我们看一下偏移 0x754 在带有 hd 的二进制文件中:

$ hd -s 0x754 -n 16 a.out
00000754 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 00 00 00 00 |Hello world!....|
00000764

关于c - 这个程序如何知道存储这个字符串的确切位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57748994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com