20.2 GCC

没有太大的不同:

Listing 20.3: GCC

  1. lea eax, [esp+40h+var_28]
  2. mov [esp+40h+var_40], eax
  3. mov [esp+40h+var_28], 764h
  4. mov [esp+40h+var_24], 2Dh
  5. mov [esp+40h+var_20], 0C8h
  6. mov [esp+40h+var_1C], 0FFFFFF9Eh
  7. mov [esp+40h+var_18], 0FF7h
  8. mov [esp+40h+var_14], 5
  9. mov [esp+40h+var_10], 0FFFFCFC7h
  10. mov [esp+40h+var_C], 43Fh
  11. mov [esp+40h+var_8], 58h
  12. mov [esp+40h+var_4], 0FFFE7960h
  13. mov [esp+40h+var_34], offset comp
  14. mov [esp+40h+var_38], 4
  15. mov [esp+40h+var_3C], 0Ah
  16. call _qsort

comp() 函数:

  1. public comp
  2. comp proc near
  3. arg_0 = dword ptr 8
  4. arg_4 = dword ptr 0Ch
  5. push ebp
  6. mov ebp, esp
  7. mov eax, [ebp+arg_4]
  8. mov ecx, [ebp+arg_0]
  9. mov edx, [eax]
  10. xor eax, eax
  11. cmp [ecx], edx
  12. jnz short loc_8048458
  13. pop ebp
  14. retn
  15. loc_8048458:
  16. setnl al
  17. movzx eax, al
  18. lea eax, [eax+eax-1]
  19. pop ebp
  20. retn
  21. comp endp

qsort()的实现在libc.so里,它实际上是qsort_r()的封装。

我们通过传递函数指针然后调用快速排序:

Listing 20.4: (file libc.so.6, glibc version—2.10.1)

  1. .text:0002DDF6 mov edx, [ebp+arg_10]
  2. .text:0002DDF9 mov [esp+4], esi
  3. .text:0002DDFD mov [esp], edi
  4. .text:0002DE00 mov [esp+8], edx
  5. .text:0002DE04 call [ebp+arg_C]
  6. ...

20.2.1 GCC + GDB (with source code)

因为我们有例子的C源代码,我们能在行数(11—第一次比较的地方)设置断点(b)。编译例子的时候使用了带有调试信息的选项(-g),当前可以查看地址及行号,也可以打印变量(p):调试信息包含寄存器和变量值信息。

我们查看堆栈(bt),看到glibc使用的中间函数msort_with_tmp()。

Listing 20.5: GDB session

  1. dennis@ubuntuvm:~/polygon$ gcc 17_1.c -g
  2. dennis@ubuntuvm:~/polygon$ gdb ./a.out
  3. GNU gdb (GDB) 7.6.1-ubuntu
  4. Copyright (C) 2013 Free Software Foundation, Inc.
  5. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  6. This is free software: you are free to change and redistribute it.
  7. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  8. and "show warranty" for details.
  9. This GDB was configured as "i686-linux-gnu".
  10. For bug reporting instructions, please see:
  11. <http://www.gnu.org/software/gdb/bugs/>...
  12. Reading symbols from /home/dennis/polygon/a.out...done.
  13. (gdb) b 17_1.c:11
  14. Breakpoint 1 at 0x804845f: file 17_1.c, line 11.
  15. (gdb) run
  16. Starting program: /home/dennis/polygon/./a.out
  17. Breakpoint 1, comp (_a=0xbffff0f8, _b=_b@entry=0xbffff0fc) at 17_1.c:11
  18. 11 if (*a==*b)
  19. (gdb) p *a
  20. $1 = 1892
  21. (gdb) p *b
  22. $2 = 45
  23. (gdb) c
  24. Continuing.
  25. Breakpoint 1, comp (_a=0xbffff104, _b=_b@entry=0xbffff108) at 17_1.c:11
  26. 11 if (*a==*b)
  27. (gdb) p *a
  28. $3 = -98
  29. (gdb) p *b
  30. $4 = 4087
  31. (gdb) bt
  32. #0 comp (_a=0xbffff0f8, _b=_b@entry=0xbffff0fc) at 17_1.c:11
  33. #1 0xb7e42872 in msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=2)
  34. at msort.c:65
  35. #2 0xb7e4273e in msort_with_tmp (n=2, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
  36. #3 msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=5) at msort.c:53
  37. #4 0xb7e4273e in msort_with_tmp (n=5, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
  38. #5 msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=10) at msort.c:53
  39. #6 0xb7e42cef in msort_with_tmp (n=10, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
  40. #7 __GI_qsort_r (b=b@entry=0xbffff0f8, n=n@entry=10, s=s@entry=4, cmp=cmp@entry=0x804844d <comp
  41. >,
  42. arg=arg@entry=0x0) at msort.c:297
  43. #8 0xb7e42dcf in __GI_qsort (b=0xbffff0f8, n=10, s=4, cmp=0x804844d <comp>) at msort.c:307
  44. #9 0x0804850d in main (argc=1, argv=0xbffff1c4) at 17_1.c:26
  45. (gdb)

