应用层内存管理及调试的学习-----(1)

艰难的起步(No symbols for ntdll. Cannot continue.)

之前在公司win7 电脑上调试内存泄漏信息,用了其中的一个命令!address 查看进程地址空间的大概的分布状态。在自己的电脑上简单的使用!address 命令的时候发现如下错误:


Microsoft (R) Windows Debugger Version 10.0.18362.1 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: F:\program\MemoryList\Release\ExeTestDllHeapTest.exe

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*c:\symbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\symbols*https://msdl.microsoft.com/download/symbols
Executable search path is: 
ModLoad: 00660000 00697000   ExeTestDllHeapTest.exe
ModLoad: 77090000 7722a000   ntdll.dll
ModLoad: 75500000 755e0000   C:\WINDOWS\SysWOW64\KERNEL32.DLL
ModLoad: 750d0000 752cc000   C:\WINDOWS\SysWOW64\KERNELBASE.dll
(688.13bc): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=002bc000 ecx=8aab0000 edx=00000000 esi=009a1ed8 edi=7709688c
eip=7713e9d2 esp=0056f948 ebp=0056f974 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!LdrpDoDebuggerBreak+0x2b:
7713e9d2 cc              int     3
0:000> !address

No symbols for ntdll. Cannot continue.

注意到输入!addrses 之后的提示:No symbols for ntdll. Cannot continue
无脑的参考之间的经验,删除了ntdll.dll 的有关符号,并重新加载,发现并没有解决问题,之后搜索引擎 ,发现并相关的方法可以没有解决自己的问题。

解决之路:

细节决定成败吧,windbg 提示我们没有ntdll 的符号,而我们看windbg 的启动信息,发现它显然是有一个ntdll.dll 的符号的,之后我们用process hacker 查看初始状态时一个进程的模块加载信息:
在这里插入图片描述
我们发现这里加载了很多符号,而windbg 只是列出了一部分,wow 相关的模块一个都没有,而我通常习惯于启动32位windbg 调试32位exe,这可能是一个问题的原因,wow 相关,后来尝试用64bit 的windbg 启动并调试32位的exe 时,可以正常的使用!address 命令了。这可能是windbg 的问题,因为我在工作机器win7上,32-bit windbg.exe 调试32-bit exe ,查看其模块信息是没有问题的,但这不是我们学习的重点,有机会可以继续探索一下

进程初始时的地址空间信息的查看


Response                         Time (ms)     Location
Deferred                                       srv*c:\symbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\symbols*https://msdl.microsoft.com/download/symbols
Executable search path is: 
ModLoad: 00000000`00660000 00000000`00697000   ExeTestDllHeapTest.exe
ModLoad: 00007ffc`65ee0000 00007ffc`660d0000   ntdll.dll
ModLoad: 00000000`77090000 00000000`7722a000   ntdll.dll
ModLoad: 00007ffc`64eb0000 00007ffc`64f05000   C:\WINDOWS\System32\wow64.dll
ModLoad: 00007ffc`64b10000 00007ffc`64b8d000   C:\WINDOWS\System32\wow64win.dll
(3524.23cc): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffc`65fb11dc cc              int     3
0:000> !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                                     15        0`7fa62000 (   1.995 GB)           99.73%
<unknown>                                13        0`00314000 (   3.078 MB)  55.41%    0.15%
Image                                    13        0`001d1000 (   1.816 MB)  32.70%    0.09%
Other                                     5        0`00054000 ( 336.000 kB)   5.91%    0.02%
Stack64                                   3        0`00040000 ( 256.000 kB)   4.50%    0.01%
Heap64                                    2        0`0000f000 (  60.000 kB)   1.05%    0.00%
TEB64                                     1        0`00003000 (  12.000 kB)   0.21%    0.00%
PEB64                                     1        0`00002000 (   8.000 kB)   0.14%    0.00%
MappedFile                                1        0`00001000 (   4.000 kB)   0.07%    0.00%

