可先参考以下链接了解一下有关函数栈、EIP、EBP、ESP寄存器的作用:https://www.k2zone.cn/?p=1911
编译C语言代码:
.file "week03031231.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
addl $3, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $24, %rsp
movl %edi, -20(%rbp)
movl $31, -4(%rbp)
movl -20(%rbp), %eax
movl %eax, %edi
call g
movl -4(%rbp), %edx
addl %edx, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size f, .-f
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $8, %edi
call f
addl $1, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
使用gdb跟踪汇编代码
-
使用
gcc - g week03031231.c -o week03031231 -m32
指令在64位的机器上产生32位汇编,然后使用gdb week03031231
指令进入gdb调试器:
-
发现报错,经上网查询得到:
sudo apt-get install gcc-multilib
sudo apt-get install g++-multilib
安装完成之后,再次运行发现成功了,
准备工作来方便记录
通过gdb main 命令进入gdb调试:
经查询esp始终指向栈顶,ebp是在堆栈中寻址用的
首先,结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc
,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。下面展示每一步时%esp、%ebp和堆栈内容的变化:
call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
将上一个函数的基址入栈,从当前%esp开始作为新基址:
f函数的汇编代码:
实参入栈:
call指令将下一条指令的地址入栈:
计算short+int:
pop %ebp指令将栈顶弹到%ebp中,同时%esp增加4字节:
ret指令将栈顶弹给%eip:
因为函数f修改了%esp,所以用leave指令恢复。leave指令先将%esp对其到%ebp,然后把栈顶弹给%ebp:
主函数汇编代码:
通过一步一步调试,我记录了每一步运行时esp、ebp、eip、eax的变化
指令 | esp | ebp | eax | eip | 堆栈 |
---|---|---|---|---|---|
endbr32 | 0xffffd03c | 0x0 | 0xf7fb5808 | 0x565561f3 | 0x0 |
push %ebp | 0xffffd03c | 0x0 | 0xf7fb5808 | 0x565561f7 | 0xf7deaee5 0x1 |
mov %esp,%ebp | 0xffffd038 | 0xffffd038 | 0xf7fb5808 | 0x565561fa | 0x0 0xf7deaee5 0x1 |
call 0x56556213 | 0xffffd034 | 0xffffd038 | 0xf7fb5808 | 0x56556213 | 0x1 0x0 0xffffd0d4 0xf7deaee5 |
mov (%esp),%eax | 0xffffd034 | 0xffffd038 | 0xf7fb5808 | 0x56556213 | 0x565561ff 0x0 0xf7deaee5 0x1 |
ret | 0xffffd034 | 0xffffd038 | 0x565561ff | 0x56556216 | 0x0 0xf7deaee5 0x1 0xffffd0d4 0xffffd0dc |
add $0x2ddd,%eax | 0xffffd038 | 0xffffd038 | 0x565561ff | 0x565561ff | 0x0 0xf7deaee5 0x1 0xffffd0d4 0xffffd0dc |
call 0x565561c6 | 0xffffd034 | 0xffffd038 | 0x56558fdc | 0x56556206 | 0x8 0x0 0xf7deaee5 0x1 0xffffd0d4 0xffffd0dc 0xffff |
endbr32 | 0xffffd030 | 0xffffd038 | 0x56558fdc | 0x565561c6 | 0x5655620b <main+24> 0x8 0x0 0xf7deaee5 0x1 0xffffd0d4 0xffffd0dc |
push %ebp | 0xffffd030 | 0xffffd038 | 0x56558fdc | 0x565561ca | 0x5655620b <main+24> 0x8 0x0 0xf7deaee5 0x1 0xffffd0d4 0xffffd0dc |
mov %esp,%ebp | 0xffffd02c | 0xffffd038 | 0x56558fdc | 0x565561cb | 0xffffd038 0x5655620b <main+24> 0x8 0x0 0xf7deaee5 0x1 |
sub $0x10,%esp | 0xffffd02c | 0xffffd02c | 0x56558fdc | 0x565561cd | 0xffffd038 0x5655620b <main+24> 0x8 0x0 0xf7deaee5 |
call 0x56556213 | 0xffffd01c | 0xffffd02c | 0x56558fdc | 0x565561d0 | 0x56556241 <__libc_csu_init+33> 0xf7fe22d0 0x0 |
mov (%esp),%eax | 0xffffd108 | 0xffffd02c | 0x56558fdc | 0x56556213 | 0xffffd438 0xffffd461 |
ret | 0xffffd108 | 0xffffd02c | 0x565561d5 | 0x56556216 | 0x565561d5 |
add $0x2e07,%eax | 0xffffd01c | 0xffffd02c | 0x565561d5 | 0x565561d5 | 0x56556241 <__libc_csu_init+33> 0xf7fe22d0 0x0 0x0 0xffffd038 0x5655620b <main+24> 0x8 0x0 |
movl $ox1f,-0x4(%ebp) | 0xffffd01c | 0xffffd02c | 0x56558fdc | 0x565561da | 0x56556241 <__libc_csu_init+33> 0xf7fe22d0 0x0 0x0 0xffffd038 0x5655620b <main+24> |
pushl 0x8(%ebp) | 0xffffd01c | 0xffffd02c | 0x56558fdc | 0x565561e1 | x56556241 <__libc_csu_init+33> 0xf7fe22d0 0x0 0x1f 0xffffd038 0x5655620b <main+24> |
call 0x565561ad | 0xffffd018 | 0xffffd02c | 0x56558fdc | 0x565561e4 | 0x8 0x56556241 <__libc_csu_init+33> 0xf7fe22d0 0x0 0x1f 0xffffd038 0x5655620b <main+24> |
endbr32 | 0xffffd014 | 0xffffd02c | 0x56558fdc | 0x56558fdc | |
push %ebp | 0xffffd014 | 0xffffd02c | 0x56558fdc | 0x565561b1 | |
mov %esp,%esp | 0xffffd010 | 0xffffd010 | 0x56558fdc | 0x565561b4 | |
...... | |||||
add $0x3,%eax | 0xfffd010 | 0xffffd010 | 0x8 | 0x565561c1 | |
pop %ebp | 0xffffd010 | 0xffffd010 | 0xb | 0x565561c4 | |
ret | 0xffffd014 | 0xffffd02c | 0xb | 0x565561c5 | |
add $0x4,%esp | 0xffffd018 | 0xffffd02c | 0xb | 0x565561e9 | |
mov -0x4(%ebp),%edx | 0xffffd01c | 0xffffd02c | 0xb | 0x565561ec | |
add %edx,%eax | 0xffffd01c | 0xffffd02c | 0xb | 0x565561ef | |
leave | 0xffffd01c | 0xffffd02c | 0x2a | 0x565561f1 | |
ret | 0xffffd030 | 0xffffd038 | 0x2a | 0x565561f2 | |
参考链接: