gcc常用选项对代码的影响
测试环境 RedHat 6.2
★ 前言
本文讨论gcc的一些常用编译选项对代码的影响。当然代码变了,它的内存布局也就会变了,随之exploit也就要做相应的变动。
gcc的编译选项实在太多,本文检了几个最常用的选项。
★ 演示程序
[alert7@redhat62 alert7]$ cat > test.c
#include
void hi(void)
{
printf("hi");
}
int main(int argc, char *argv[])
{
hi();
return 0;
}
[目录]
一般情况
★ 一般情况
[alert7@redhat62 alert7]$ gcc -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11773 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483e4 : push %ebp
0x80483e5 : mov %esp,%ebp
0x80483e7 : call 0x80483d0
0x80483ec : xor %eax,%eax
0x80483ee : jmp 0x80483f0
0x80483f0 : leave
0x80483f1 : ret
....
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483d0 : push %ebp
0x80483d1 : mov %esp,%ebp
0x80483d3 : push $0x8048450
0x80483d8 : call 0x8048308
0x80483dd : add $0x4,%esp
0x80483e0 : leave
0x80483e1 : ret
0x80483e2 : mov %esi,%esi
End of assembler dump.
来看看部分的内存映象
(内存高址)
+--------+
|bffffbc4| argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
|00000001| argc的值
0xbffffb80 +--------+
|400309cb|main的返回地址
0xbffffb7c +--------+ <-- 调用main函数前的esp
|bffffb98| 调用main函数前的ebp
0xbffffb78 +--------+ <-- main函数的ebp
|080483ec| hi()的返回地址
0xbffffb74 +--------+
|bffffb78| 调用hi()前的esp
0xbffffb70 +--------+
|08048450| "hi"的地址
0xbffffb6c +--------+
| ...... |
(内存低址)
leave 指令所做的操作相当于MOV ESP,EBP 然后 POP EBP
ret 指令所做的操作相当于POP EIP
[目录]
--------------------------------------------------------------------------------
-O 编译选项
★ -O 编译选项
With `-O', the compiler tries to reduce code size and execution time.
When you specify `-O', the two options `-fthread-jumps' and
`-fdefer-pop' are turned on
优化,减少代码大小和执行的时间
[alert7@redhat62 alert7]$ gcc -O -o test test.c
[alert7@redhat62 alert7]$ wc -c test
11757 test
[alert7@redhat62 alert7]$ gdb -q test
(gdb) disass main
Dump of assembler code for function main:
0x80483d8 : push %ebp
0x80483d9 : mov %esp,%ebp
0x80483db : call 0x80483c8
0x80483e0 : xor %eax,%eax
0x80483e2 : leave
0x80483e3 : ret
0x80483e4 : nop
...
End of assembler dump.
(gdb) disass hi
Dump of assembler code for function hi:
0x80483c8 : push %ebp
0x80483c9 : mov %esp,%ebp
0x80483cb : push $0x8048440
0x80483d0 : call 0x8048308
0x80483d5 : leave
0x80483d6 : ret
0x80483d7 : nop
End of assembler dump.
在main()中,把一条jmp指令优化掉了,很显然,这条指令是可以不需要的。
在hi()中,把add $0x4,%esp优化掉了,这会不会使stack不平衡呢?
来看看部分的内存映象
(内存高址)
+--------+
|bffffbc4| argv的地址(即argv[0]的地址)
0xbffffb84 +--------+
|00000001| argc的值
0xbffffb80 +--------+
|400309cb|main的返回地址
0xbffffb7c +--------+ <-- 调用main函数前的esp
|bffffb98| 调用main函数前的ebp
0xbffffb78 +--------+ <-- main函数的ebp
|080483e0| hi()的返回地址
0xbffffb74 +--------+
|bffffb78| 调用hi()前的esp
0xbffffb70 +--------+
|08048440| "hi"的地址
0xbffffb6c +--------+
| ...... |
(内存低址)
leave指令所做的操作相当于把MOV ESP,EBP 然后 POP EBP。看到leave指令操作了没有,先把ebp-->esp,再pop ebp,这样即使在过程内堆栈的esp,ebp是不平衡的,但只要返回时候碰到leave指令就会平衡了,所以把add $0x4,%esp优化掉也是没有问题的。
Linux下GNU调试器gdb详细说明(3)
内容版权声明:除非注明,否则皆为本站原创文章。