windbg内存查看(d*)
d*命令
d{a|b|c|d|D|f|p|q|u|w|W} Address [/c ColumuWidth] [l Length]
Address:查看address地址处的内存。
ColumnWidth:Windbg每行显示的多少个数据单位。默认为16进制数字,十进制需加前缀0n
Length:总共显示Address
地址后的多少个数据单位。
如:
db /c 0n32 06beee78 l 0n128
表示 显示06beee78之后的128个byte,每行显示32个byte,
dw /c 0n32 06beee78 l 0n128
表示 显示06beee78之后的128个word,每行显示32个word。
db: 按照Byte(单字节)来显示。如果为ASCII字符就显示ASCII字符。会在第八个和第九个16进制间插入分隔符-
;右边显示每个16进制数据对应的ASCII字符,ASCII不支持的、或者不能显示的字符用.
点号代替。
如:
地址002afa48指向一个char s[51]
的字符串:
红框中的-表示第八个和第九个16进制数据之前的分隔符。
蓝框中的表示ASCII字符。
地址002afa84指向长整型变量 long a = 0x12345678;
为什么没有按照12345678的顺序显示,而是显示的78563412了? 这个涉及到了数据存储的大小端问题,不清楚的话可以先看1.2节。
dw:按照Word(双字节)来显示。
现在显示的是5678 1234
dd: 按照Double-Word(4个字节)来显示。
dq :按照8个字节来显示。
du: 按照Unicode字符格式来显示。
df :按照单浮点(float,4字节)来显示。
dD :按照双浮点(double,8字节)来显示。
dt:不仅可以显示内存的值,还能显示变量的值、类型、结构等信息。
dv:显示局部变量、全局变量等。
大小端
什么是大小端?
Big-Endian和Little-Endian的定义如下:
Little-Endian 数据的低位字节位存放在内存的低地址端,高位字节存放在内存的高地址端。
Big-Endian 数据的高位字节位存放在内存的低地址端,低位字节存放在内存的高地址端。
比如1.1节中提到的数字0x12345678,它总共占4个字节(1个字节8位,2个16进制占8位,所以1个字节最大表示0xFF)。这个数据在大小端模式下,在内存中的存储布局为:
大端模式:
低地址 -----------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
小端模式:
低地址 ------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12
因为windows是小端模式,所以,db 002afa84
以字节为单位显示002afa84地址处的数据(0x12345678)会显示为:
更详细的介绍可以参考:http://blog.csdn.net/ce123_zhouwei/article/details/6971544
程序判断大小端
bool IsLittleEndian() {
int a = 0x1234;
char c = *(char *)&a;
if (c == 0x34) {
return true;
}
return false;
}
STL(std::string)显示
文件stl_show.cpp:
void test1(long l, char* pMsg, std::string str, std::vector<int> vInts) {
printf("%ld, %s, %s, %d", l, pMsg, str.c_str(), vInts.size()); // 第10行
}
int main()
{
long l = 0x12345678;
char szMsg[100] = { "I'm ok" };
std::string strInfo = "hello 123";
std::vector<int> vInts;
vInts.push_back(1);
vInts.push_back(2);
vInts.push_back(3);
test1(l, szMsg, strInfo, vInts);
return 0;
}
test1函数第3个参数为std::string,在第10行printf函数下断点bp stl_show.cpp:10
,g
执行到断点,kvn查看堆栈信息:
0:000> kbn
# ChildEBP RetAddr Args to Child
00 002af970 0018899e 12345678 002afb10 0033e1d8 stl_show!test1+0x1e [c:\users\jeffery\desktop\stl_show\stl_show\stl_show.cpp @ 10]
01 002afb94 00189b4e 00000001 0033db98 0033cbd0 stl_show!main+0x14e [c:\users\jeffery\desktop\stl_show\stl_show\stl_show.cpp @ 26]
02 002afba8 001899b0 9bea5bac 00000000 00000000 stl_show!invoke_main+0x1e [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 64]
03 002afc00 0018984d 002afc10 00189b68 002afc1c stl_show!__scrt_common_main_seh+0x150 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 253]
04 002afc08 00189b68 002afc1c 76de336a 7efde000 stl_show!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 296]
05 002afc10 76de336a 7efde000 002afc5c 77659902 stl_show!mainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17]
06 002afc1c 77659902 7efde000 776bd5e0 00000000 kernel32!BaseThreadInitThunk+0xe
07 002afc5c 776598d5 001810f5 7efde000 00000000 ntdll!__RtlUserThreadStart+0x70
08 002afc74 00000000 001810f5 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b
栈帧#0显示第三个参数值为0033e1d8,因为现在加载了pdb,我直接使用dt -b 0033e1d8
是可以显示std::string的结构和值的,但windbg却提示我:
Symbol not found at address 0033e1d8.
无论0033e1d8地址存储的是什么数据,但windbg识别不了这是std::string结构,我猜想这个值可能是string结构中某个成员的值,下面我来证明我的猜想。
因为函数test1前2个参数各占4个字节,所以第三个参数地址应该是EBP+0x8+0x4+0x4=EBP+0x10=002af970+0x10=002af980
,
查看该地址的内容 dd 002af980
刚好和栈帧#0显示第三个参数值为0033e1d8一样。
所以windbg针对std::string类型的参数提示多做了一步,这一步刚好也是多余的。
现在需要分析std::string结构,在pdb文件的情况直接使用dt -b str
来查看str变量的结构,如图:
可以看到,字符串缓冲区的地址等于参数地址+0x004偏移即0x002af980+0x004,使用db 0x002af980+0x004
查看字符串内容:
综上所述,对于std::string变量,输出其存储的字符串的方法为:
db 变量地址+0x4
,这种方法无论是否有pdb符号文件都适用。
在有pdb的情况,使用 !stl 变量名
无疑是最快捷的方式。
windbg内存查看(d*)的更多相关文章
- Windbg 内存命令 《第四篇》
内存是存储数据.代码的地方,通过内存查看命令可以分析很多问题.相关命令可以分为:内存查看命令和内存统计命令.内存统计命令用来分析内存的使用状况. 一.查看内存 有非常丰富的内存查看命令,它们被容易为d ...
- jboss内存查看管理 .
jboss内存查看管理 标签: jbossjavagenerationjvmclassjar 2009-04-09 14:47 4248人阅读 评论(2) 收藏 举报 本文章已收录于: // ' ...
- PHP错误日志和内存查看(转)
本篇文章给大家带来的内容是关于PHP错误日志和内存查看的方法介绍(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.通过命令查看服务器上一共开了多少的 php-cgi 进程: ...
- Linux下内存查看命令
在Linux下面,我们常用top命令来查看系统进程,top也能显示系统内存.我们常用的Linux下查看内容的专用工具是free命令. Linux下内存查看命令free详解: 在Linux下查看内存我们 ...
- [转]java线程安全、jstack\线程dump、内存查看分析总结
http://jameswxx.iteye.com/blog/808546 java线程安全总结二 http://jameswxx.iteye.com/blog/1041173 jstack和线程du ...
- linux 内存查看方法:meminfo\maps\smaps\status 文件解析
linux 下面查看内存有多种渠道,比如通过命令 ps ,top,free 等,比如通过/proc系统,一般需要比较详细和精确地知道整机内存/某个进程内存的使用情况,最好通过/proc 系统,下面介绍 ...
- Linux下内存查看及详解
在Linux下面,我们常用top命令来查看系统进程,top也能显示系统内存.我们常用的Linux下查看内容的专用工具是free命令. Linux下内存查看命令free详解: 在Linux下查看内存我们 ...
- 使用WinDBG调试查看C#内存转储文件
有时候我们想查看一个正在运行的程序内存中的数据,可以在任务管理器将内存状态保存为转储文件,并使用WinDBG验证,这里我们来试试: 0.安装WinDBG 1.首先写个代码用来测试 一个class pu ...
- 在WinDBG中查看内存的命令
当我们在调试器中分析问题时, 经常需要查看不同内存块的内容以分析产生的原因, 并且在随后验证所做出的假设是否正确. 由于各个对象的状态都是保存在内存中的, 因此内存的内容也就相当于对象的状态. d命令 ...
随机推荐
- Android帧动画笔记
创建drawable资源文件,选择animation-list<?xml version="1.0" encoding="utf-8"?><a ...
- Go语言学习笔记(三)数组 & 切片 & map
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 数组 Arrays 数组是同一种数据类型的固定长度的序列. 数组是值类型,因此改变副本的值,不会改变本身的值: 当 ...
- APP测试 - android os6,7 新增特性测试
背景 android os6,7推出后,公司的APP在市场上面反映的一些问题.初始方案在7月份已经整了一份,但是邮件发出大部分同学都看不到,这里在博客里面整理后再在部门内邮件发出来. android ...
- iOS开发实战-时光记账Demo 本地数据库版
现在记账APP也是用途比较广泛 自己写了个简单的demo 欢迎指正 效果 分析 1.思维推导 首先简单的做了下思维推导 2.文件结构 大致框架想好后就可以着手开始准备了 数据库管理:coreData ...
- Python实现单词查询&文件查找
最近学C++ Primer,做到第十二章有个习题.要求针对英文文本,对于用户想搜索的单词,打印出该单词在文本中出现的总次数,单词所出现行号及对应的行内容:单词在一行内出现多次,只打印该行一次.C++的 ...
- macOS下配置scapy环境
测试需求需要用到scapy库,遂在本机配置scapy环境,但最后一直提示权限问题,可能和sip有关系. 最后在同事介绍下使用虚拟环境(virtualenv)搞定. virtualenv: Virtua ...
- cmd命令行进入DOS方式编译运行C语言程序实现字符串转换
需求:输入一个字符串(长度小于50),然后过滤掉所有的非数字字符,得到由数字字符组成的字符串,将其转化为double型结果输出(4位小数). 源程序: #include<stdio.h>i ...
- jQuery 去空
//去左右空格; function trim(s){ return s.replace(/(^\s*)|(\s*$)/g, ""); } //去掉字符串中所有空格(包括中间 ...
- CocoaPods的一些略为高级一丁点的使用【转】
记得我刚开始做iOS开发的时候,是没有项目依赖管理工具.当需要引入第三方库的时候是相当麻烦的,不是直接拷贝库近来,就是添加依赖工程,直到CocoaPods出来才改变这个状况.项目依赖管理不是Cocoa ...
- pickle和json模块
json模块 json模块是实现序列化和反序列化的,主要用户不同程序之间的数据交换,首先来看一下: dumps()序列化 import json '''json模块是实现序列化和反序列话功能的''' ...