ZLIB на Windows: gzopen/gzwrite/gzclose създава кастриран изходен файл / грешка на антивирусната програма?

От дни преследвам много мистериозна грешка, която изглежда се върти около (ZLIB библиотека); случва се веднъж на месец или така и само в някои специфични производствени среди. Ето какво прави кодът:

  1. Програмата извиква gzopen, за да запише във файл X.
  2. Програмата записва данни във файла, като прави няколко gzwrite.
  3. Програмата най-накрая извиква gzclose, което изчиства файла.

Обикновено всичко работи добре и файлът X е валиден; той е правилно прекратен с CRC и дължината на изходния поток.

Въпреки това, при една от грешките, наблюдавам, че X е повреден: началото на данните е правилно, но започвайки от отместване 0x00302000, всеки байт е нулев. Дори последните осем байта, които кодират CRC и дължината, са нула. Файлът обаче е с правилния размер! И което е по-лошо: същата система успешно компресира много подобен файл няколко минути по-рано.

Забележка: ZLIB.DLL, който използваме, има версия 1.1.3; да, знам, съдържа някои дупки в сигурността и трябва да надстроим до най-новата ZLIB 1.2.3, но не искам да променям нищо в настройката си, докато не открия причината за нулирането.

Мисля, че съм изключил повреда на паметта (между другото, как би могъл повреден обем на паметта да наруши fwrite достатъчно, че да записва само нули в изходния поток? би ли било това правдоподобно?), цикълът, който отваря/записва/затваря потокът е прост и не разкрива никакви дефекти, които мога да забележа, кодът не разпределя/освобождава/бърка със структури в ZLIB (което може да е проблем, тъй като ZLIB е свързан с друга C библиотека, различна от DLL на моите приложения), така че мога подозират само други елементи в системата.

По някакъв начин съм склонен да имам доверие в C библиотеката (CRTDLL.DLL), Win32 API, NTFS стека, I/O стека, драйверите на устройства от ниско ниво, фърмуера на твърдите дискове и самия твърд диск... И да, аз също съм склонен да вярвам, че Visual C++ 2008 създава правилни двоични файлове, поне в този случай ;-)

И така, прав ли съм да подозирам, че антивирусният софтуер може да е виновникът? Трябва да се внимава със ZLIB, тъй като поне Kaspersky разпознава DLL като възможна заплаха. Но ще бъде ли политически коректно антивирусната програма просто да напише нули вместо данните, ако инфекцията бъде забелязана (неправилно)? Или това може да е грешка в антивирусната?

Или напълно пропускам смисъла?


person Pierre Arnaud    schedule 02.06.2009    source източник


Отговори (1)


Без да знам нищо друго, бих подозирал по-скоро вашия код, отколкото антивирусния код.

Ще е необходима проста грешка, за да се запише правилната дължина на данните във файла, но да се подаде неправилен буфер, което води до „всички нули“ като данни във файла.

Простите грешки, които са трудни за забелязване, понякога водят до много голямо объркване, каквото имате при вас.

Ако отстранявах това, бих:

  • опростявам опростявам опростявам, докато проблемът не спря. след това добавете сложност обратно, постепенно.
  • проверете указателите си и аритметиката на указателя
  • проверете дали изтривате и затваряте файла правилно
  • използвайте разпределител, който съхранява маркерни байтове в разпределените буфери, като 0xAA, а не 0x00. По този начин можете да видите дали вашият (нулиран) буфер се записва във файла.
  • преминете през всичко това в програма за отстраняване на грешки

При нормални обстоятелства GZIP данните никога няма да имат дълга последователност от нули. Те ще бъдат свити в речник и код за дължина.

person Cheeso    schedule 02.06.2009
comment
Благодаря за съветите. Мисля, че проверих отново всичко, но вие сте прав, трябва да сменя разпределителя на паметта, за да се уверя, след това няколко седмици, за да видя дали проблемът се появява отново в производството... Също така забелязах, че обикновен файл копиране (fopen A/fopen B/fread A/fwrite B/fclose A/fclose B) генерира файл B с подходящ размер, но само нули в него; но това се случва само след като се случи гореописаният проблем. - person Pierre Arnaud; 03.06.2009