20.2.2 GCC + GDB (no source code)

更多时候我们没有源码,我们可以反汇编comp()函数(disas),找到CMP指令地址并设置断点(b)。每次中断后,dump所有寄存器的值(info registers),堆栈信息(bt),但是没有comp()函数对应的行号信息。

Listing 20.6: GDB session

  1. dennis@ubuntuvm:~/polygon$ gcc 17_1.c
  2. dennis@ubuntuvm:~/polygon$ gdb ./a.out
  3. GNU gdb (GDB) 7.6.1-ubuntu
  4. Copyright (C) 2013 Free Software Foundation, Inc.
  5. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  6. This is free software: you are free to change and redistribute it.
  7. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  8. and "show warranty" for details.
  9. This GDB was configured as "i686-linux-gnu".
  10. For bug reporting instructions, please see:
  11. <http://www.gnu.org/software/gdb/bugs/>...
  12. Reading symbols from /home/dennis/polygon/a.out...(no debugging symbols found)...done.
  13. (gdb) set disassembly-flavor intel
  14. (gdb) disas comp
  15. Dump of assembler code for function comp:
  16. 0x0804844d <+0>: push ebp
  17. 0x0804844e <+1>: mov ebp,esp
  18. 0x08048450 <+3>: sub esp,0x10
  19. 0x08048453 <+6>: mov eax,DWORD PTR [ebp+0x8]
  20. 0x08048456 <+9>: mov DWORD PTR [ebp-0x8],eax
  21. 0x08048459 <+12>: mov eax,DWORD PTR [ebp+0xc]
  22. 0x0804845c <+15>: mov DWORD PTR [ebp-0x4],eax
  23. 0x0804845f <+18>: mov eax,DWORD PTR [ebp-0x8]
  24. 0x08048462 <+21>: mov edx,DWORD PTR [eax]
  25. 0x08048464 <+23>: mov eax,DWORD PTR [ebp-0x4]
  26. 0x08048467 <+26>: mov eax,DWORD PTR [eax]
  27. 0x08048469 <+28>: cmp edx,eax
  28. 0x0804846b <+30>: jne 0x8048474 <comp+39>
  29. 0x0804846d <+32>: mov eax,0x0
  30. 0x08048472 <+37>: jmp 0x804848e <comp+65>
  31. 0x08048474 <+39>: mov eax,DWORD PTR [ebp-0x8]
  32. 0x08048477 <+42>: mov edx,DWORD PTR [eax]
  33. 0x08048479 <+44>: mov eax,DWORD PTR [ebp-0x4]
  34. 0x0804847c <+47>: mov eax,DWORD PTR [eax]
  35. 0x0804847e <+49>: cmp edx,eax
  36. 0x08048480 <+51>: jge 0x8048489 <comp+60>
  37. 0x08048482 <+53>: mov eax,0xffffffff
  38. 0x08048487 <+58>: jmp 0x804848e <comp+65>
  39. 0x08048489 <+60>: mov eax,0x1
  40. 0x0804848e <+65>: leave
  41. 0x0804848f <+66>: ret
  42. End of assembler dump.
  43. (gdb) b *0x08048469
  44. Breakpoint 1 at 0x8048469
  45. (gdb) run
  46. Starting program: /home/dennis/polygon/./a.out
  47. Breakpoint 1, 0x08048469 in comp ()
  48. (gdb) info registers
  49. eax 0x2d 45
  50. ecx 0xbffff0f8 -1073745672
  51. edx 0x764 1892
  52. ebx 0xb7fc0000 -1208221696
  53. esp 0xbfffeeb8 0xbfffeeb8
  54. ebp 0xbfffeec8 0xbfffeec8
  55. esi 0xbffff0fc -1073745668
  56. edi 0xbffff010 -1073745904
  57. eip 0x8048469 0x8048469 <comp+28>
  58. eflags 0x286 [ PF SF IF ]
  59. cs 0x73 115
  60. ss 0x7b 123
  61. ds 0x7b 123
  62. es 0x7b 123
  63. fs 0x0 0
  64. gs 0x33 51
  65. (gdb) c
  66. Continuing.
  67. Breakpoint 1, 0x08048469 in comp ()
  68. (gdb) info registers
  69. eax 0xff7 4087
  70. ecx 0xbffff104 -1073745660
  71. edx 0xffffff9e -98
  72. ebx 0xb7fc0000 -1208221696
  73. esp 0xbfffee58 0xbfffee58
  74. ebp 0xbfffee68 0xbfffee68
  75. esi 0xbffff108 -1073745656
  76. edi 0xbffff010 -1073745904
  77. eip 0x8048469 0x8048469 <comp+28>
  78. eflags 0x282 [ SF IF ]
  79. cs 0x73 115
  80. ss 0x7b 123
  81. ds 0x7b 123
  82. es 0x7b 123
  83. fs 0x0 0
  84. gs 0x33 51
  85. (gdb) c
  86. Continuing.
  87. Breakpoint 1, 0x08048469 in comp ()
  88. (gdb) info registers
  89. eax 0xffffff9e -98
  90. ecx 0xbffff100 -1073745664
  91. edx 0xc8 200
  92. ebx 0xb7fc0000 -1208221696
  93. esp 0xbfffeeb8 0xbfffeeb8
  94. ebp 0xbfffeec8 0xbfffeec8
  95. esi 0xbffff104 -1073745660
  96. edi 0xbffff010 -1073745904
  97. eip 0x8048469 0x8048469 <comp+28>
  98. eflags 0x286 [ PF SF IF ]
  99. cs 0x73 115
  100. ss 0x7b 123
  101. ds 0x7b 123
  102. es 0x7b 123
  103. fs 0x0 0
  104. gs 0x33 51
  105. (gdb) bt
  106. #0 0x08048469 in comp ()
  107. #1 0xb7e42872 in msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=2)
  108. at msort.c:65
  109. #2 0xb7e4273e in msort_with_tmp (n=2, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
  110. #3 msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=5) at msort.c:53
  111. #4 0xb7e4273e in msort_with_tmp (n=5, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
  112. #5 msort_with_tmp (p=p@entry=0xbffff07c, b=b@entry=0xbffff0f8, n=n@entry=10) at msort.c:53
  113. #6 0xb7e42cef in msort_with_tmp (n=10, b=0xbffff0f8, p=0xbffff07c) at msort.c:45
  114. #7 __GI_qsort_r (b=b@entry=0xbffff0f8, n=n@entry=10, s=s@entry=4, cmp=cmp@entry=0x804844d <comp
  115. >,
  116. arg=arg@entry=0x0) at msort.c:297
  117. #8 0xb7e42dcf in __GI_qsort (b=0xbffff0f8, n=10, s=4, cmp=0x804844d <comp>) at msort.c:307
  118. #9 0x0804850d in main ()