--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE                              21        0`00369000 (   3.410 MB)  61.39%    0.17%
MEM_IMAGE                                13        0`001d1000 (   1.816 MB)  32.70%    0.09%
MEM_MAPPED                                5        0`00054000 ( 336.000 kB)   5.91%    0.02%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE                                 15        0`7fa62000 (   1.995 GB)           99.73%
MEM_RESERVE                               8        0`0034a000 (   3.289 MB)  59.21%    0.16%
MEM_COMMIT                               31        0`00244000 (   2.266 MB)  40.79%    0.11%

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_EXECUTE_READ                         2        0`0013b000 (   1.230 MB)  22.15%    0.06%
PAGE_READONLY                            12        0`000e1000 ( 900.000 kB)  15.82%    0.04%
PAGE_READWRITE                           11        0`0001a000 ( 104.000 kB)   1.83%    0.00%
PAGE_WRITECOPY                            4        0`00009000 (  36.000 kB)   0.63%    0.00%
PAGE_READWRITE|PAGE_GUARD                 2        0`00005000 (  20.000 kB)   0.35%    0.00%

--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free                                      0`01580000        0`75b10000 (   1.839 GB)
<unknown>                                 0`0109a000        0`00166000 (   1.398 MB)
Image                                     0`77091000        0`0011a000 (   1.102 MB)
Other                                     0`7f550000        0`00033000 ( 204.000 kB)
Stack64                                   0`01220000        0`00035000 ( 212.000 kB)
Heap64                                    0`01574000        0`0000b000 (  44.000 kB)
TEB64                                     0`01097000        0`00003000 (  12.000 kB)
PEB64                                     0`01095000        0`00002000 (   8.000 kB)
MappedFile                                0`7f540000        0`00001000 (   4.000 kB)

使用winddbg 加载exe 之后第一次查看调试信息会发现上面的地址空间分布,由于我们猜测进程模块会有进程模块堆的构建,这里只看到了64-bit 的堆,有点难以理解。

定制的dll 和 exe ,用于研究dll 模块的堆的使用和释放

  • exe

int main()
{
	printf("print to alloc local memory\n");
	getchar();
	char* pszLocal = (char*)malloc(0x2000);
	strcpy_s(pszLocal, 0x2000, "hello local");

	printf("[%p]\t[%s]\n", pszLocal, pszLocal);

	printf("print to local free\n");
	getchar();

	free(pszLocal);
	pszLocal = NULL;
	
	typedef void(__stdcall * ptr_func)(void);
	HMODULE hDll = LoadLibrary(_T("DllHeapTest.dll"));
	printf("print to load library \n");
	getchar();
	ptr_func Func = (ptr_func)GetProcAddress(hDll, "AllocMemoryAndNoFree");
	
	printf("print to call alloc memory");
	getchar();
	Func();

	printf("before FreeLibrary click to free");
	getchar();

	FreeLibrary(hDll);


    std::cout << "after free memory!\n"; 
	getchar();
	system("pause");
  • dll

void __stdcall AllocMemoryAndNoFree()
{
	void* temp = malloc(0x1000);
	char flag[] = "hello world";
	memcpy_s(temp, 0x1000,flag, sizeof(flag));
	printf("[%p]\n", temp);
}

f5 键,查看进程的crt 执行之后再下断点,查看进程的地址信息


0:000> g
ModLoad: 00000000`77080000 00000000`77089000   C:\WINDOWS\System32\wow64cpu.dll
ModLoad: 00000000`75500000 00000000`755e0000   C:\WINDOWS\SysWOW64\KERNEL32.DLL
ModLoad: 00000000`750d0000 00000000`752cc000   C:\WINDOWS\SysWOW64\KERNELBASE.dll
(3524.23cc): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll_77090000!LdrpDoDebuggerBreak+0x2b:
7713e9d2 cc              int     3

我们之后f5 键,发现又有模块加载,并被断了下来,是之前在process hacker 中显示,却没有在windbg 中显示的模块。此时我们再次尝试使用!address 命令,看看有没有我们想要的进程默认堆结构

0:000:x86> !address -summary

No symbols for ntdll. Cannot continue.

再次出现了这个可怕的指令,可怕,但由于之前我们是有机会能使用!address 命令的,这里猜测是wow64系统上,刚开始的初始化是初始化了一个64-bit 进程 ,并被windbg 断了下来,此时被断,进程已经被转换成了wow64 模式,平时也经常遇见这种wow 无法正常调试的状况,需要使用转换命令,将环境转换为32-bit 环境,再继续调试

0:000:x86> .load wow64exts
0:000:x86> !address -summary

No symbols for ntdll. Cannot continue.
0:000:x86> !sw
Switched to Host mode
0:000> !address -summary

注意上面的操作,连续执行 .load wow64exts !sm才可以转换过来,还是要熟悉这个 操作
。。。。等等,和上面刚开始的地址空间来说,是有区别的,但不是我们此次关注的重点,暂时忽略

经历了这里的环境转换,恍然大悟,是不是32-bit windbg.exe在 win10 上,调试32-bit .exe 的时候,也需要 转换wow 环境的?-------反人类的是,我们已经用32-bit windbg.exe调试 32-bit 程序了,为啥还需要这一个转换的步骤,验证之后发现无法通过类似办法转换模式解决!address 指令执行失败的问题,老老实实用64-bit windbg.exe 转换模式后调试 wow64 进程

继续我们的程序,此次f5 之后,应该走完了进程crt 的初始化,然后我们再下断点一定可以得到一个相关熟悉的进程的地址空间

0:001> !address -summary

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Free                                     23        0`7f35d000 (   1.988 GB)           99.39%
<unknown>                                21        0`0051a000 (   5.102 MB)  40.57%    0.25%
Image                                    33        0`004b6000 (   4.711 MB)  37.47%    0.23%
MappedFile                                3        0`001c3000 (   1.762 MB)  14.01%    0.09%
Stack64                                   6        0`00080000 ( 512.000 kB)   3.98%    0.02%
Other                                     6        0`00059000 ( 356.000 kB)   2.76%    0.02%
Heap64                                    3        0`0001f000 ( 124.000 kB)   0.96%    0.01%
TEB64                                     2        0`00006000 (  24.000 kB)   0.19%    0.00%
PEB64                                     1        0`00002000 (   8.000 kB)   0.06%    0.00%

