【发布时间】:2015-08-24 03:14:21
【问题描述】:
我正在尝试理解这个简单的 C 程序的汇编。
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
void foobar(char *a){
char c = a[0];
}
int main(){
int fd = open("file.txt", O_RDONLY);
char buf1[100]="\0";
char buf[100];
int aa=0,b=1,c=2,d=3,f=2,g=3;
read(fd,buf1,104);
if(strlen(buf1) > 100){
}else{
strcpy(buf,buf1);
}
//strcpy(buf,buf1);
foobar(buf1);
}
我得到的使用 gdb 对可执行文件的反汇编是 foobar 反汇编。
0x000000000040067d <+0>: push rbp
0x000000000040067e <+1>: mov rbp,rsp
0x0000000000400681 <+4>: mov QWORD PTR [rbp-0x18],rdi
0x0000000000400685 <+8>: mov rax,QWORD PTR [rbp-0x18]
0x0000000000400689 <+12>: movzx eax,BYTE PTR [rax]
0x000000000040068c <+15>: mov BYTE PTR [rbp-0x1],al
0x000000000040068f <+18>: pop rbp
在 foobar 之前的主要反汇编
0x0000000000400784 <+243>: lea rax,[rbp-0xf0]
0x000000000040078b <+250>: mov rdi,rax
0x000000000040078e <+253>: call 0x40067d <foobar>
0x0000000000400793 <+258>: mov rbx,QWORD PTR [rbp-0x18]
0x0000000000400797 <+262>: xor rbx,QWORD PTR fs:0x28
0x00000000004007a0 <+271>: je 0x4007a7 <main+278>
0x0000000000400690 <+19>: ret
现在,我有一个关于 foobar 反汇编的问题
0x0000000000400681 <+4>: mov QWORD PTR [rbp-0x18],rdi
0x0000000000400685 <+8>: mov rax,QWORD PTR [rbp-0x18]
指令不行
mov rax, rdi
将完成上述两条指令所需的工作。为什么要为 rdi 使用额外的内存位置 rbp - 0x18 ?
和引用传递有关吗?
编辑:
我想问的另一个问题是,为什么 foobar 函数正在访问不在 foobar 框架中的 something(rbp - 0x18)。?
我的 gcc 版本是 gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
编辑: 在编译时使用 -O1 -O2 和 -O3 优化标志后,foobar 程序集变为
0x0000000000400670 <+0>: repz ret
在使用 -O3 标志时,main 的一些反汇编是
0x0000000000400551 <+81>: rep stos QWORD PTR es:[rdi],rax
0x0000000000400554 <+84>: mov DWORD PTR [rdi],0x0
0x000000000040055a <+90>: mov cl,0x64
0x000000000040055c <+92>: mov edi,r8d
0x000000000040055f <+95>: call 0x4004b0 <__read_chk@plt>
0x0000000000400564 <+100>: mov rdx,QWORD PTR [rsp+0x68]
0x0000000000400569 <+105>: xor rdx,QWORD PTR fs:0x28
0x0000000000400572 <+114>: jne 0x400579 <main+121>
0x0000000000400574 <+116>: add rsp,0x78
0x0000000000400578 <+120>: ret
0x0000000000400579 <+121>: call 0x4004c0 <__stack_chk_fail@plt>
我在 main 中找不到任何对 foobar 的调用。
【问题讨论】:
-
你的编译器标志是什么?
-
我正在使用以下命令进行编译。 gcc a.c -o a -g
-
使用一些优化设置,否则代码不会优化:) 如
-O3. -
我想问的另一个问题是为什么 foobar 函数正在访问不在 foobar 框架中的东西(rbp - 0x18)。
标签: c gcc assembly gdb reverse-engineering