在WinDBG中查看内存的命令
当我们在调试器中分析问题时, 经常需要查看不同内存块的内容以分析产生的原因, 并且在随后验证所做出的假设是否正确. 由于各个对象的状态都是保存在内存中的, 因此内存的内容也就相当于对象的状态.
d命令最常见的格式就是根据指定的类型信息来显示存储在某地址中的数据. 调试器并不会去猜测这个地址上存储的是什么数据, 因为在大多数情况下猜测都是错误的. 所以需要用户显式地制定按照何种格式来解析数据. 命令格式如下:
d [type] [address range]
- d - 该命令按照上一个d*命令的同样格式显示数据. 如果前面没有d*命令的话, 它跟db的效果相同.
- da - ASCII 字符. 每行最多显示48个字符. 直到遇到一个null字节, 或者指定的范围内的所有字符都已经被显示. 所有无法打印的字符都会被显示为" . "
- db - 字节值或ASCII字符. 默认长度为128字节.
- dc - 双字(4字节)值和ASCII字符. 默认长度为32 DWORDs(128字节)
- dd - 双字(4字节). 默认长度为32 DWORDs(128字节)
- dD - 双精度浮点数(8字节). 默认15个数字(120字节)
- df - 单精度浮点数(4字节). 默认16个数字(63字节).
- dp - 指针大小的值. 相当于dd或dq, 具体取决于计算机的处理器架构是x86还是x64. 默认长度32个双字, 或16个四字(128字节).
- dq - 四字值(8字节). 默认16四字(128字节).
- du - Unicode字符. 每行显示至多48个字符. 直到遇到一个null字节, 或者指定的范围内的所有字符都已经被显示. 所有无法打印的字符都会被显示为" . "
- dw - 字值(2字节). 默认显示64个字(128字节).
- dW - 字值(2字节)和ASCII字符. 默认64个字(128字节).
- dyb - 二进制值和字节值. 默认32个字节.
- dyd - 二进制值和四字值(4字节). 默认是8个双字(32字节).
这里顺便把计算机中的计量单位也总结一下吧.
============
bit(比特) – 1 or 0
1 byte(字节) = 8 bit(比特)
1 word(字) = 2 byte = 16 bit
1 dword(双字) = 4 byte = 32 bit
1 qword(四字) = 8 byte = 64 bit
1 ASCII character = 1 byte
1 Unicode character = 2 byte
另一种方式 - d*s
===========
该命令形式可以将内存区域转储出来, 并且将内存中的每一个元素都视作一个单元对其进行解析. 这个命令有三种形式, 通常被称之为d*s命令.
dds 将四个字节视作一个单元
dqs 将八个字节视作一个单元
dps 则根据当前处理器架构来选择最合适的长度. 它将每个从内存读取出来的值都作为某种数据类型的指针.
在内存中搜索某个值 - 命令s
============
命令s(表示搜索search), 是一个非常有用的命令, 可以用来在调试目标内找出已知的值.
这个命令的参数包括素要搜索的类型和值.
s –d 0012ff40 L1024 c0000005
其中-d代表双字DWORD, 是搜索的类型. 其他类型例举如下:
- b – Byte
- w – WORD
- d – DWORD
- q – QWORD
- a – ASCII字符串
- u – Unicode字符串
查看内存的每个位置上都包含着什么
==============
在调试时, 对象和栈都包含了大量的指针, 我们无法很快地猜测出他们所表示的数据. 虽然我们可以很容易地将内核空间的地址与用户态空间的地址分开, 但要把一个表示栈的地址和一个表示堆的地址区分开却不容易. 我们可以使用一个很有用的扩展命令!address <your address>来解决这个问题.
该命令的参数为一个地址, 如果没有指定地址参数, 那么这个扩展命令将搜索并且枚举所有的内存区域并给出详细的信息.