无论是分析程序崩溃原因,还是解决程序hang问题,我们最常查看的就是程序调用堆栈。学会windbg调用堆栈命令,以及理解堆栈中的各个参数的意义就显得至关重要。

上图就是一个典型的Windbg堆栈,如果不理解ChildEBP、RetAddr、Args to Child等参数意义,以及它们之间的来龙去脉,调试工作将很难进行下去。

1. 函数参数

        函数的参数传递有二种方式:堆栈方式、寄存器方式。如果是堆栈方式传递的,就需要定义参数在堆栈中的传递顺序,并约定函数被调用之后,由谁来平衡堆栈;如果是寄存器方式传递的,就需要确定参数存放在哪个寄存器中。每一种方式都有其优缺点,而且与使用的编程语言有关系,不存在哪种方式好与坏。

如Visual Studio中的C++工程,可以C++ --> 高级 --> 调用约定中进行设置:

        常用的调用约定类型有__cdecl、stdcall、PASCAL、fastcall。除了fastcall可以支持以寄存器的方式来传递函数参数外,其他的都是通过堆栈的方式来传递函数参数的。

利用堆栈传递参数

        堆栈是一种“后进先出”的数据结构,ESP寄存器始终指向栈顶。栈中数据地址从底部到顶部依次减小,也就是说,栈底对应高地址,栈顶对应低地址。

调用函数时,调用者依次把参数压栈,然后调用函数,函数被调用之后,在堆栈中取得参数数据。函数调用结束以后,堆栈需要恢复到函数调用之前的样子,具体由调用者来恢复还是由函数自身来恢复,根据不同的调用约定类型采用不同的方式。

约定类型 __cdecl stdcall PASCAL fastcall
参数传递顺序 从右到左 从右到左 从左到右 使用寄存器
平衡堆栈者 调用者 函数自身 函数自身 函数自身

__cdcel是C/C++/MFC程序默认的调用约定。

stdcall是Win32中绝大多数 API函数的约定方式,也有少部分使用__cdcel约定方式,如wsprintf等。

        在windows C/C++开发中常用的就是__cdecl和stdcall这2种调用约定。

假设调用函数int add(int a, int b), 按照不同的调用约定来调用它。从调用者的视角来看,其汇编代码分别表示如下:

__cdecl

push b     ;参数按从右到左传递
push a
call add
add esp, 8 ;调用者在函数外部平衡堆栈

stdcall

push b     ;参数按从右到左传递
push a
call add ;函数自己内部平衡堆栈

在函数调用过程中,参数入栈的过程:

上图中,EBP和函数返回地址都是地址,在32位程序中地址占4个字节。在函数的一次调用过程中EBP是不会变化的,函数调用完之后会将EBP恢复为暂存在堆栈中的原EBP值。所以,通过EBP可以获取函数各个参数的值:

参数a = EBP + 0x8

参数b = EBP + 0xC

2. Windbg堆栈命令

2.1 显示堆栈信息k*