--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE                              33        0`005b2000 (   5.695 MB)  45.29%    0.28%
MEM_IMAGE                                33        0`004b6000 (   4.711 MB)  37.47%    0.23%
MEM_MAPPED                                9        0`0022b000 (   2.168 MB)  17.24%    0.11%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_FREE                                 23        0`7f35d000 (   1.988 GB)           99.39%
MEM_RESERVE                              20        0`006b2000 (   6.695 MB)  53.25%    0.33%
MEM_COMMIT                               55        0`005e1000 (   5.879 MB)  46.75%    0.29%

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_EXECUTE_READ                         6        0`00365000 (   3.395 MB)  27.00%    0.17%
PAGE_READONLY                            24        0`0021b000 (   2.105 MB)  16.74%    0.10%
PAGE_READWRITE                           20        0`00056000 ( 344.000 kB)   2.67%    0.02%
PAGE_READWRITE|PAGE_GUARD                 4        0`0000a000 (  40.000 kB)   0.31%    0.00%
PAGE_WRITECOPY                            1        0`00001000 (   4.000 kB)   0.03%    0.00%

--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Free                                      0`01850000        0`73880000 (   1.805 GB)
<unknown>                                 0`0109d000        0`00163000 (   1.387 MB)
Image                                     0`750d1000        0`001c3000 (   1.762 MB)
MappedFile                                0`7f3f5000        0`000fb000 (1004.000 kB)
Stack64                                   0`01220000        0`00035000 ( 212.000 kB)
Other                                     0`7f550000        0`00033000 ( 204.000 kB)
Heap64                                    0`00fc0000        0`00010000 (  64.000 kB)
TEB64                                     0`01097000        0`00003000 (  12.000 kB)
PEB64                                     0`01095000        0`00002000 (   8.000 kB)

发现了地址空间的heap 还是用heap64标识的时候,我已经知道了自己的假设错误了,64-bit上,或者说64-bit windbg中标识heap 的方法,应该就是heap64吧,此时我们观察heap结构不太合理,因为之前没有观察初始的时候的heap 的结构

从头开始,对比heap 进程crt 初始化前后,heap的状态:

00007ffc`65fb11dc cc              int     3
0:000> !heap -p -all
    _HEAP @ b80000
      No FrontEnd
      _HEAP_SEGMENT @ b80000
       CommittedRange @ b80740
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
      * 0000000000b80740 0013 0000  [00]   0000000000b80750    0012f - (busy)
        0000000000b80870 0013 0013  [00]   0000000000b80880    00100 - (busy)
        0000000000b809a0 0021 0013  [00]   0000000000b809b0    001d8 - (busy)
        0000000000b80bb0 0021 0021  [00]   0000000000b80bc0    001d8 - (busy)
        0000000000b80dc0 0008 0021  [00]   0000000000b80dd0    00048 - (busy)
        0000000000b80e40 0004 0008  [00]   0000000000b80e50    00004 - (busy)
        0000000000b80e80 0004 0004  [00]   0000000000b80e90    00010 - (busy)
        0000000000b80ec0 0013 0004  [00]   0000000000b80ed0    00100 - (busy)
        0000000000b80ff0 0013 0013  [00]   0000000000b81000    00100 - (busy)
        0000000000b81120 0133 0013  [00]   0000000000b81130    012f2 - (busy)
          unknown!printable
        0000000000b82450 007e 0133  [00]   0000000000b82460    007a8 - (busy)
        0000000000b82c30 0007 007e  [00]   0000000000b82c40    0003c - (busy)
          unknown!noop
        0000000000b82ca0 0006 0007  [00]   0000000000b82cb0    00030 - (busy)
          unknown!noop
        0000000000b82d00 000a 0006  [00]   0000000000b82d10    00062 - (busy)
          unknown!noop
        0000000000b82da0 0015 000a  [00]   0000000000b82db0    00120 - (busy)
        0000000000b82ef0 0008 0015  [00]   0000000000b82f00    00050 - (busy)
        0000000000b82f70 0015 0008  [00]   0000000000b82f80    00120 - (busy)
        0000000000b830c0 0008 0015  [00]   0000000000b830d0    00050 - (busy)
        0000000000b83140 0027 0008  [00]   0000000000b83150    00238 - (busy)
        0000000000b833b0 0013 0027  [00]   0000000000b833c0    00120 - (free)
        0000000000b834e0 0015 0013  [00]   0000000000b834f0    00120 - (busy)
        0000000000b83630 0008 0015  [00]   0000000000b83640    00050 - (busy)
          unknown!noop
        0000000000b836b0 0007 0008  [00]   0000000000b836c0    0003c - (busy)
          unknown!noop
        0000000000b83720 001a 0007  [00]   0000000000b83730    00190 - (free)
        0000000000b838c0 0015 001a  [00]   0000000000b838d0    00120 - (busy)
          ? ntdll!PebLdr+10
        0000000000b83a10 0008 0015  [00]   0000000000b83a20    00070 - (free)
        0000000000b83a90 0008 0008  [00]   0000000000b83aa0    00042 - (busy)
          unknown!noop
        0000000000b83b10 004b 0008  [00]   0000000000b83b20    004a0 - (free)
      * 0000000000b83fc0 0004 004b  [00]   0000000000b83fd0    00030 - (busy)
       VirtualAllocdBlocks @ b80110

