快速业务通道

小览CallStack(调用栈)(三)-用调试器脚本查看调用栈信息

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29

在这一系列之前的两篇文章中,我介绍了如何在windbg中查看调用栈的相关 信息(详见小览call stack(调用栈)(一)),以及调用约定(详见小览call stack(调用栈) (二)——调用约定)。今天的这篇博客在二者的基础 之上,介绍如何使用调式器脚本程序来观察调用栈。对CallStack感兴趣的朋友 可以在此基础上开发更加详尽的脚本来观察CallStack的信息;对调试感兴趣的 朋友则可以看一下DScript的用处。

我们先来看一个例子,下面的程序并不是一个优美的程序片段,但是它能够 帮助我们说明问题。程序使用了一个简单的递归,把1到参数d的和累加到sum之 上。在main中,我们把d设为10,这样,在断点处,我们就能获得一个深度为11 的调用栈。

#include <stdio.h>

int SumToOne(int d, int sum)
{
    sum += d;
    if (d != 1)
        sum = SumToOne(d-1, sum);
    else
        sum = sum; // 这条语句方便设置断点
    return sum;
}

void main()
{
    int sum = SumToOne(10, 0);
    printf("sum=%d", sum);
}

然后,在当前文件夹下,编辑调试器脚本文件DumpStack.txt,内容如下

.printf "Dump %d frames\n", ${$arg1}
r $t1=@ebp;
.for (r $t0=1; $t0<=${$arg1}; r $t0=$t0+1)
{
    .printf "frame %d, d=%d sum=%d\n", $t0, poi($t1+8), poi($t1+c)
    r $t1=poi($t1)
}

在windbg中,运行程序,当程序停止在断点处时,执行脚本

$>a< “dumpStack.txt”a

如下图所示

我们看到了10个frame以及它的参数信息。

现在,对这个调试脚本稍加解释,稍显来看看脚本的语法:

调试脚本的调用方法,windbg的语法是$>a< “脚本文件名 ”参数。其中$>a<中的a示意运行脚本的时候传入参数(argument)

调试脚本的参数:在调试脚本中,用${$argi}来引用第i个参数。由于windbg 默认16进制数,所以我们在调用这个参数的时候,用了a($>a< "dumpStack.txt" a)

脚本变量的赋值和引用:这里使用了windbg别名(alias)的语法,大家可以把 别名类比成c中的宏。在赋值的时候,用r $别名= 的格式,引用的时候,使用$ 别名

取值操作:c中的*p操作在windbg中,要用poi(p),原因是因为windbg默认支 持MSAM语法。

控制语句:.for语句的使用和任何一种语言的for语句思想一样,不再多述

输出语句:.printf和c中的printf也基本相似,这里也不多述

了解了语法之后,来看看算法:

脚本通过poi($t1+8), poi($t1+c)来显示每个frame中d和sum的值,这里$t1 代表了每个frame中ebp的值,所以简单的说,就是把每个frame中ebp+8,ebp+c 的值输出。在介绍调用约定的博客中,我讲述了这个偏移量的由来,在这里重温 一下。由于函数SumToOne是stdcall,压栈顺序从右往左,如下表所示

前一个ebp
eip
d
sum
ebp指向存储前一个ebo的位置,所以d的位置在ebp+8,sum在ebp+c

前往下一个frame,只需要把栈上ebp位置的值取出,作为新的ebp就可以了。 因为基本上每一个程序在进行栈操作之前都会备份老的ebp(push ebp),然后把 当前的esp作为新的ebp(mov ebp, esp)

总结一下,今天这篇博文作为这个系列的结束,通过一个调式器脚本,复习 了之前讲述的调用栈的相关概念。同时也展示了调试器脚本的相关语法。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号