Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В следующей серии команд показано, как использовать функции проверки кучи страниц gFlags и отладчика NTSD для обнаружения ошибки в использовании кучи памяти. В этом примере программист подозревает, что вымышленное приложение под названием pheap-buggy.exeимеет ошибку кучи и проходит ряд тестов, чтобы выявить ошибку.
Дополнительные сведения о NTSD см. в разделе Отладка с помощью CDB и NTSD.
Шаг 1: Включение стандартной проверки кучи страниц
Следующая команда включает стандартную проверку кучи страницы для pheap-buggy.exe:
gflags /p /enable pheap-buggy.exe
Шаг 2: Убедитесь, что куча страниц включена
Следующая команда перечисляет файлы изображений, для которых включена проверка кучи страниц.
gflags /p
В ответ GFlags отображает следующий список программ. В этом отображении трассировки указывают на стандартную проверку страничной кучи, а полные трассировки указывают на полную проверку страничной кучи. В этом случае pheap-buggy.exe перечислен с , указывающим, что означает, что стандартная проверка кучи страниц включена, как и задумано.
pheap-buggy.exe: page heap enabled with flags (traces )
шаг 3. Запуск отладчика
Следующая команда запускает функцию CorruptAfterEnd pheap-buggy.exe в NTSD с параметрами -g (игнорировать начальную точку останова) и -x (задать второй шанс перерыва на исключения нарушения доступа):
ntsd -g -x pheap-buggy CorruptAfterEnd
Если приложение завершается ошибкой, NTSD создает следующий дисплей, который указывает, что он обнаружил ошибку в pheap-buggy.exe:
===========================================================
VERIFIER STOP 00000008: pid 0xAA0: corrupted suffix pattern
00C81000 : Heap handle
00D81EB0 : Heap block
00000100 : Block size
# 00000000 :
===========================================================
Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00d81eb0 ecx=77f7e257 edx=0006fa18 esi=00000008 edi=00c81000
eip=77f7e098 esp=0006fc48 ebp=0006fc5c iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
77f7e098 cc int 3
Сведения о заголовке включают адрес кучи с поврежденным блоком (00C81000 : дескриптор кучи), адрес поврежденного блока (00D81EB0 : блок в куче), а также размер выделения (00000100 : размер блока).
Сообщение "поврежденный шаблон суффикса" указывает на то, что приложение нарушило шаблон целостности данных, вставленный GFlags после завершения выделения кучи pheap-buggy.exe.
шаг 4. Отображение стека вызовов
На следующем шаге используйте адреса, сообщаемые NTSD, чтобы найти функцию, вызвавшей ошибку. Следующие две команды включают отображение номеров строк в отладчике и показывают стек вызовов с номерами строк.
C:\>.lines
Line number information will be loaded
C:\>kb
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0006fc5c 77f9e6dd 00000008 77f9e3e8 00c81000 ntdll!DbgBreakPoint
0006fcd8 77f9f3c8 00c81000 00000004 00d81eb0 ntdll!RtlpNtEnumerateSubKey+0x2879
0006fcfc 77f9f5bb 00c81000 01001002 00000010 ntdll!RtlpNtEnumerateSubKey+0x3564
0006fd4c 77fa261e 00c80000 01001002 00d81eb0 ntdll!RtlpNtEnumerateSubKey+0x3757
0006fdc0 77fc0dc2 00c80000 01001002 00d81eb0 ntdll!RtlpNtEnumerateSubKey+0x67ba
0006fe78 77fbd87b 00c80000 01001002 00d81eb0 ntdll!RtlSizeHeap+0x16a8
0006ff24 010013a4 00c80000 01001002 00d81eb0 ntdll!RtlFreeHeap+0x69
0006ff3c 01001450 00000000 00000001 0006ffc0 pheap-buggy!TestCorruptAfterEnd+0x2b [d:\nttest\base\testsrc\kernel\rtl\pageheap\pheap-buggy.cxx @ 185]
0006ff4c 0100157f 00000002 00c65a68 00c631d8 pheap-buggy!main+0xa9 [d:\nttest\base\testsrc\kernel\rtl\pageheap\pheap-buggy.cxx @ 69]
0006ffc0 77de43fe 00000000 00000001 7ffdf000 pheap-buggy!mainCRTStartup+0xe3 [crtexe.c @ 349]
0006fff0 00000000 0100149c 00000000 78746341 kernel32!DosPathToSessionPathA+0x204
В результате отладчик отображает стек вызовов для pheap-buggy.exe с номерами строк. Отображение стека вызовов показывает, что ошибка произошла, когда функция TestCorruptAfterEnd в pheap-buggy.exe попыталась освободить область памяти по адресу 0x00c80000 с вызовом HeapFree, перенаправлением на RtlFreeHeap.
Наиболее вероятной причиной этой ошибки является то, что программа вышла за пределы буфера, который она выделила в этой функции.
Шаг 5: Включение полной проверки кучи на странице
В отличие от стандартной проверки страницы кучи, полная проверка страницы кучи может перехватывать неправильное использование этого буфера кучи сразу после его возникновения. Следующая команда включает полную проверку кучи страницы для pheap-buggy.exe:
gflags /p /enable pheap-buggy.exe /full
шаг 6: Убедитесь, что включена полная куча страниц
Следующая команда содержит программы, для которых включена проверка кучи страницы:
gflags /p
В ответ GFlags отображает следующий список программ. В этом отображении трассировки указывают стандартную проверку кучи страниц, а полные трассировки указывают полную проверку кучи страниц. В этом случае pheap-buggy.exe находится в списке с полных трасс, указывая, что включена полная проверка кучи страниц, как предполагалось.
pheap-buggy.exe: page heap enabled with flags (full traces )
шаг 7. Снова запустите отладчик
Следующая команда выполняет функцию CorruptAfterEnd из pheap-buggy.exe в отладчике NTSD с параметрами -g (игнорировать начальную точку останова) и -x (установить прерывание второго шанса на исключения нарушений доступа):
ntsd -g -x pheap-buggy CorruptAfterEnd
Если приложение завершается ошибкой, NTSD выводит следующее сообщение, которое указывает, что он обнаружил ошибку в pheap-buggy.exe:
Page heap: process 0x5BC created heap @ 00880000 (00980000, flags 0x3)
ModLoad: 77db0000 77e8c000 kernel32.dll
ModLoad: 78000000 78046000 MSVCRT.dll
Page heap: process 0x5BC created heap @ 00B60000 (00C60000, flags 0x3)
Page heap: process 0x5BC created heap @ 00C80000 (00D80000, flags 0x3)
Access violation - code c0000005 (first chance)
Access violation - code c0000005 (!!! second chance !!!)
eax=00c86f00 ebx=00000000 ecx=77fbd80f edx=00c85000 esi=00c80000 edi=00c16fd0
eip=01001398 esp=0006ff2c ebp=0006ff4c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000206
pheap-buggy!TestCorruptAfterEnd+1f:
01001398 889801010000 mov [eax+0x101],bl ds:0023:00c87001=??
При включенной проверке кучи полной страницы отладчик прерывается при нарушении доступа. Чтобы найти точное расположение нарушения доступа, включите отображение номеров строк и отобразите трассировку стека вызовов.
Трассировка нумерованного стека вызовов отображается следующим образом:
ChildEBP RetAddr Args to Child
0006ff3c 01001450 00000000 00000001 0006ffc0 pheap-buggy!TestCorruptAfterEnd+0x1f [d:\nttest\base\testsrc\kernel\rtl\pageheap\pheap-buggy.cxx @ 184]
0006ff4c 0100157f 00000002 00c16fd0 00b70eb0 pheap-buggy!main+0xa9 [d:\nttest\base\testsrc\kernel\rtl\pageheap\pheap-buggy.cxx @ 69]
0006ffc0 77de43fe 00000000 00000001 7ffdf000 pheap-buggy!mainCRTStartup+0xe3 [crtexe.c @ 349]
WARNING: Stack unwind information not available. Following frames may be wrong.
0006fff0 00000000 0100149c 00000000 78746341 kernel32!DosPathToSessionPathA+0x204
Трассировка стека показывает, что проблема возникает на строке 184 в pheap-buggy.exe. Так как включена проверка полной страничной кучи, стек вызовов начинается в коде приложения, а не в системной библиотеке DLL. В результате нарушение было обнаружено в месте его происхождения, а не когда блок кучи был освобожден.
шаг 8. Поиск ошибки в коде
Быстрая проверка показывает причину проблемы: программа пытается записать в 257-й байт (0x101) буфера размером 256 байт (0x100), что является распространенной ошибкой смещения на один.
*((PCHAR)Block + 0x100) = 0;