第一次被断的情况 下两次如下:

0:000> g
ModLoad: 00000000`77080000 00000000`77089000   C:\WINDOWS\System32\wow64cpu.dll
ModLoad: 00000000`75500000 00000000`755e0000   C:\WINDOWS\SysWOW64\KERNEL32.DLL
ModLoad: 00000000`750d0000 00000000`752cc000   C:\WINDOWS\SysWOW64\KERNELBASE.dll
(3fc8.13e0): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll_77090000!LdrpDoDebuggerBreak+0x2b:
7713e9d2 cc              int     3
0:000:x86> .load wow64exts
0:000:x86> !sw
Switched to Host mode
0:000> !heap -p -all
    _HEAP @ b80000
      No FrontEnd
      _HEAP_SEGMENT @ b80000
       CommittedRange @ b80740
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
      * 0000000000b80740 0013 0000  [00]   0000000000b80750    0012f - (busy)
        0000000000b80870 0013 0013  [00]   0000000000b80880    00100 - (busy)
        0000000000b809a0 0021 0013  [00]   0000000000b809b0    001d8 - (busy)
        0000000000b80bb0 0021 0021  [00]   0000000000b80bc0    001d8 - (busy)
        0000000000b80dc0 0008 0021  [00]   0000000000b80dd0    00048 - (busy)
        0000000000b80e40 0004 0008  [00]   0000000000b80e50    00004 - (busy)
        0000000000b80e80 0004 0004  [00]   0000000000b80e90    00010 - (busy)
        0000000000b80ec0 0013 0004  [00]   0000000000b80ed0    00100 - (busy)
        0000000000b80ff0 0013 0013  [00]   0000000000b81000    00100 - (busy)
        0000000000b81120 0133 0013  [00]   0000000000b81130    012f2 - (busy)
          unknown!printable
        0000000000b82450 007e 0133  [00]   0000000000b82460    007a8 - (busy)
        0000000000b82c30 0007 007e  [00]   0000000000b82c40    0003c - (busy)
          unknown!noop
        0000000000b82ca0 0006 0007  [00]   0000000000b82cb0    00030 - (busy)
          unknown!noop
        0000000000b82d00 000a 0006  [00]   0000000000b82d10    00062 - (busy)
          unknown!noop
        0000000000b82da0 0015 000a  [00]   0000000000b82db0    00120 - (busy)
        0000000000b82ef0 0008 0015  [00]   0000000000b82f00    00050 - (busy)
        0000000000b82f70 0015 0008  [00]   0000000000b82f80    00120 - (busy)
        0000000000b830c0 0008 0015  [00]   0000000000b830d0    00050 - (busy)
        0000000000b83140 0027 0008  [00]   0000000000b83150    00238 - (busy)
        0000000000b833b0 0006 0027  [00]   0000000000b833c0    00050 - (free)
        0000000000b83410 0008 0006  [00]   0000000000b83420    00050 - (busy)
        0000000000b83490 0005 0008  [00]   0000000000b834a0    00040 - (free)
        0000000000b834e0 0015 0005  [00]   0000000000b834f0    00120 - (busy)
        0000000000b83630 0008 0015  [00]   0000000000b83640    00050 - (busy)
          unknown!noop
        0000000000b836b0 0007 0008  [00]   0000000000b836c0    0003c - (busy)
          unknown!noop
        0000000000b83720 0008 0007  [00]   0000000000b83730    00042 - (busy)
          unknown!printable
        0000000000b837a0 0012 0008  [00]   0000000000b837b0    00110 - (free)
        0000000000b838c0 0015 0012  [00]   0000000000b838d0    00120 - (busy)
        0000000000b83a10 0006 0015  [00]   0000000000b83a20    00028 - (busy)
        0000000000b83a70 0002 0006  [00]   0000000000b83a80    00010 - (free)
        0000000000b83a90 0008 0002  [00]   0000000000b83aa0    00042 - (busy)
          unknown!noop
        0000000000b83b10 0083 0008  [00]   0000000000b83b20    00800 - (busy)
        0000000000b84340 0015 0083  [00]   0000000000b84350    00120 - (busy)
          ? ntdll!PebLdr+10
        0000000000b84490 0008 0015  [00]   0000000000b844a0    00042 - (busy)
          unknown!noop
        0000000000b84510 02ab 0008  [00]   0000000000b84520    02aa0 - (free)
      * 0000000000b86fc0 0004 02ab  [00]   0000000000b86fd0    00030 - (busy)
       VirtualAllocdBlocks @ b80110
    _HEAP @ aa0000
      No FrontEnd
      _HEAP_SEGMENT @ aa0000
       CommittedRange @ aa0740
        0000000000aa0740 0088 0004  [00]   0000000000aa0750    00870 - (free)
      * 0000000000aa0fc0 0004 0088  [00]   0000000000aa0fd0    00030 - (busy)
       VirtualAllocdBlocks @ aa0110
