博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

windbg 内存

Posted on 2023-12-13 15:21  linFen  阅读(16)  评论(0编辑  收藏  举报

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)
Filter 只显示指定的区域。Filter 的值不区分大小写
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"
注意的是l4是要用中括号括起来的

 

 

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