[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] [FrameCount]
[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtr [FrameCount]
[~Thread] k[b|p|P|v] [c] [n] [f] [L] [M] = BasePtr StackPtr InstructionPtr
[~Thread] kd [WordCount]

参数:

Thread  指定显示哪个线程的调用堆栈。如果省略该参数,则显示当前线程的调用堆栈。*显示所有线程的调用堆栈。

b  显示每个函数的前3个参数。

p  显示每个函数的所有参数。参数列表包括每个参数的类型、名称、值。

        如上图,可以看到函数的每个参数的类型,名称,值。但是这个需要有对应的符号文件(pdb),没有应用程序的符号文件只能显示系统API的参数信息。

P  类似p。不同之处在于,每个参数显示在单独的行上面。

n  显示调用堆栈中每帧的序号(一般称栈帧,如栈帧3)。

FrameCount  指定显示调用堆栈的帧数,即调用堆栈的深度。默认为16进制格式。默认帧数为0x14=20

2.2 切换到指定帧信息.frame

        调用堆栈显示出来之后,如果想知道调用某帧时的相关信息,可以使用.frame 来切换指定帧,然后就可以使用如dv命令显示局部变量等。

.frame [/c] [/r] [FrameNumber]

/c

/r  显示执行该帧时寄存器的值。

FrameNumber  指定要切换到的帧号。

3. 实例分析

kbn 显示堆栈信息:

栈帧12

调用add函数,参数1=00000001,参数2=000000002,EBP=0015fc0c

根据图1得知,函数返回地址=EBP+4,我们使用dw命令来验证。

参考:

《软件调试》张银奎 著

《格蠹汇编》张银奎 著

《加密与解密》第三版 段刚编著

Windbg查看调用堆栈(k*)的更多相关文章

  1. VC调试篇:ASSERT(FALSE)时怎么办?查看调用堆栈

    问题简述 我们在调试程序时,经常会遇到程序中断的情况,就像下图这样. 我艹,这该怎么办,我们一下子就懵逼了.我们选择中断,常常会跳到一个莫名其妙的地方去. 正是这个断言 ASSERT(::IsWind ...

  2. Windbg Call Stack(调用堆栈)窗口的使用

    调用堆栈是指向程序计数器当前位置的函数调用链.调用堆栈的顶部函数是当前函数,下一个函数是调用当前函数的函数,依此类推.显示的调用堆栈基于当前程序计数器,除非更改寄存器上下文. 在 WinDbg 中,可 ...

  3. vs2010 调试 调用堆栈 窗口

    msdn 如何使用call stack窗口: http://msdn.microsoft.com/zh-cn/library/a3694ts5(v=vs.90).aspx 使用“调用堆栈”窗口可以查看 ...

  4. c# 如何获取当前方法的调用堆栈

    c# 调试程序时常常需要借助 call stack 查看调用堆栈,实际上通过code也可以获取: class Program { static void Main(string[] args) { T ...

  5. [转]如何利用ndk-stack工具查看so库的调用堆栈【代码示例】?

    如何利用ndk-stack工具查看so库的调用堆栈[代码示例]? http://hi.baidu.com/subo4110/item/d00395b3bf63e4432bebe36d Step1:An ...

  6. 怎样重建一个损坏的调用堆栈(callstack)

    原文作者:Aaron Ballman原文时间:2011年07月04日原文地址:http://blog.aaronballman.com/2011/07/reconstructing-a-corrupt ...

  7. 如何重建一个损坏的调用堆栈(callstack)

    原文作者:Aaron Ballman原文时间:2011年07月04日原文地址:http://blog.aaronballman.com/2011/07/reconstructing-a-corrupt ...

  8. 在 Visual Studio 中调试时映射调用堆栈上的方法

    本文转自:https://msdn.microsoft.com/zh-cn/library/dn194476.aspx 1.创建代码图,以便在调试时对调用堆栈进行可视化跟踪. 你可以在图中进行标注以跟 ...

  9. Linux 如何使用gdb 查看core堆栈信息

    转载:http://blog.csdn.net/mergerly/article/details/41994207 core dump 一般是在segmentation fault(段错误)的情况下产 ...

随机推荐

  1. nyoj_61: 传纸条(一)

    题目链接 使用双线dp,假设两个人同时从左上角移动到右下角,且满足路线不交叉,另k=x1+y1=x2+y2压缩状态进行优化.每次状态转移满足 x1,x2,y1,y2都在矩阵范围内,且(x2,y2)在相 ...

  2. 配置ssh免密码登录——集群学习日记

    度过了难熬的考试月时期之后,最近和小伙伴一起参加的的比赛进入了紧张的准备时期.在进行工作的时候,发现有很多基础的知识点,自己不是很清楚以及了解,所以在想,要不就边学习的时候边写下学习日记,以供自己后来 ...

  3. (转)Mysql数据库存储引擎

    什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合.     我们通常说的MySql数据库,sql server数据库等 ...

  4. Echarts关系图-力引导布局

    需要做一个树形图,可以查看各个人员的关系. 可伸缩的力引导图-失败 刚开始,打算做一个可展开和伸缩的,搜索时候发现CSDN有一篇美美哒程序媛写的Echarts Force力导向图实现节点可折叠. 这里 ...

  5. 程序员面试必备-链表各种操作及其实现方法(c实现)

    链表是一种最简单的数据结构之一,经常会被面试官用来考察应聘者的基础扎不扎实,最近也到了求职季,所以我把自己对链表的一些理解写出来,希望能跟大家交流交流: 链表的概念其实挺简单,无非就是一个利用指针将数 ...

  6. springboot用thymeleaf模板的paginate分页

    本文根据一个简单的user表为例,展示 springboot集成mybatis,再到前端分页完整代码(新手自学,不足之处欢迎纠正): 先看java部分 pom.xml 加入 <!--支持 Web ...

  7. Struts2漏洞解决

    如果你也正在使用Struts2作为web层框架做开发或者做公司的送检产品,然后被告知有各种各样的Struts2漏洞,那本篇博客值得你花时间来喽上一两眼. 前端时间抽空为公司做了新一代的送检产品,为了方 ...

  8. input file样式修改,图片预览删除功能

    本篇对input file进行了修改,改成自己需要的样式,类似验证身份上传身份证图片的功能. 效果图如下: 这里主要展示上传预览图片功能,对于删除功能的html及css写的比较粗糙,对于想要精细表现这 ...

  9. JBOSS安装配置详细教程

    首先在http://jbossas.jboss.org/downloads/下载相关程序我下载的是 JBoss AS 6.1.0.Final 1.配置jboss环境 1.1用户变量path后面添加 ; ...

  10. java解析xml汇总(转自倾城幻影-Java解析xml汇总,链接:http://www.cnblogs.com/jiugehuanying/archive/2012/01/12/2320058.html)

    [引言] 目前在Java中用于解析XML的技术很多,主流的有DOM.SAX.JDOM.DOM4j,下文主要介绍这4种解析XML文档技术的使用.优缺点及性能测试. [一.基础知识--扫盲] sax.do ...