Linux下GNU调试器gdb详细说明(3)

  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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzwwdy.html