0:000> g
(3fc8.26c4): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
00007ffc`65f7fad0 cc              int     3
0:001> !heap -p -all
    _HEAP @ b80000
      No FrontEnd
      _HEAP_SEGMENT @ b80000
       CommittedRange @ b80740
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
      * 0000000000b80740 0013 0000  [00]   0000000000b80750    0012f - (busy)
        0000000000b80870 0013 0013  [00]   0000000000b80880    00100 - (busy)
        0000000000b809a0 0021 0013  [00]   0000000000b809b0    001d8 - (busy)
        0000000000b80bb0 0021 0021  [00]   0000000000b80bc0    001d8 - (busy)
        0000000000b80dc0 0008 0021  [00]   0000000000b80dd0    00048 - (busy)
        0000000000b80e40 0004 0008  [00]   0000000000b80e50    00004 - (busy)
        0000000000b80e80 0004 0004  [00]   0000000000b80e90    00010 - (busy)
        0000000000b80ec0 0013 0004  [00]   0000000000b80ed0    00100 - (busy)
        0000000000b80ff0 0013 0013  [00]   0000000000b81000    00100 - (busy)
        0000000000b81120 0133 0013  [00]   0000000000b81130    012f2 - (busy)
          unknown!printable
        0000000000b82450 007e 0133  [00]   0000000000b82460    007a8 - (busy)
        0000000000b82c30 0007 007e  [00]   0000000000b82c40    0003c - (busy)
          unknown!noop
        0000000000b82ca0 0006 0007  [00]   0000000000b82cb0    00030 - (busy)
          unknown!noop
        0000000000b82d00 000a 0006  [00]   0000000000b82d10    00062 - (busy)
          unknown!noop
        0000000000b82da0 0015 000a  [00]   0000000000b82db0    00120 - (busy)
        0000000000b82ef0 0008 0015  [00]   0000000000b82f00    00050 - (busy)
        0000000000b82f70 0015 0008  [00]   0000000000b82f80    00120 - (busy)
        0000000000b830c0 0008 0015  [00]   0000000000b830d0    00050 - (busy)
        0000000000b83140 0027 0008  [00]   0000000000b83150    00238 - (busy)
        0000000000b833b0 0006 0027  [00]   0000000000b833c0    00050 - (free)
        0000000000b83410 0008 0006  [00]   0000000000b83420    00050 - (busy)
        0000000000b83490 0005 0008  [00]   0000000000b834a0    00040 - (free)
        0000000000b834e0 0015 0005  [00]   0000000000b834f0    00120 - (busy)
        0000000000b83630 0008 0015  [00]   0000000000b83640    00050 - (busy)
          unknown!noop
        0000000000b836b0 0007 0008  [00]   0000000000b836c0    0003c - (busy)
          unknown!noop
        0000000000b83720 0008 0007  [00]   0000000000b83730    00042 - (busy)
          unknown!printable
        0000000000b837a0 0012 0008  [00]   0000000000b837b0    00110 - (free)
        0000000000b838c0 0015 0012  [00]   0000000000b838d0    00120 - (busy)
        0000000000b83a10 0006 0015  [00]   0000000000b83a20    00028 - (busy)
        0000000000b83a70 0002 0006  [00]   0000000000b83a80    00010 - (free)
        0000000000b83a90 0008 0002  [00]   0000000000b83aa0    00042 - (busy)
          unknown!noop
        0000000000b83b10 0083 0008  [00]   0000000000b83b20    00800 - (busy)
        0000000000b84340 0015 0083  [00]   0000000000b84350    00120 - (busy)
          ? ntdll!PebLdr+10
        0000000000b84490 0008 0015  [00]   0000000000b844a0    00042 - (busy)
          unknown!noop
        0000000000b84510 02ab 0008  [00]   0000000000b84520    02aa0 - (free)
      * 0000000000b86fc0 0004 02ab  [00]   0000000000b86fd0    00030 - (busy)
       VirtualAllocdBlocks @ b80110
    _HEAP @ aa0000
      No FrontEnd
      _HEAP_SEGMENT @ aa0000
       CommittedRange @ aa0740
        0000000000aa0740 0088 0004  [00]   0000000000aa0750    00870 - (free)
      * 0000000000aa0fc0 0004 0088  [00]   0000000000aa0fd0    00030 - (busy)
       VirtualAllocdBlocks @ aa0110

里面微小的差距,我们大可不必纠结,下面可以看一下概览的信息,用于有个大概的了解:

0:001> !address -f:Heap(过滤只查看Heap 相关的信息)
        BaseAddress      EndAddress+1        RegionSize     Type       State                 Protect             Usage
--------------------------------------------------------------------------------------------------------------------------
       0`00aa0000        0`00ab0000        0`00010000 MEM_MAPPED  MEM_COMMIT  PAGE_READWRITE                     Heap64     [ID: 1; Handle: 0000000000aa0000; Type: Segment]
       0`00b80000        0`00b87000        0`00007000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     Heap64     [ID: 0; Handle: 0000000000b80000; Type: Segment]
       0`00b87000        0`00b8f000        0`00008000 MEM_PRIVATE MEM_RESERVE                                    Heap64     [ID: 0; Handle: 0000000000b80000; Type: Segment]

