该程序如何知道此字符串的确切存储位置? [英] How does this program know the exact location where this string is stored?
问题描述
我已经用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屋!