原文中作者是从堆里面寻找丢失的博客文章,在这里我模拟的环境是从gvim编辑器里面寻找一段文字的地址
强大的!address命令
!address -summary
可以显示进程空间中内存使用情况的摘要
0:003> !address -summary
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...
--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free 102 7fff`f37ff000 ( 128.000 TB) 100.00%
Image 399 0`04b2e000 ( 75.180 MB) 37.60% 0.00%
MappedFile 27 0`02e13000 ( 46.074 MB) 23.04% 0.00%
Stack 12 0`02000000 ( 32.000 MB) 16.00% 0.00%
<unknown> 49 0`01830000 ( 24.188 MB) 12.10% 0.00%
Heap 51 0`0149d000 ( 20.613 MB) 10.31% 0.00%
Other 7 0`001d8000 ( 1.844 MB) 0.92% 0.00%
TEB 4 0`0000a000 ( 40.000 kB) 0.02% 0.00%
PEB 1 0`00001000 ( 4.000 kB) 0.00% 0.00%
--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE 117 0`04cc9000 ( 76.785 MB) 38.40% 0.00%
MEM_IMAGE 399 0`04b2e000 ( 75.180 MB) 37.60% 0.00%
MEM_MAPPED 34 0`02ffa000 ( 47.977 MB) 24.00% 0.00%
--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE 102 7fff`f37ff000 ( 128.000 TB) 100.00%
MEM_COMMIT 512 0`07862000 ( 120.383 MB) 60.21% 0.00%
MEM_RESERVE 38 0`04f8f000 ( 79.559 MB) 39.79% 0.00%
--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READONLY 218 0`03ff2000 ( 63.945 MB) 31.98% 0.00%
PAGE_EXECUTE_READ 62 0`0248d000 ( 36.551 MB) 18.28% 0.00%
PAGE_READWRITE 167 0`0130e000 ( 19.055 MB) 9.53% 0.00%
PAGE_WRITECOPY 47 0`000b8000 ( 736.000 kB) 0.36% 0.00%
PAGE_READWRITE|PAGE_GUARD 5 0`0000f000 ( 60.000 kB) 0.03% 0.00%
PAGE_NOACCESS 12 0`0000c000 ( 48.000 kB) 0.02% 0.00%
PAGE_EXECUTE 1 0`00002000 ( 8.000 kB) 0.00% 0.00%
--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free 0`7fff0000 7ff6`48020000 ( 127.962 TB)
Image 7ff9`4a4a1000 0`00e46000 ( 14.273 MB)
MappedFile 0`02f4d000 0`011e3000 ( 17.887 MB)
Stack 0`04470000 0`007fb000 ( 7.980 MB)
<unknown> 0`08341000 0`007ff000 ( 7.996 MB)
Heap 0`08e0b000 0`00534000 ( 5.203 MB)
Other 0`02ba0000 0`00181000 ( 1.504 MB)
TEB 0`0040a000 0`00004000 ( 16.000 kB)
PEB 0`005f8000 0`00001000 ( 4.000 kB)
几个字段的说明:
- Total Size ------ 总的内存大小
- %ofBusy --------- 在已经使用了的内存中所占的百分比
- %ofTotal -------- 在可用的内存地址中所占的百分比(因为是使用的64位系统,理论上可以寻址的范围大小是2^64,所使用的内存远远不及这个数字,所以这个字段大部分都是0.00%)
Usage Summary指的是内存不同用途的使用情况:
- Free ----------- 空闲内存
- Image ---------- 可执行文件映像所占的内存
- MappedFile ----- 已经映射的文件所占的内存
- Stack ---------- 栈空间所占用的内存
- unknown -------- 顾名思义,未知的
- Heap ----------- 堆
- Other ---------- 其它
- TEB ------------ 线程环境块
- PEB ------------ 进程环境块
Type Summary指的是不同类型的内存的使用情况:
- MEM_PRIVATE ---- 进程私有的内存(堆栈占大部分)
- MEM_IMAGE ------ 可执行文件映像(程序文件、动态库等等)所占的,一般为多个进程共享
- MEM_MAPPED ----- 内存映射文件
State Summary指的是不同状态的内存的使用情况:
- MEM_FREE ------- 空闲
- MEM_COMMIT ----- 已提交(虚拟地址已经被物理地址映射)的内存
- MEM_RESERVE ---- 保留(该段虚拟内存地址为被分配到物理内存,但是保留起来不再分配给别人)
Protect Summary指的是不同的内存保护属性的内存的使用情况:
- PAGE_READONLY --------- 只读
- PAGE_EXECUTE_READ ----- 可读可执行
- PAGE_READWRITE -------- 可读写
- PAGE_WRITECOPY -------- 写时复制
- PAGE_READWRITE|PAGE_GUARD
- PAGE_NOACCESS --------- 不可访问
- PAGE_EXECUTE ---------- 可执行
缩小搜索范围
可以看出已经使用的堆空间占用了20.613MB,从这么多的内存中找到所需要的数据不是一件轻松的事情
我们可以使用!address -f:Heap
命令过滤出堆内存的地址分布
0:003> !address -f:Heap
BaseAddress EndAddress+1 RegionSize Type State Protect Usage
--------------------------------------------------------------------------------------------------------------------------
0`00250000 0`00260000 0`00010000 MEM_MAPPED MEM_COMMIT PAGE_READWRITE Heap [ID: 1; Handle: 0000000000250000; Type: Segment]
0`00390000 0`00393000 0`00003000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Front End]
0`00393000 0`003aa000 0`00017000 MEM_PRIVATE MEM_RESERVE Heap [ID: 0; Handle: 0000000000f00000; Type: Front End]
0`003b0000 0`003b2000 0`00002000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 2; Handle: 0000000002980000; Type: Front End]
0`003b2000 0`003ca000 0`00018000 MEM_PRIVATE MEM_RESERVE Heap [ID: 2; Handle: 0000000002980000; Type: Front End]
0`00e00000 0`00e05000 0`00005000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Front End]
0`00e05000 0`00e1a000 0`00015000 MEM_PRIVATE MEM_RESERVE Heap [ID: 3; Handle: 0000000002900000; Type: Front End]
0`00e80000 0`00e89000 0`00009000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 4; Handle: 0000000000e80000; Type: Segment]
0`00e89000 0`00e8f000 0`00006000 MEM_PRIVATE MEM_RESERVE Heap [ID: 4; Handle: 0000000000e80000; Type: Segment]
0`00f00000 0`00fff000 0`000ff000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`02800000 0`028ff000 0`000ff000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`02900000 0`0290f000 0`0000f000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`02980000 0`0298f000 0`0000f000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 2; Handle: 0000000002980000; Type: Segment]
0`05c70000 0`05cab000 0`0003b000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 2; Handle: 0000000002980000; Type: Segment]
0`05cab000 0`05d6f000 0`000c4000 MEM_PRIVATE MEM_RESERVE Heap [ID: 2; Handle: 0000000002980000; Type: Segment]
0`05e30000 0`05ffb000 0`001cb000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`05ffb000 0`05ffc000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`05ffc000 0`0602f000 0`00033000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06030000 0`06074000 0`00044000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06074000 0`06075000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06075000 0`06125000 0`000b0000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06125000 0`06126000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06126000 0`06131000 0`0000b000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06131000 0`06132000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06132000 0`06218000 0`000e6000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06218000 0`06219000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06219000 0`06230000 0`00017000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06230000 0`06231000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06231000 0`0624e000 0`0001d000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`0624e000 0`0624f000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`0624f000 0`063f4000 0`001a5000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`063f4000 0`063f5000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`063f5000 0`0640f000 0`0001a000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`0640f000 0`06410000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06410000 0`0641a000 0`0000a000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`0641a000 0`0642f000 0`00015000 MEM_PRIVATE MEM_RESERVE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06670000 0`06706000 0`00096000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`06706000 0`06707000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`06707000 0`0676f000 0`00068000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`068f0000 0`06a26000 0`00136000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`06a26000 0`06aef000 0`000c9000 MEM_PRIVATE MEM_RESERVE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`06c70000 0`06c71000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 4; Handle: 0000000000e80000; Type: Front End]
0`06c71000 0`06c8a000 0`00019000 MEM_PRIVATE MEM_RESERVE Heap [ID: 4; Handle: 0000000000e80000; Type: Front End]
0`08b40000 0`08b81000 0`00041000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08b81000 0`08b82000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08b82000 0`08b8e000 0`0000c000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08b8e000 0`08b8f000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_NOACCESS Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08b8f000 0`08d22000 0`00193000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08d22000 0`08dcd000 0`000ab000 MEM_PRIVATE MEM_RESERVE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08dcd000 0`08e0b000 0`0003e000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08e0b000 0`0933f000 0`00534000 MEM_PRIVATE MEM_RESERVE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
数量有点大呀!不过考虑到编辑器buffer中的数据肯定已经被存储到物理内存中,所以其所在的地址属性应该是MEM_COMMIT,而且其保护属性应该是可读写的,即PAGE_READWRITE,使用!address -f:Heap,MEM_COMMIT,PAGE_READWRITE
再过滤一下
0:003> !address -f:Heap,MEM_COMMIT,PAGE_READWRITE
BaseAddress EndAddress+1 RegionSize Type State Protect Usage
--------------------------------------------------------------------------------------------------------------------------
0`00250000 0`00260000 0`00010000 MEM_MAPPED MEM_COMMIT PAGE_READWRITE Heap [ID: 1; Handle: 0000000000250000; Type: Segment]
0`00390000 0`00393000 0`00003000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Front End]
0`003b0000 0`003b2000 0`00002000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 2; Handle: 0000000002980000; Type: Front End]
0`00e00000 0`00e05000 0`00005000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Front End]
0`00e80000 0`00e89000 0`00009000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 4; Handle: 0000000000e80000; Type: Segment]
0`00f00000 0`00fff000 0`000ff000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`02800000 0`028ff000 0`000ff000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`02900000 0`0290f000 0`0000f000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`02980000 0`0298f000 0`0000f000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 2; Handle: 0000000002980000; Type: Segment]
0`05c70000 0`05cab000 0`0003b000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 2; Handle: 0000000002980000; Type: Segment]
0`05e30000 0`05ffb000 0`001cb000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`05ffc000 0`0602f000 0`00033000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06030000 0`06074000 0`00044000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06075000 0`06125000 0`000b0000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06126000 0`06131000 0`0000b000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06132000 0`06218000 0`000e6000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06219000 0`06230000 0`00017000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06231000 0`0624e000 0`0001d000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`0624f000 0`063f4000 0`001a5000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`063f5000 0`0640f000 0`0001a000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06410000 0`0641a000 0`0000a000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`06670000 0`06706000 0`00096000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`06707000 0`0676f000 0`00068000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`068f0000 0`06a26000 0`00136000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 0; Handle: 0000000000f00000; Type: Segment]
0`06c70000 0`06c71000 0`00001000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 4; Handle: 0000000000e80000; Type: Front End]
0`08b40000 0`08b81000 0`00041000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08b82000 0`08b8e000 0`0000c000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08b8f000 0`08d22000 0`00193000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
0`08dcd000 0`08e0b000 0`0003e000 MEM_PRIVATE MEM_COMMIT PAGE_READWRITE Heap [ID: 3; Handle: 0000000002900000; Type: Segment]
这下需要搜索的地址就小了,我们可以从00250000到08e0b000搜索关键字
使用搜索命令
搜索命令为s -[au] <Range> "<String>"
,-a搜索ASCII数据,-u搜索Unicode数据,注意在windbg中输入的中文是gbk编码的数据
Range有两种表示方法,一种是起始地址 结束地址
,另一种是起始地址 L地址长度
,比如s -a 00001000 00002000 "abc"
和s -a 00001000 L1000 "abc"
是等价的
保存内存中的数据到文件中
.writemem d:\blog.txt 07288600 L2000