a a*_*a a 0 c++ assembly printf reverse-engineering x86-64
有人可以解释一下_IO_stdin_used下面这一行的内容吗:
114a: 48 8d 3d b3 0e 00 00 lea rdi,[rip+0xeb3] # 2004 <_IO_stdin_used+0x4>
Run Code Online (Sandbox Code Playgroud)
抱歉这个菜鸟问题。
扩展/sf/users/15689271/的评论(什么是 _IO_stdin_used),一些工具可以帮助理解这一点。从...开始burt.c:
#include <stdio.h>
void main (void) {
puts("hello!");
}
Run Code Online (Sandbox Code Playgroud)
像这样构建:LDFLAGS=-Wl,-Map=burt.map make burt
我们稍后将查看映射文件,首先检查可执行文件:
$ objdump -xsd -M intel burt
...
0000000000002000 g O .rodata 0000000000000004 _IO_stdin_used
...
Contents of section .rodata:
2000 01000200 68656c6c 6f2100 ....hello!.
...
1148: 48 8d 05 b5 0e 00 00 lea rax,[rip+0xeb5] # 2004 <_IO_stdin_used+0x4>
114f: 48 89 c7 mov rdi,rax
1152: e8 d9 fe ff ff call 1030 <puts@plt>
...
Run Code Online (Sandbox Code Playgroud)
请注意,字符串的位置 (2004h) 在符号表中没有条目(2000h 条目_IO_stdin_used出现的位置)。因此,objdump 的反汇编注释相对于它所知道的另一个符号提到了它。
但是为什么它知道_IO_stdin_used,或者为什么包含该符号以及为什么它有一个名称?burt.map显示它来自Scrt1.o:
...
.rodata 0x0000000000002000 0xb
*(.rodata .rodata.* .gnu.linkonce.r.*)
.rodata.cst4 0x0000000000002000 0x4 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../lib/Scrt1.o
.rodata 0x0000000000002004 0x7 /tmp/ccYG1XvK.o
...
Run Code Online (Sandbox Code Playgroud)
在我的电脑上,Scrt1.o属于glibc,符号可以追溯到这里:https://sourceware.org/git/?p=glibc.git;a=blob;f=csu/init.c;h=c2f978f3da565590bcab355fefa3d81cf211cb36; hb=63fb8f9aa9d19f85599afe4b849b567aefd70a36。
为了表明objdump由于地址没有名称而在反汇编中显示它,我们可以给字符串一个名称以将其添加到符号表中,这样就会objdump显示它。为此,我们进行burt.c如下修改:
#include <stdio.h>
const char greeting[] = "hello!";
void main (void) {
puts(greeting);
}
Run Code Online (Sandbox Code Playgroud)
构建,然后检查:
...
0000000000002004 g O .rodata 0000000000000007 greeting
...
0000000000002000 g O .rodata 0000000000000004 _IO_stdin_used
...
Contents of section .rodata:
2000 01000200 68656c6c 6f2100 ....hello!.
...
113d: 48 8d 05 c0 0e 00 00 lea rax,[rip+0xec0] # 2004 <greeting>
1144: 48 89 c7 mov rdi,rax
1147: e8 e4 fe ff ff call 1030 <puts@plt>
Run Code Online (Sandbox Code Playgroud)
相对于 的偏移量rip发生了一点变化,因为.text和部分.rodata现在分开了一点,尽管.rodata内容保持不变,因为选择了源修改以避免修改.rodata- 如果greetings不是const,它将位于.data。与之前相同数据没有名称的映射文件相比,下面的映射文件现在显示了临时对象文件对定义符号burt.c的贡献:.rodatagreeting
.rodata 0x0000000000002000 0xb
*(.rodata .rodata.* .gnu.linkonce.r.*)
.rodata.cst4 0x0000000000002000 0x4 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../..
/lib/Scrt1.o
0x0000000000002000 _IO_stdin_used
.rodata 0x0000000000002004 0x7 /tmp/ccDnWXjG.o
0x0000000000002004 greeting
Run Code Online (Sandbox Code Playgroud)