neutronion а как адресуются страницы? что это вообще такое? а для такого стека call VirtualAlloc mov [Esp_store], esp lea esp, [eax + this_block_len] ? в этом есть смысл. зачем давать юным и горячим закрытые структуры и неописанные поля? чтоб лепили куда можно и куда нельзя, бо это круто? и в при следующей итерации выни куча программ перестала работать или заглючила в самых неожиданных местах? для вирусов это не критично, тк срок жизни виря/троя редко превышает 3 месяца. а о глючности требований к нему почти не стоит.
я даже не знаю зачем вы мне доказываете свой способ с метками. ну, используйте если так хотите. я свое мнение сказал, а как поступите вы: через метки, образ, тиб или еще как - дело ваше. вот еще маленький пример распространенной ошибки char* a = my_malloc(8); char* b = my_malloc(10); // допустим, они выделятся подряд sprint(a, "123456789"); // видно, что строка превышает размер буфера a и затирает метку в начале буфера b. // в хип менеджерах основанных на метках это частая причина нарушений в работе хипа и утчек памяти
Ну так замечательно! Таким образом схема с метками как в вышеприведенном способе, будет решать еще одну задачу! После того как мы, что либо пишем в буфер, мы теперь можем проверить не произошло ли переполнение буфера проверив метку, как в этом случае. Значит теперь метка служит уже 2 целям: 1 - контроль переполнения буферов 2 - контроль утечек. Не здорово ли? вот вариант с меткой Код (Text): char* a = (char *)malloc(8+4); memset(a+8,'a',4); char* b = (char *)malloc(10); // допустим, они выделятся подряд sprintf(a, "123456789"); if(memcmp(a+8,"aaaa",4)) { /// ПЕРЕПОЛНЕНИЕ БУФЕРА БОЛЬШАЯ ОШИБКА!!! return 0; } Два джина в одном флаконе!
даже подряд идущие маллоки не гарантируют, что эти области будут идти подряд или что между них не будет других областей или разрывов в выделенной памяти. даже то не гарантируется, что более поздний маллок выделится по более старшим адресам. вы после каждой операции над буферами или вызова каждой функции делать кучу проверок? есть специальные инструменты для этого. в том числе и опенсорсные. можете почитать сорцы их ---- я не знаю для чего вы так доказываете свою мысль. писать/отлаживать/сдавать вашу прогу не мне. если вы делаете по этому вопросу рос, то доказывание мне - это не рос. я не ваш заказчик, веса мое мнение для вашего заказчика не имеет. не вижу причин для подобных доказательств.
Причем здесь, когда и где вызывается маллок? На вышеописанный код это никак не повлияет. Как проводилась проверка целостности на переполнение и проверку на удаление из хипа, так и будет, из за разной последовательности вызовов маллока и нахождения указателей на данные, проверки как работали так и будут работать корректно . Код при тестировании обязательно должен проходить необходимые многочисленные проверки в дебажной версии. В релизе это можно убрать.
neutronion в дебаг версии замените маллок на выделение буффера на границе страницы, а следующую делайте невалидной, и все будут счастливы)
neutronion Вот эта хреновина как-раз такое делает: http://technet.microsoft.com/en-us/library/bb457063.aspx
AsmGuru62 у меня она сделала следующее - подключенная к ней прога обычно жрущая около метра-2х озу и выполняющейся около 30 сек захватила около 2 гиг озу и через 40 минут стартования на полной загрузке проца свалилась с истошным мессаж бохом.
например так Код (Text): void* __cdecl malloc_overruntest( IN size_t Size ) { VOID* pData = NULL; if((pData = VirtualAlloc(NULL, ALIGN_UP(Size, PAGE_SIZE) + PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS))) { if((pData = VirtualAlloc(pData, ALIGN_UP(Size, PAGE_SIZE), MEM_COMMIT, PAGE_READWRITE))) { pData = (VOID*)((ULONG_PTR)pData + (ULONG_PTR)(ALIGN_UP(Size, PAGE_SIZE) - Size)); } } return pData; } void __cdecl free_overruntest( IN OUT void* pData ) { VirtualFree((VOID* )ALIGN_DOWN(pData, PAGE_SIZE), 0, MEM_RELEASE); } #ifdef _DEBUG # undef malloc # define malloc malloc_overruntest # undef free # define free free_overruntest #endif ULONG AppEntry() { CHAR* pTest = malloc(9999); pTest[9998] = '\0';// OK pTest[9999] = '\0';// Access violation writing location free(pTest); ExitProcess(ERROR_SUCCESS); } точно так же можно проверить и на ошибки buffer underrun, но неясно зачем это все если есть спец ПО типа Application Verifier и Driver Verifier которое проверяет это
Для блочного тестирования. Application Verifier предпологает, что приложение уже создано. Мне же надо просто тестировать части приложения в дебаггере. Вот этот код замечательно пока себя оправдывает ввиду своей простоты. Код (Text): _CrtMemState s1, s2, s3; void StartLeakDetection() { //s1, s2, s3; надо бы здесь их обнулить _CrtMemCheckpoint( &s1 ); } bool StopLeakDetection() { _CrtMemCheckpoint( &s2 ); if ( _CrtMemDifference( &s3, &s1, &s2) ) { //leak!!!!! return false; } return true; } void Main() { StartLeakDetection(); //здесь делаем выделения и освобождения if(true != StopLeakDetection()) { //утечка!!!! } }
это используется только для верификации, к чему ваш коментарий не ясно или вы и в продакшен версии использовать решили?
Просто ваше решение неплохое, но опять таки, оно не подходит, если память выделяется кусочками от 2 до 255 байт. Хотя, для других целей, неплохое решение. Буду иметь ввиду. У Рихтера есть подробное описание этого, что-то я упустил. Спасибо за пример.
страница не committed и исключение будет соответственно другое так что не нужно ее гардовой называть, фактически только ее описатель создается это не мое еще раз - чем не подходит?
neutronion вы хотите сделать идеальный контролер работы с памятью? почему б тогда не оттолкнуться от какой нибудь открытой либы - виртуализатора х86/х64? будете иметь контроль над каждым обращением к памяти.