ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

x86手推调用栈

2021-12-20 16:36:07  阅读:132  来源: 互联网

标签:0xbffff048 调用 x86 int 手推 gdb test main 0xbffff078


当程序crash的时候,我们可以通过coredump文件,来定位问题。比如使用bt命令可以完整的展开函数的调用栈。但是有些时候,部分栈的数据可能被损坏,导致gdb无法直接显示函数的调用栈。那么这时就需要我们手工展开函数栈。   关于x86的函数调用栈的示意图基本如下图所示: img_38abab7e0d4e02fdc12c84323b15b8f4.gif   关于参数的压栈顺序,上图为cdecl方式,这个可以通过编译选项修改。GCC默认使用cdecl。   下面看一下例子:
  1. #include stdlib.h>
  2. #include stdio.h>
  3. static int test(int a, int b, int c)
  4. {
  5.     return a+b+c;
  6. }
  7. int main()
  8. {
  9.     int a = 1;
  10.     int b = 2;
  11.     int c = 3;
  12.     int d = test(a, b, c);
  13.     printf("%d\n", d);
  14.     return 0;
  15. }
编译:gcc -g -Wall test.c 进入test,查看函数调用栈:
  1. Breakpoint 1, test (a=1, b=2, c=3) at test.c:7
  2. 7 return a+b+c;
  3. Missing separate debuginfos, use: debuginfo-install glibc-2.11-2.i686
  4. (gdb) bt
  5. #0 test (a=1, b=2, c=3) at test.c:7
  6. #1 0x08048412 in main () at test.c:16
那么现在查看一下寄存器:
  1. eax 0x1 1
  2. ecx 0x2c0187d8 738297816
  3. edx 0x1 1
  4. ebx 0x73fff4 7602164
  5. esp 0xbffff048 0xbffff048
  6. ebp 0xbffff048 0xbffff048
  7. esi 0x0 0
  8. edi 0x0 0
  9. eip 0x80483c7 0x80483c7 test+3>
  10. eflags 0x286 [ PF SF IF ]
  11. cs 0x73 115
  12. ss 0x7b 123
  13. ds 0x7b 123
  14. es 0x7b 123
  15. fs 0x0 0
  16. gs 0x33 51
得到ebp的地址为0xbffff048,现在检查这个地址的内存
  1. (gdb) x /8x 0xbffff048
  2. 0xbffff048: 0xbffff078 0x08048412 0x00000001 0x00000002
  3. 0xbffff058: 0x00000003 0x0073fff4 0x00000001 0x00000002
下面分析一下这些内存的内容: 1. 0xbffff078:为test的调用者,即main函数的bp地址;BP地址即为该函数的栈顶指针。 2. 0x08048412:为test的返回地址,与前面的bt的输出相符; 3. 后面的0x00000001,0x00000002,0x00000003,为传给test的三个参数,且参数顺序为由右向左压栈——注意这个顺序是可以通过改变编译参数改变的。   回到main中,验证一下bp寄存器的内容:
  1. 0x08048412 in main () at test.c:16
  2. 16 int d = test(a, b, c);
  3. Value returned is $2 = 6
  4. (gdb) info registers
  5. eax 0x6 6
  6. ecx 0x39ff7a48 973044296
  7. edx 0x1 1
  8. ebx 0x73fff4 7602164
  9. esp 0xbffff050 0xbffff050
  10. ebp 0xbffff078 0xbffff078
可见BP的地址确实为0xbffff078,与之前的分析相符。   注:关于压栈顺序,参数的传递方式等等,都可以通过编译选项来指定或者禁止的。本文的情况为GCC的默认行为。

标签:0xbffff048,调用,x86,int,手推,gdb,test,main,0xbffff078
来源: https://www.cnblogs.com/axjlxy/p/15711442.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有