该程序如何知道此字符串的确切存储位置? [英] How does this program know the exact location where this string is stored?

查看:83
本文介绍了该程序如何知道此字符串的确切存储位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have disassembled a C program with Radare2. Inside this program there are many calls to scanf like the following:

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是exectable文件中"%d"的位置,因为如果我以调试模式(r2 -d ./exec)重新启动Radare2,则lea rdi, [0x000368ff]将替换为lea rdi, [someMemoryAddress].

Here scanf has the address of the string "%d" passed to it from the line lea rdi, [0x000368ff]. I'm assuming 0x000368ff is the location of "%d" in the exectable file because if I restart Radare2 in debugging mode (r2 -d ./exec) then lea rdi, [0x000368ff] is replaced by lea rdi, [someMemoryAddress].

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

If lea rdi, [0x000368ff] is whats hard coded in the file then how does the instruction change to the actual memory address when run?

推荐答案

Radare欺骗了您,您看到的不是真正的指令,它已为您简化了.

Radare is tricking you, what you see is not the real instruction, it has been simplified for you.

真正的指示是:<​​/p>

The real instruction is:

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

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

This is a typical position independent lea. The string to use is stored in your binary at the offset 0x000368ff, but since the executable is position independent, the real address needs to be calculated at runtime. Since the next instruction is at offset 0x0000120c, you know that, no matter where the binary is loaded in memory, the address you want will be rip + (0x000368ff - 0x0000120c) = rip + 0x356f3, which is what you see above.

进行静态分析时,由于Radare不知道内存中二进制文件的基址,因此只需计算0x0000120c + 0x356f3 = 0x000368ff.这使逆向工程更加容易,但是由于实际的指令不同,因此可能会造成混淆.

When doing static analysis, since Radare does not know the base address of the binary in memory, it simply calculates 0x0000120c + 0x356f3 = 0x000368ff. This makes reverse engineering easier, but can be confusing since the real instruction is different.

例如,以下程序:

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,如果我们用hd来查看二进制文件中的偏移量0x754:

So rip + 0x99 = 0x6bb + 0x99 = 0x754, and if we take a look at offset 0x754 in the binary with 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

这篇关于该程序如何知道此字符串的确切存储位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