** 进程初始化的时候,只有两个堆**

进程的第一次malloc 操作之后的地址状态:

在这里插入图片描述
尝试获取其所在的堆的信息:

0:001> !heap -p -a c67330

发现没有输出任何信息,查看对列表及地址空间的详细信息:

0:001> !address -f:Heap


        BaseAddress      EndAddress+1        RegionSize     Type       State                 Protect             Usage
        BaseAddress      EndAddress+1        RegionSize     Type       State                 Protect             Usage
--------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------
       0`00a40000        0`00a50000        0`00010000 MEM_MAPPED  MEM_COMMIT  PAGE_READWRITE                     Heap64            0`00a40000        0`00a50000        0`00010000 MEM_MAPPED  MEM_COMMIT  PAGE_READWRITE                     Heap64     [ID: 1; Handle: 0000000000a40000; Type: Segment][ID: 1; Handle: 0000000000a40000; Type: Segment]

       0`011e0000        0`011e7000        0`00007000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     Heap64            0`011e0000        0`011e7000        0`00007000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     Heap64     [ID: 0; Handle: 00000000011e0000; Type: Segment][ID: 0; Handle: 00000000011e0000; Type: Segment]

       0`011e7000        0`011ef000        0`00008000 MEM_PRIVATE MEM_RESERVE                                    Heap64            0`011e7000        0`011ef000        0`00008000 MEM_PRIVATE MEM_RESERVE                                    Heap64     [ID: 0; Handle: 00000000011e0000; Type: Segment][ID: 0; Handle: 00000000011e0000; Type: Segment]


