Windbg脚本中的“变量”之坑(其实叫“别名”)

4 篇文章 0 订阅
4 篇文章 0 订阅

在用windbg调试程序的时候,有些命令会重复使用,因此想把这些命令封装为脚本文件,实现自动化。但是在对其“变量”(别名)的使用中遇到了不少坑,致使出现意料之外的值,或者脚本在重复调用时出现前后结果不一致的状况。比如下面的脚本:

ad /q *;
aS ${/v:MyVar} 0x1;
.echo `MyVar` is ${MyVar};

aS ${/v:MyVar} 0x2;
.echo `MyVar` is ${MyVar};

al;

这个脚本先删除所有别名,然后指定MyVar作为数字0x1的别名,并打印MyVar,接着将MyVar作为数字0x2的别名,再打印它,最后al列出所有别名。按往常的编码思维,运行完这个脚本,预想打印的前两行应分别为 `MyVar` is 0x1`MyVar` is 0x2,然而实际结果却是:
在这里插入图片描述
通过查阅使用手册及外网论坛,总结了关于windbg脚本中的别名的如下几个要点:

  • 别名相当于C语言中的宏。因此它出现的位置会在执行命令前替换成它的真实值。如果这个别名未被使用,则直接替换为别名的本名。
  • windbg在遇到一个.block {}块时,会将块中所有别名同时展开。
  • 不同.block {}块中的别名会各自展开。
  • 一个脚本文件相当于一个.block {}块。

也就是说,上面的代码在执行前,先把.echo语句中的${MyVar}展开为它的真实值了,而这时MyVar并未作为别名,所以打印出来的是${MyVar}

如果要让第一次"赋值"有效,从而让第二条.echo语句打印出赋予了新值的${MyVar},则可以利用上述的第三个要点,即使用多个.block {}块:
在这里插入图片描述
这样一来,脚本文件就不会在一开始展开所有的${MyVar},而是先展开第一个.block {}块中的${MyVar},并运行完块中的指令。之后展开第二个.block {}块中的${MyVar},这时${MyVar}已经在第一个.block {}块被“赋值”为0x1,所以第二个块中的${MyVar}便展开为0x1

还有一种吊诡的情况,如果ad /q *;这行命令不在第一行(比如,在它前面加个空行),脚本的运行结果也不一样:
在这里插入图片描述

这意味着ad /q *;这一行并没有生效,而因为我在执行脚本前先把MyVar作为0x3的别名,所以脚本中${MyVar}直接以其已有的真实值0x3展开。原因暂不明了,而这也导致我无法在文件开头加一些注释,无奈之下只能将注释放在文件结尾了。

参考资料

[1] https://stackoverflow.com/questions/36969406/does-windbg-aliases-really-be-expanded-when-a-new-block-of-code-is-entered

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值