命令脚本,就是将完成某个特定任务的相关命令组合在一起,保存在脚本文件里,加载到Windbg里执行,达到我们的目的。你可以理解为脚本就是一种语言,就像c或者汇编,但是他不需要编译器将其编译为可执行文件,而是由解释器将其内容翻译为对应的动作。而Windbg的脚本就是利用Windbg作为解释器,将脚本内容翻译为实际的动作。
既然可以作为一种语言,那么它就具有一般语言通常包含的要素:数据类型、变量、表达式、语句、函数等,下面我们分别简单讲一下。
一、数据类型
关于数据类型,Windbg的帮助里没有明确列举,但是,在使用时一般会遇到,数值和字符串这两种。
- 数值
数值没有太多需要解释的,和所有编程语言里的整数含义一样,在表示的时候有进制之分。
代码:
2进制 0b
8进制 0n
10进制 0t
16进制 0x - 字符串
字符串用一对 ” 括起来。比如上面的 ”hello windbg”。
二、变量
在windbg中变量的定义很特别,实际上,它并没有变量这个概念,所以,在学习的时候会觉得很别扭。不过,我们换个思路就容易了,变量实际上就是为了保存临时结果, 如果只想保存一些数值,那么伪寄存器(参考Windbg命令的语法规则系列)应该是比较好的选择,windbg提供了20个伪寄存器$t0-$t19,供命令保存临时数值变量。称他们为伪寄存器是有原因的,首先对他们的操作和寄存器一样,都是使用r命令,在C++表达式里都前面需要加@符,但是他们又不是真正的寄存器,只是windbg定义的名字而已。使用这些伪寄存器也是很方便的:
代码:
0:000> r $t0=0x123 0:000> r $t0 $t0=00000123 0:000> r eax eax=004c1b89 0:000> r $t0=@eax 0:000> r $t0 $t0=004c1b89
从上面的例子也可以看出r命令后面的@是可以省略的。
三、别名
别名和变量还有些区别,变量是在执行过程中取他的值,而别名更像是宏,在解释时直接用内容替换原始操作数。别名有两种,一种是固定名字的,一种是自定义的。
- 固定名字别名
固定名字别名和伪寄存器很类似,Windbg提供了10个,$u0-$u9。使用的时候依然是r命令,不过要在“u”前面加个“.”,像下面这样:
代码:
0:000> r $.u0 = "123" 0:000> .echo $u0 123
- 自定义别名
自定义别名会复杂一些,但是,有了它的存在,我们才可以为内存中的一些字符串定义别名。操作自定义别名有3个命令:as,ad,al。
As 定义一个别名,其强大之处在于,可以指定一个内存地址,然后将内存中的内容定义为别名。
代码:
0:000> .dvalloc 10 Allocated 1000 bytes starting at 00010000 0:000> ea 00010000 "123456" 0:000> as /ma ${/v:test} 0x00010000 0:000> .echo test 123456