堆的地址空间不包含我们申请的内存的起始地址。
检查地址空间:

0:001> !address

                                     
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...


        BaseAddress      EndAddress+1        RegionSize     Type       State                 Protect             Usage
        BaseAddress      EndAddress+1        RegionSize     Type       State                 Protect             Usage
--------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------
        无用信息
+ +        0`00c00000        0`00c35000        0`00035000 MEM_PRIVATE MEM_RESERVE                                    Stack64           0`00c00000        0`00c35000        0`00035000 MEM_PRIVATE MEM_RESERVE                                    Stack64    [~1; 42bc.2ed8][~1; 42bc.2ed8]

           0`00c35000        0`00c38000        0`00003000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE|PAGE_GUARD          Stack64           0`00c35000        0`00c38000        0`00003000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE|PAGE_GUARD          Stack64    [~1; 42bc.2ed8][~1; 42bc.2ed8]

           0`00c38000        0`00c40000        0`00008000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     Stack64           0`00c38000        0`00c40000        0`00008000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     Stack64    [~1; 42bc.2ed8][~1; 42bc.2ed8]

+ +        0`00c40000        0`00c60000        0`00020000             MEM_FREE    PAGE_NOACCESS                      Free              0`00c40000        0`00c60000        0`00020000             MEM_FREE    PAGE_NOACCESS                      Free       

+ +        0`00c60000        0`00c6d000        0`0000d000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     <unknown>         0`00c60000        0`00c6d000        0`0000d000 MEM_PRIVATE MEM_COMMIT  PAGE_READWRITE                     <unknown>  [mb..............][mb..............]

           0`00c6d000        0`00d60000        0`000f3000 MEM_PRIVATE MEM_RESERVE                                    <unknown>         0`00c6d000        0`00d60000        0`000f3000 MEM_PRIVATE MEM_RESERVE                                    <unknown>  

+ +        0`00d60000        0`00d61000        0`00001000 MEM_IMAGE   MEM_COMMIT  PAGE_READONLY                      Image             0`00d60000        0`00d61000        0`00001000 MEM_IMAGE   MEM_COMMIT  PAGE_READONLY                      Image      [ExeTestDllHeapTest; "ExeTestDllHeapTest.exe"][ExeTestDllHeapTest; "ExeTestDllHeapTest.exe"]

           0`00d61000        0`00d82000        0`00021000 MEM_IMAGE   MEM_COMMIT  PAGE_EXECUTE_READ                  Image             0`00d61000        0`00d82000        0`00021000 MEM_IMAGE   MEM_COMMIT  PAGE_EXECUTE_READ                  Image      [ExeTestDllHeapTest; "ExeTestDllHeapTest.exe"][ExeTestDllHeapTest; "ExeTestDllHeapTest.exe"]

       无用信息

这个地址在windbg 中没有关联其他的heap信息,和通常我们理解的,new delete,malloc,free 都操作的是进程堆,是违背的。
通过ida查看申请操作的详细逻辑:

