20145203盖泽双 反汇编代码实践
反汇编代码实践
(1)使用vim 20145203gdbtest.c编写代码。代码如下图
(2)产生汇编代码:
gcc -S 20145203gdbtest.c -o 20145203gdbtest.s
cat 20145203gdbtest.s
(3)产生反汇编代码:
gcc -c 20145203gdbtest.s -o 20145203gdbtest.o
objdump -d 20145203gdbtest.o
(4)利用gdb进行调试
补充一下有关gdb调试的相关命令
1、查看函数调用栈信息的GDB命令
① backtrace/bt n
n是一个正整数,表示只打印栈顶上n层的栈信息。
-n表一个负整数,表示只打印栈底下n层的栈信息。
② frame n
n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
这个指令的意思是移动到n指定的栈帧中去,并打印选中的栈的信息。如果没有n,则打印当前帧的信息。
③ up n
表示向栈的上面移动n层,可以不打n,表示向上移动一层。
④ down n
表示向栈的下面移动n层,可以不打n,表示向下移动一层。
2、gdb基础调试命令
开始gdb调试
gcc -g 20145203gdbtest.c -o 20145203gdbtest
gdb 20145203gdbtest
①查看源代码
②在main处设置断点
③运行一下
④使用disassemble指令获取汇编代码
⑤用i(info) r(registers)指令查看各寄存器的值:
反汇编代码分析:
汇编流程分析:这个程序的流程其实是sec函数调用了add的过程
①首先sec先把它的%ebp寄存器压入栈作为帧指针,然后压入被保存的寄存器、本地变量和临时变量,最上面是参数构造区域。然后再用call调用add,这时又把返回地址压入栈。
②add被调用后,把它的帧指针%ebp压入栈,然后压入寄存器、本地变量、临时变量,最上面是参数构造区域。
③add运算结束前,add会把%ebp弹出栈,然后ret指令弹出并跳转到之前call压入的地址,返回到sec过程,最后因为leave,%ebp出栈。
汇编代码分析,下面逐行解释:
①删除gcc产生代码中以"."开头的编译器指得到如下代码:
add:
pushl %ebp ;将%ebp入栈,为帧指针,将父函数的栈底寄存器存入当前程序栈中
movl %esp, %ebp
movl 8(%ebp), %eax :从父函数堆栈中取得参数,存入ax寄存器
addl $9, %eax :完成+9操作
popl %ebp ;%ebp出栈,恢复父函数堆栈
ret
sec:
pushl %ebp ;将%ebp入栈,为帧指针
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call add ;调用add函数
leave ;为返回准备栈,相当于%ebp出栈
main:
push &ebp
mov %esp,%ebp
push $0xf
call 21 <main+0x6>
add $0x4,%esp
add $0x8,%eax :完成+8操作
leave
ret
②针对每条指令画出相应栈帧的情况: