1!address
!address 扩展显示目标进程或目标机使用的内存信息。
这个学习起来比较简单:我们直接使用!address -?就可以找到它的使用说明:
给个例子:
0:001> !address -? !address - prints information on the entire address space !address -? - prints this help !address <address> - prints available information about the region of the address space containing this address !address -summary - prints only summary information !address -RegionUsageXXX - fiters the output limiting the dispaly to one of the following types: RegionUsageIsVAD - `busy` region that could be charcterized better this includes Virtual-Alloc-ed blocks, SBH heap, memory from custom allocators, etc RegionUsageFree - availalble (neither committed nor reserved) region RegionUsageImage - region used by mapped images of binaries RegionUsageStack - stack of threads RegionUsageTeb - TEB of threads RegionUsageHeap - region in used by a heap RegionUsagePageHeap - region in use by full page-heap RegionUsagePeb - PEB of the process RegionUsageProcessParametrs - parameters of the process RegionUsageEnvironmentBlock - environment block
那么一个个说明吧:
!address显示整个地址空间和使用摘要的信息
这个太长了,它会把从0-7ffefff的全打印出来,熟悉核心编程的应该知道,正常的2G用户地址空间是这样划分的:0-ffff为64K空指针区,1000-7ffeffff为用户模式分区
之后64K为禁入分区,之后就是内核模式分区,要看它们的信息,需要用到以下的表,
Filter 值 | 显示的内存区域 |
---|---|
RegionUsageIsVAD | "busy" 区域。包括所有 虚拟分配块、SBH堆、自定义内存分配器(custom allocators)的内存、以及地址空间中所有属于其他分类的内存块。 |
RegionUsageFree | 目标的虚拟地址空间中所有可用内存。包括所有非提交(committed)和非保留(reserved)的内存。 |
RegionUsageImage | 用来映射二进制映像的内存区域。 |
RegionUsageStack | 用作目标进程的线程的堆栈的内存区域。 |
RegionUsageTeb | 用作目标进程中所有线程的线程环境块(TEB)的内存区域。 |
RegionUsageHeap | 用作目标进程的堆的内存区域。 |
RegionUsagePageHeap | 用作目标进程的整页堆(full-page heap)的内存区域。 |
RegionUsagePeb | 目标进程的进程环境块(PEB)的内存区域。 |
RegionUsageProcessParametrs | 用作目标进程启动参数的内存区域。 |
RegionUsageEnvironmentBlock | 用作目标进程的环境块的内存区域。 |
下面这些Filter值按照内存类型来指定内存。
Filter 值 | 显示的内存类型 |
---|---|
MEM_IMAGE | 映射的文件属于可执行映像一部分的内存。 |
MEM_MAPPED | 映射的文件不属于可执行映像一部分的内存。这种内存包含哪些从页面文件映射的内存。 |
MEM_PRIVATE | 私有的(即不和其他进程共享)并且未用来映射任何文件的内存。 |
下面的Filter 值按照状态来指定内存:
Filter 值 | 显示的内存状态 |
---|---|
MEM_COMMIT | 当前已提交给目标使用的所有内存。已经在物理内存或者页面文件中为这些内存分配了物理的存储空间。 |
MEM_RESERVE | 所有为目标以后的使用保留的内存。这种内存还没有分配物理上的存储空间。 |
MEM_FREE | 目标虚拟地址空间中所有可用内存。包括所有未提交并且未保留的内存。该Filter 值和RegionUsageFree一样。 |
我们取一部分来看吧:
7ffe0000 : 7ffe0000 - 00001000 Type 00020000 MEM_PRIVATE Protect 00000002 PAGE_READONLY State 00001000 MEM_COMMIT Usage RegionUsageIsVAD 7ffe1000 - 0000f000 Type 00020000 MEM_PRIVATE Protect 00000001 PAGE_NOACCESS State 00002000 MEM_RESERVE Usage RegionUsageIsVAD -------------------- Usage SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Pct(Busy) Usage 84f000 ( 8508) : 00.41% 24.79% : RegionUsageIsVAD 7de6c000 ( 2062768) : 98.36% 00.00% : RegionUsageFree 15e0000 ( 22400) : 01.07% 65.27% : RegionUsageImage 50000 ( 320) : 00.02% 00.93% : RegionUsageStack 2000 ( 8) : 00.00% 00.02% : RegionUsageTeb 300000 ( 3072) : 00.15% 08.95% : RegionUsageHeap 0 ( 0) : 00.00% 00.00% : RegionUsagePageHeap 1000 ( 4) : 00.00% 00.01% : RegionUsagePeb 1000 ( 4) : 00.00% 00.01% : RegionUsageProcessParametrs 1000 ( 4) : 00.00% 00.01% : RegionUsageEnvironmentBlock Tot: 7fff0000 (2097088 KB) Busy: 02184000 (34320 KB) -------------------- Type SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Usage 7de6c000 ( 2062768) : 98.36% : <free> 15e0000 ( 22400) : 01.07% : MEM_IMAGE 7cd000 ( 7988) : 00.38% : MEM_MAPPED 3d7000 ( 3932) : 00.19% : MEM_PRIVATE -------------------- State SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Usage 19eb000 ( 26540) : 01.27% : MEM_COMMIT 7de6c000 ( 2062768) : 98.36% : MEM_FREE 799000 ( 7780) : 00.37% : MEM_RESERVE Largest free region: Base 100b0000 - Size 48f00000 (1195008 KB)
7ffe0000 - 00001000是私有的(即不和其他进程共享)并且未用来映射任何文件的内存,只读的,已分配物理内存空间的
,.......
-summary 仅显示摘要信息。0:001> !address -summary -------------------- Usage SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Pct(Busy) Usage 84f000 ( 8508) : 00.41% 24.79% : RegionUsageIsVAD 7de6c000 ( 2062768) : 98.36% 00.00% : RegionUsageFree 15e0000 ( 22400) : 01.07% 65.27% : RegionUsageImage 50000 ( 320) : 00.02% 00.93% : RegionUsageStack 2000 ( 8) : 00.00% 00.02% : RegionUsageTeb 300000 ( 3072) : 00.15% 08.95% : RegionUsageHeap 0 ( 0) : 00.00% 00.00% : RegionUsagePageHeap 1000 ( 4) : 00.00% 00.01% : RegionUsagePeb 1000 ( 4) : 00.00% 00.01% : RegionUsageProcessParametrs 1000 ( 4) : 00.00% 00.01% : RegionUsageEnvironmentBlock Tot: 7fff0000 (2097088 KB) Busy: 02184000 (34320 KB) -------------------- Type SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Usage 7de6c000 ( 2062768) : 98.36% : <free> 15e0000 ( 22400) : 01.07% : MEM_IMAGE 7cd000 ( 7988) : 00.38% : MEM_MAPPED 3d7000 ( 3932) : 00.19% : MEM_PRIVATE -------------------- State SUMMARY -------------------------- TotSize ( KB) Pct(Tots) Usage 19eb000 ( 26540) : 01.27% : MEM_COMMIT 7de6c000 ( 2062768) : 98.36% : MEM_FREE 799000 ( 7780) : 00.37% : MEM_RESERVE Largest free region: Base 100b0000 - Size 48f00000 (1195008 KB)
0:001> !address -RegionUsageFree 00000000 : 00000000 - 00010000 Type 00000000 Protect 00000001 PAGE_NOACCESS State 00010000 MEM_FREE Usage RegionUsageFree 00011000 : 00011000 - 0000f000 Type 00000000 Protect 00000001 PAGE_NOACCESS State 00010000 MEM_FREE Usage RegionUsageFree 00021000 : 00021000 - 0000f000 Type 00000000 ..............................
上面是只打印了目标的虚拟地址空间中所有可用内存
这个命令可以把一个表示栈的地址和一个表示堆的内存块地址区分开来:
0:000> !address 0a690005 0a690000 : 0a690000 - 00006000 Type 00020000 MEM_PRIVATE Protect 00000004 PAGE_READWRITE State 00001000 MEM_COMMIT Usage RegionUsageHeap Handle 01be0000
2。s
s 命令搜索内存查找指定模板
S 命令可以搜索内存。一般来说,用在下面的地方:
1. 寻找内存泄露的线索。比如知道当前内存泄漏的内容是一些固定的字符串,就可以在
DLL 区域搜索这些字符串出现的地址,然后再搜索这些地址用到什么代码中,找出这些
内存是在什么地方开始分配的。
2. 寻找错误代码的根源。比如知道当前程序返回了 0x80074015 这样的一个代码,但是不
知道这个代码是由哪一个内层函数返回的。就可以在代码区搜索 0x80074015,找到可能
返回这个代码的函数。
s-sa 和s-su 命令搜索未指定的ASCII和Unicode字符串。这在检查某段内存是否包含可打印字符时有用。
s-a 和s-u 命令分别用来搜索指定的ASCII和Unicode字符串。这些字符串不一定要null结尾
我们来测试下这些命令吧:
s-sa 和s-su不需要指定字符串,比如我想查下42200后L100中有什么Ascii字符:
0:002> s -sa 422000 L100 00422000 "-GUOYOU-HUANG" 0042200e "ComSpec=C:\WINDOWS\system32\cmd." 0042202e "exe" 00422032 "FP_NO_HOST_CHECK=NO" 00422046 "HOMEDRIVE=C:" 00422053 "HOMEPATH=\Documents and Settings" 00422073 "\guoyou.huang" 00422081 "LOGONSERVER=\\SZDC01" 00422096 "NUMBER_OF_PROCESSORS=4" 004220ad "OS=Windows_NT"
查下42200后L100中有什么Unicode字符:
0:002> s -su 422000 L100 00422000 "䜭何余" 00422008 "啈乁G潃卭数㵣㩃坜义佄南獜獹整" 0042202e "硥e偆也彏佈呓䍟䕈䭃丽O佈䕍剄噉㵅㩃䠀䵏偅呁㵈䑜捯浵湥獴愠摮匠瑥" 0042206e "楴杮屳畧祯畯栮慵杮䰀䝏乏䕓噒剅尽卜䑚ぃ1啎䉍剅佟彆剐䍏卅体卒㐽伀" 004220ae "㵓楗摮睯彳呎倀瑡㵨㩃坜义佄南獜獹整" 004220d2 "㬲㩃坜义佄南䌻尺䥗䑎坏屓祓瑳浥" 004220f2 "坜敢㭭㩃坜义佄南獜獹整" 0042210a "尲楗摮睯偳睯牥桓汥屬ㅶ" 00422122 "䌻尺牐杯慲" 0042212e "楆敬屳楍牣獯景" 0042213e "兓⁌敓癲牥㥜尰潔汯屳楢湮㭜㩃停潲牧浡䘠汩獥䥜䵄䌠浯異整" 00422176 "潓畬楴湯屳汕牴䕡楤" 0042218c "䌻尺牐杯慲" 00422198 "楆敬屳潃浭湯䘠汩獥䅜潤敢䅜䱇䐻尺牐杯慲" 004221c0 "楆敬屳慒楴湯污䍜敬牡慃敳扜湩䐻尺牐杯慲"
有时,我们可能只想查找长度大于4的字符串,那么可以用-[l4]sa来替换-sa,如下:
0:004> s -sa 00c60000 L100 00c6004d "!This program cannot be run in D" 00c6006d "OS mode." 00c60090 "Ej]" 00c600a0 "Ej[" 00c600a8 "EjK" 00c600b0 "EjL" 00c600b8 "Ej\" 00c600c0 "EjY" 00c600c8 "RichL" 0:004> s -[l4]sa 00c60000 L100 00c6004d "!This program cannot be run in D" 00c6006d "OS mode." 00c600c8 "RichL"
OK,我们来测试下s-a 和s-u
0:002> s -a 422000 L100 "exe" 0042202e 65 78 65 00 46 50 5f 4e-4f 5f 48 4f 53 54 5f 43 exe.FP_NO_HOST_C
0:002> s -u 422000 L100 "啈乁G潃卭" 00422008 5548 4e41 0047 6f43 536d 6570 3d63 3a43 HUANG.ComSpec=C:
和前面的比较,我们可以发现,这两个命令是在某一个范围内查询Ascii码和Unicode码
好吧,前面的肯定都掌握了,下面来说下地址范围吧,一般地址范围有如下几种写法:
一对地址:我们可以这样写:
0:002> s -a 422000 422100 "exe" 0042202e 65 78 65 00 46 50 5f 4e-4f 5f 48 4f 53 54 5f 43 exe.FP_NO_HOST_C
LSize第二种形式包括一个地址参数,字母 L(大小写都行)和一个数值参数。地址指定起始地址;数值指定要检查或显示的对象的数目
上面的例子用的都是这种形式,不多举例了
L?Size (带一个问号)和LSize 意思相同,但是它会去掉调试器的自动范围限制。其他的表示法都有一个 256 MB 的范围限制,因为更大的范围经常打印出错。如果你实际上想要指定一个比 256 MB 大的范围,需要使用L?Size语法。
0:002> s -a 422000 L?100 "exe" 0042202e 65 78 65 00 46 50 5f 4e-4f 5f 48 4f 53 54 5f 43 exe.FP_NO_HOST_C
我个人推荐这种写法,因为这样就可以不受范围限制
L-Size(带一个连字号)指定一个长度为 Size 到给定地址结束的范围。例如,80000000 L20 表示 0x80000000 到 0x8000001F,而 80000000 L-20 表示 0x7FFFFFE0 到 0x7FFFFFFF。
0:002> s -a 422100 L-100 "exe" 0042202e 65 78 65 00 46 50 5f 4e-4f 5f 48 4f 53 54 5f 43 exe.FP_NO_HOST_C
注意,-a后接的是422100而不是422000,
!vadump
这个会显示所有的虚拟内存区域和它的保护属性
0:000> !vadump BaseAddress: 00000000 RegionSize: 00010000 State: 00010000 MEM_FREE Protect: 00000001 PAGE_NOACCESS BaseAddress: 00010000 RegionSize: 00010000 State: 00001000 MEM_COMMIT Protect: 00000004 PAGE_READWRITE Type: 00040000 MEM_MAPPED BaseAddress: 00020000 RegionSize: 00010000 State: 00010000 MEM_FREE Protect: 00000001 PAGE_NOACCESS