void *__cdecl _malloc_base(unsigned int size)
.text:00411285 __malloc_base   proc near               ; CODE XREF: __crt_stdio_output::formatting_buffer::ensure_buffer_is_big_enough<char>(uint)+46↑p
.text:00411285                                         ; _malloc+6↑j ...
.text:00411285
.text:00411285 size            = dword ptr  8
.text:00411285
.text:00411285                 mov     edi, edi
.text:00411287                 push    ebp
.text:00411288                 mov     ebp, esp
.text:0041128A                 push    esi
.text:0041128B                 mov     esi, [ebp+size]
.text:0041128E                 cmp     esi, 0FFFFFFE0h
.text:00411291                 ja      short loc_4112C3
.text:00411293                 test    esi, esi
.text:00411295                 jnz     short loc_4112AE
.text:00411297                 inc     esi
.text:00411298                 jmp     short loc_4112AE
.text:0041129A ; ---------------------------------------------------------------------------
.text:0041129A
.text:0041129A loc_41129A:                             ; CODE XREF: __malloc_base+3A↓j
.text:0041129A                 call    __query_new_mode
.text:0041129F                 test    eax, eax
.text:004112A1                 jz      short loc_4112C3
.text:004112A3                 push    esi             ; size
.text:004112A4                 call    __callnewh
.text:004112A9                 pop     ecx
.text:004112AA                 test    eax, eax
.text:004112AC                 jz      short loc_4112C3
.text:004112AE
.text:004112AE loc_4112AE:                             ; CODE XREF: __malloc_base+10↑j
.text:004112AE                                         ; __malloc_base+13↑j
.text:004112AE                 push    esi             ; dwBytes
.text:004112AF                 push    0               ; dwFlags
.text:004112B1                 push    ___acrt_heap    ; hHeap//这里我们明显看到了crt 中使用了堆内存,但是windbg 中显然没有堆这部分内存的支持
.text:004112B7                 call    ds:__imp__HeapAlloc@12 ; HeapAlloc(x,x,x)
.text:004112BD                 test    eax, eax
.text:004112BF                 jz      short loc_41129A
.text:004112C1                 jmp     short loc_4112D0
.text:004112C3 ; ---------------------------------------------------------------------------
.text:004112C3
.text:004112C3 loc_4112C3:                             ; CODE XREF: __malloc_base+C↑j
.text:004112C3                                         ; __malloc_base+1C↑j ...
.text:004112C3                 call    __errno
.text:004112C8                 mov     dword ptr [eax], 0Ch
.text:004112CE                 xor     eax, eax
.text:004112D0
.text:004112D0 loc_4112D0:                             ; CODE XREF: __malloc_base+3C↑j
.text:004112D0                 pop     esi
.text:004112D1                 pop     ebp
.text:004112D2                 retn
.text:004112D2 __malloc_base   endp

确实用的是堆内存,而且是peb 中的系统默认堆,但是windbg 中没有显示这部分的堆内存
使用!peb 检查当前peb,手动查看进程默认堆的细节

0:001> !peb
Wow64 PEB32 at edf000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            Yes
    ImageBaseAddress:         0000000000d60000
    NtGlobalFlag:             70
    NtGlobalFlag2:            0
    Ldr                       00000000771adca0
    ***  _PEB_LDR_DATA type was not found...
    *** unable to read Ldr table at 00000000771adca0
    SubSystemData:     0000000000000000
    ProcessHeap:       0000000000c60000
    ProcessParameters: 0000000000c61ed8
    ***  _CURDIR type was not found...
    ***  _CURDIR type was not found...
    WindowTitle:  '< Name not readable >'
    ImageFile:    '< Name not readable >'
    CommandLine:  '< Name not readable >'
    DllPath:      '< Name not readable >'
    Environment:  0000000000000000
       Unable to read Environment string.

查看进程默认堆 0000000000c60000的信息

失败的原因还是,wow 64调试的问题,这块我不是那么熟悉,导致了这么艰难的行进

先跳过这个疑问,在32-bit win7 虚拟机中,用相关指令研究堆的分配情况

  • 打开虚拟机的时候发现虚拟机无法执行,相关解决方案见:
  • https://bbs.csdn.net/topics/394603510?page=1#post-409297329

####重开一个博客收拾鸡毛

发布了93 篇原创文章 · 获赞 13 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_18218335/article/details/102144706