0BCA1000 : Heap handle used in the call.
49DC31C8 : Heap block involved in the operation.
000000E3 : Size of the heap block.
49DC32AB : Corruption address.
На хипе с "ручкой " 0BCA1000 запросили память длинной 0x000000E3, и куча вернула ее по адресу 0x49DC31C8.
Но какая то редиска снесла маркеры верификатора по 0x49DC32AB
Т.е. буквально говоря: 0x49DC31C8 + 0x000000E3 = 0x49DC32AB произошла запись прямо сразу за выделенным блоком.
Т.е. это классический, но головомойный buffer overrun.
Место где это произошло мне с помощью Application Verifier не определить, придется делать какой то вспомогательный класс + макросы
и рассовывать по коду в места когда по выделенному указателю или смещению от него происходит запись, для отслеживания редиски.
X>address sanitizer в помощь. лучшей тулзы для подобных задач еще не видел.
А оно с cl дружит? Сссыль я нашёл, но смущают названия exe файлов которые начинаются с llvm или gcc
Здравствуйте, PPA, Вы писали:
PPA>Озвучьте ценник — сколько хотите за сборку моей виндовой программы в линуксе PPA>и обработкой ее санитаром?
Кстати, у clang'а тоже есть санитары. Я могу ошибаться, но вроде они вообще пошли от llvm сначала.
Так вот, у него же есть поддержка Windows, эти плагины должны работать в нём (clang.exe --help | grep -i sanitize).
int main(int argc, char* argv[]) {
char* p = new char[3];
for(int i = 0; i < argc; i++)
p[i] = argv[i][0];
return argc;
}
sample output
$ clang-cl -v -fsanitize=address ctest.cpp
$ ctest 1 2 3
=================================================================
==6424==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x02d006b3 at pc 0x004014f0 bp 0xdeadbeef sp 0x0018fe14
WRITE of size 1 at 0x02d006b3 thread T0
#0 0x4014ef in main+0x4ef (F:\Documents\ctest.exe+0x14ef)
#1 0x41c448 in __tmainCRTStartup f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c:266
#2 0x75fb3389 in BaseThreadInitThunk+0x11 (C:\Windows\syswow64\kernel32.dll+0x13389)
#3 0x77849f71 in RtlInitializeExceptionChain+0x62 (C:\Windows\SysWOW64\ntdll.dll+0x39f71)
#4 0x77849f44 in RtlInitializeExceptionChain+0x35 (C:\Windows\SysWOW64\ntdll.dll+0x39f44)
0x02d006b3 is located 0 bytes to the right of 3-byte region [0x02d006b0,0x02d006b3)
allocated by thread T0 here:
#0 0x41c082 in operator new[]+0x72 (F:\Documents\ctest.exe+0x1c082)
#1 0x4011dc in main+0x1dc (F:\Documents\ctest.exe+0x11dc)
#2 0x41c448 in __tmainCRTStartup f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c:266
#3 0x75fb3389 in BaseThreadInitThunk+0x11 (C:\Windows\syswow64\kernel32.dll+0x13389)
#4 0x77849f71 in RtlInitializeExceptionChain+0x62 (C:\Windows\SysWOW64\ntdll.dll+0x39f71)
#5 0x77849f44 in RtlInitializeExceptionChain+0x35 (C:\Windows\SysWOW64\ntdll.dll+0x39f44)
SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 main
Shadow bytes around the buggy address:
0x205a0080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x205a0090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x205a00a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x205a00b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x205a00c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x205a00d0: fa fa fa fa fa fa[03]fa fa fa 00 06 fa fa 00 00
0x205a00e0: fa fa 00 07 fa fa 00 06 fa fa 00 05 fa fa 00 07
0x205a00f0: fa fa 00 07 fa fa 00 06 fa fa 00 07 fa fa 00 06
0x205a0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x205a0110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x205a0120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
ASan internal: fe
==6424==ABORTING
Здравствуйте, nen777w, Вы писали:
N>Место где это произошло мне с помощью Application Verifier не определить, придется делать какой то вспомогательный класс + макросы N>и рассовывать по коду в места когда по выделенному указателю или смещению от него происходит запись, для отслеживания редиски.
Простой вариант — включить PageHeap, тогда запись за пределами выделенного в хипе блока сразу приведет к легко обнаруживаемому AV.
Надо установить Debugging Tools for Windows, запустить утилиту Global Flags и для заданного процесса поставить одну галочку. Короче, google for "page heap".
Здравствуйте, PPA, Вы писали:
PPA>В заголовке ведь явно указано — используется Application Verifier
это мне должно о чем-то говорить?
PPA>Вы тут в подписи подработку ищите. PPA>Озвучьте ценник — сколько хотите за сборку моей виндовой программы в линуксе PPA>и обработкой ее санитаром?
не интересно.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, nen777w, Вы писали:
N>Т.е. это классический, но головомойный buffer overrun. N>Место где это произошло мне с помощью Application Verifier не определить, придется делать какой то вспомогательный класс + макросы N>и рассовывать по коду в места когда по выделенному указателю или смещению от него происходит запись, для отслеживания редиски.
Я делал так (без Application Verifier, с перерасходом памяти).
Для каждого затребованного куска памяти выделял две страницы (или больше) и возвращал указатель из первой из них так, чтобы конец выделенной памяти приходился ровно на конец первой страницы. Со второй страницы снимал права чтения/записи. Поэтому прострел мимо выделенной памяти приводил к исключения прямо в месте возникновения. Понятно, что такой метод не для всех случаев подходит, но мне помогал частенько.
А мемори брейкпоинт на этот адрес памяти не поможет? Будет видно кто меняет.
Правда работает если все детерменированно и в одном и том же месте проблема происходит.
Здравствуйте, OlegMax, Вы писали:
OM>Здравствуйте, nen777w, Вы писали:
N>>Место где это произошло мне с помощью Application Verifier не определить, придется делать какой то вспомогательный класс + макросы N>>и рассовывать по коду в места когда по выделенному указателю или смещению от него происходит запись, для отслеживания редиски.
OM>Простой вариант — включить PageHeap, тогда запись за пределами выделенного в хипе блока сразу приведет к легко обнаруживаемому AV. OM>Надо установить Debugging Tools for Windows, запустить утилиту Global Flags и для заданного процесса поставить одну галочку. Короче, google for "page heap".
Спасибо. Утилиту нашёл, подсунул в закладке Image File путь к бинарю и поставил только эту галку. Приложение стало тормозить еще больше, но к сожалению место где портят память не показывает.
Кстати что за галка Enable Application Verifier? Не понял зачем, если appverif рабоает и без этого.
Правильно ли я понимаю что оно как Application Verifier должно в случае обнаружения такого места сгенерировать int 3 и оставноиться отладчике?
Ещё вопрос по appverif, я где то читал, что утилита работает следующим образом, на каждое выделение памяти запомнинает текущий стек приложения.
Но мне то в принципе стек не нужен, я и так знаю где память выделялась (написал специальный класс + макросы для отслеживания этого дела), но просто интересно.
Фигня в том что выделения и освобождения памяти очень много, буквально счёт идёт на тысячи, отследить это руками я пока не представляю как.
Пока благодаря моим спец. классам я знаю только что размер выделенного блока, (когда на free происходит ругань от appverif) один и тот же.
T>А мемори брейкпоинт на этот адрес памяти не поможет? Будет видно кто меняет. T>Правда работает если все детерменированно и в одном и том же месте проблема происходит.
Было бы очень просто, но увы это не всгда один и тот же адрес и тем более на одно и то же по счёту выделение/освобождение памяти.