windbg – 如何从DLL堆标记中受益?
如何使用GFlags设置
Enable heap tagging by DLL并从中受益?
我知道如何激活进程的设置,但我没有在WinDbg的!heap -t的输出中找到有用的信息.我期待这样的输出: 0:000> !heap -t Index Address Allocated by 1: 005c0000 MyDll.dll 2: 006b0000 AnotherDll.dll 这样我就可以识别哪个堆是由哪个DLL创建的,然后是识别内存泄漏的来源. 这是对“DLL堆标记”一词的误解,还是需要更多命令来获得所需的结果? 我的研究到目前为止: >我搜索了有关此主题的教程,但我找不到详细的说明 解决方法
再来一个很晚的答案
要从HeapTagging中受益,您需要先在代码中创建一个标记. (从那时起我就没有堆乱了,所以我不知道os中的最新api> vista重写是对堆管理器进行的,所以我下面发布的很多^^^功能^^^可能已被更正或更好或者错误删除) 在xp-sp3中,您可以使用未记录的RtlCreateTagHeap为Process Heap或Private堆创建新标记 在创建tha标签后,您需要设置全局标志8000 | 800 htg - Enable heap tagging htd - Enable heap tagging by DLL 并且理论上所有的alloc和frees都必须被标记. 但实际上只有分配> 512 kB使用这些基本步骤在xp-sp3中标记 它要么是一个错误,要么是一个限制标记分配和释放的功能> 512 kB 作为debuging辅助工具,您可以动态修补ntdll.dll,以便为所有分配和释放启用标记. 下面是一个示例代码,演示了标记以及如何在windbg中查看它们 使用cl / Zi / analyze / W4< src>进行编译/ link / RELEASE 使用windbg执行应用程序并使用!heap * -t命令查看标记 #include <windows.h> #include <stdio.h> //heaptags are kinda broken or they are intentionally //given only to allocations > 512 kb // allocation > 512 kb //go through VirtualAlloc Route for Heap created with maxsize //set to 0 uncomment ALLOCSIZE 0xfdfd2 and recompile to watch // tagging increase by 100% with ALLOCSIZE 0xfdfd1 only 50 allocs // and frees that are > 512 kB will be tagged these magic numbers // are related to comment in HeapCreate Documentation that state // slightly less than 512 kB will be allocated for 32 bit process // tagging can be dramatically increased by patching ntdll when // stopped on system breakpoint patch 7c94b8a4 (xpsp3 ntdll.dll) // use the below command in windbg for finding the offset of pattern // command must be in single line no line breaks // .foreach /pS 4 /ps 4 ( place { !grep -i -e call -c // "# call*RtlpUpdateTagEntry 7c900000 l?20000" } ) { ub place } // the instruction we are searching to patch is //7c94b8a1 81e3ff0fffff and ebx,0FFFF0FFFh // patch 0f to 00 at system breakpoint with eb 7c94b8a1+3 00 #define BUFFERSIZE 100 #define ALLOCSIZE 0xfdfd1 //#define ALLOCSIZE 0xfdfd2 typedef int ( __stdcall *g_RtlCreateTagHeap) ( HANDLE hHeap,void * unknown,wchar_t * BaseString,wchar_t * TagString ); void HeapTagwithHeapAllocPrivate() { PCHAR pch[BUFFERSIZE] = {}; HANDLE hHeap = 0; ULONG tag1 = 0; ULONG tag2 = 0; ULONG tag3 = 0; ULONG tag4 = 0; ULONG tag5 = 0; g_RtlCreateTagHeap RtlCreateTagHeap = 0; HMODULE hMod = LoadLibrary("ntdll.dll"); if(hMod) { RtlCreateTagHeap = (g_RtlCreateTagHeap) GetProcAddress( hMod,"RtlCreateTagHeap"); } if (hHeap == 0) { hHeap = HeapCreate(0,0); if (RtlCreateTagHeap != NULL) { tag1 = RtlCreateTagHeap (hHeap,L"HeapTag!",L"MyTag1"); tag2 = RtlCreateTagHeap (hHeap,L"MyTag2"); tag3 = RtlCreateTagHeap (hHeap,L"MyTag3"); tag4 = RtlCreateTagHeap (hHeap,L"MyTag4"); } } HANDLE DefHeap = GetProcessHeap(); if ( (RtlCreateTagHeap != NULL) && (DefHeap != NULL )) { tag5 = RtlCreateTagHeap (DefHeap,L"MyTag5"); for ( int i = 0; i < BUFFERSIZE ; i++ ) { pch[i]= (PCHAR) HeapAlloc( DefHeap,HEAP_ZERO_MEMORY| tag5,1 ); HeapFree(DefHeap,NULL,pch[i]); } } if(hHeap) { for ( int i = 0; i < BUFFERSIZE ; i++ ) { pch[i]= (PCHAR) HeapAlloc( hHeap,HEAP_ZERO_MEMORY| tag1,1 ); //lets leak all allocs patch ntdll to see the tagging details //HeapFree(hHeap,pch[i]); } for ( int i = 0; i < BUFFERSIZE ; i++ ) { pch[i]= (PCHAR) HeapAlloc( hHeap,HEAP_ZERO_MEMORY| tag2,100 ); // lets leak 40% allocs patch ntdll to see the tagging details if(i >= 40) HeapFree(hHeap,pch[i]); } // slightly less than 512 kb no tagging for ( int i = 0; i < BUFFERSIZE / 2 ; i++ ) { pch[i]= (PCHAR) HeapAlloc( hHeap,HEAP_ZERO_MEMORY| tag3,ALLOCSIZE / 2 ); } // > 512 kb default tagging for ( int i = BUFFERSIZE / 2; i < BUFFERSIZE ; i++ ) { pch[i]= (PCHAR) HeapAlloc( hHeap,HEAP_ZERO_MEMORY | tag4,ALLOCSIZE ); } for (int i =0 ; i < BUFFERSIZE ; i++) { HeapFree(hHeap,pch[i]); } } } void _cdecl main() { HeapTagwithHeapAllocPrivate(); } 使用windbg运行的已编译的exe如下所示 默认执行和检查 cdb -c“g;!heap * -t; q”newheaptag.exe | grep标签** heaptag:&;cdb -c "g;!heap * -t;q" newheaptag.exe | grep Tag Tag Name Allocs Frees Diff Allocated Tag Name Allocs Frees Diff Allocated Tag Name Allocs Frees Diff Allocated 0004: HeapTag!MyTag4 50 50 0 0 在系统断点上修补ntdll应该使所有标签可见 eb =写字节 heaptag:&;cdb -c "eb 7c94b8a1+3 00;g;!heap * -t;q" newheaptag.exe | grep Tag Tag Name Allocs Frees Diff Allocated 0012: HeapTag!MyTag5 100 100 0 0 <-our tag in process heap Tag Name Allocs Frees Diff Allocated Tag Name Allocs Frees Diff Allocated 0001: HeapTag!MyTag1 100 0 100 3200 <--- leak all 0002: HeapTag!MyTag2 100 60 40 5120 <--- leak 40 % 0003: HeapTag!MyTag3 50 50 0 0 <--- clean < 512 kB 0004: HeapTag!MyTag4 50 50 0 0 <----clean > 512 kB (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows常用操作
- windows-installer – 无提示Windows Installer安装程序,无
- 如何在Windows控制台中递归使用“svn add”?
- windows-8 – 如何使用在任何分辨率上都很好的字体设计Metr
- Windows 7:过冲C std :: this_thread :: sleep_for
- 简单探究一下window下的wifi各种东西
- windows文件命名特性利用漏洞
- win10 下安装 neo4j(转)
- .net – 在WPF中实例化用户控件时PresentationFramework.dl
- 为什么Windows Server 2012 R2标准版仅显示可用内存的20%?