2014-04-24 20 views
5

Jak korzystać z ustawienia GFlags i jak z niego korzystać Enable heap tagging by DLL?Jak skorzystać z tagowania sterty przez bibliotekę DLL?

W jaki sposób aktywować ustawienie dla procesu, ale nie znalazłem przydatne informacje na wyjściu z !heap -t w WinDbg. Spodziewałem się niektórych wyników takich jak to:

0:000> !heap -t 
Index Address Allocated by 
1:  005c0000 MyDll.dll 
2:  006b0000 AnotherDll.dll 

dzięki czemu mogę zidentyfikować, która stuła została utworzona przez które DLL, a następnie np. zidentyfikować źródło wycieku pamięci.

Czy jest to nieporozumienie dotyczące terminu "oznaczanie sterty przez bibliotekę DLL" lub czy potrzebuję więcej poleceń, aby uzyskać pożądany wynik?

Moje badania do tej pory:

  • google za tutorial na ten temat, ale nie mogłem znaleźć szczegółowy opis
  • czytałem WinDbg na .hh !heap ale to nie wyjaśniono tam szczegółowo, jak również. Tag jest używany tylko w !heap -b

Odpowiedz

5

znowu bardzo późnym odpowiedź

korzystać z HeapTagging you need to create a tag pierwszy w kodzie.
o ile wiem (czyli do września XP SP3) były no Documented APIS to Create a tag

(I miałaś spasowane ze sterty od tego czasu więc nie jestem świadomy najnowsze API w OS> przepisuje Vista zostały wykonane do menedżera sterty więc prawdopodobnie wielu z ^^^features^^^ że mogę napisać poniżej mogły być poprawione lub poprawił lub usunięto błędy)

w XP SP3 można użyć nieudokumentowane RtlCreateTagHeap aby utworzyć nowy tag albo Process Heap lub Private Heap

i po utworzeniu tha tag musisz ustawić globalną flagę 8000 | 800

htg - Enable heap tagging 
htd - Enable heap tagging by DLL 

i theoratically all allocs and frees must get tagged.

ale practically only allocations > 512 kB gets tagged w XP SP3 z tych podstawowych etapów

to albo jest błąd lub funkcja ograniczenia znakowania przydziałów i uwalnia> 512 kB
HeapAlloc goes through ZwAllocateVirtualMemory w przypadku PRZYDZIELANIA> 512 kb 32 procesu bitów refer HeapCreate/HeapAlloc Documentation in msdn

i jako debuging aid możesz patch ntdll.dll na the fly to enable tagging dla all Allocations and frees.

Poniżej znajduje się przykładowy kod, który demonstruje tagowanie i jak to wszystko zobaczyć w WinDBG

kompilacji używając cl /Zi /analyze /W4 <src> /link /RELEASE

użytkowania WinDbg wykonać aplikację i oglądać tagging z poleceniem !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,0); 
     if (RtlCreateTagHeap != NULL) 
     { 
      tag1 = RtlCreateTagHeap (hHeap,0,L"HeapTag!",L"MyTag1"); 
      tag2 = RtlCreateTagHeap (hHeap,0,L"HeapTag!",L"MyTag2"); 
      tag3 = RtlCreateTagHeap (hHeap,0,L"HeapTag!",L"MyTag3"); 
      tag4 = RtlCreateTagHeap (hHeap,0,L"HeapTag!",L"MyTag4"); 
     } 
    } 
    HANDLE DefHeap = GetProcessHeap(); 
    if ((RtlCreateTagHeap != NULL) && (DefHeap != NULL)) 
    { 
     tag5 = RtlCreateTagHeap (DefHeap,0,L"HeapTag!",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,NULL,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,NULL,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,NULL,pch[i]); 
     } 
    } 
} 
void _cdecl main() 
{ 
    HeapTagwithHeapAllocPrivate(); 
} 

skompilowany plik exe do uruchomienia z windbg, jak poniżej:

wykonanie domyślnie i inspekcja
** zaledwie 50 tagi będą widoczne wszystkie z nich są> 512 kB Przydziały

CDB -c "g; sterty * -t; q!" Newheaptag.exe | grep Tag **

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 

łatanie Ntdll na system przerwania powinny wszystkie znaczniki widoczne

eb = zapisu bajt plaster i uruchomić exe na wyjściu sprawdzać stosy ze znacznikami cdb -c "eb 7c94b8a1 + 3 00; g;! heap * -t; q" newheaptag.exe | grep Tag

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 
+0

Jest ok czekać dłuższy czas na twardszych pytań :-) pójdę do przodu i spróbować (Windows 7). Sama koncepcja brzmi mało użytecznie, ponieważ ktoś musi pomyśleć o oznaczaniu stosów z góry. Zazwyczaj myślę o tagowaniu sterty tylko w przypadku, gdy już mam problem. –

+0

koncepcja jest cicha przydatna robisz z przyzwyczajenia do kodowania solidnie :) w jądrze jesteś zmuszony to zrobić domyślnie ..... ExAllocatePool jest przestarzałe radzimy użyć ExAllocatePoolWithTag i tak z wyprzedzeniem tagować, które narzędzia pomocnicze użyj do zera, to wszystko jest w jądrze, jest usprawnione w trybie użytkownika, ale nie jest usprawnione, ale jeśli spróbujesz go na dowolnym os> xp upto wygrać 8.1 jako datę, odeślij wyniki – blabb

Powiązane problemy