Утечка памяти при проверке подписи Authenticode исполняемых файлов?
Я использую WinVerifyTrust для проверки правильности некоторых исполняемых файлов Windows с помощью следующей функции, вызываемой в цикле из _tmain
:
int signature_is_valid(const wchar_t *filepath) {
GUID guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_FILE_INFO file_info = { 0 };
WINTRUST_DATA wd;
file_info.cbStruct = sizeof(file_info);
file_info.pcwszFilePath = filepath;
file_info.hFile = NULL;
file_info.pgKnownSubject = NULL;
ZeroMemory(&wd, sizeof(wd));
wd.cbStruct = sizeof(wd);
wd.dwUIChoice = WTD_UI_NONE;
wd.fdwRevocationChecks = WTD_REVOCATION_CHECK_NONE;
wd.dwUnionChoice = WTD_CHOICE_FILE;
wd.dwStateAction = 0;
wd.pFile = &file_info;
wd.dwProvFlags = WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | WTD_CACHE_ONLY_URL_RETRIEVAL;
return 0 == WinVerifyTrust(NULL, &guid, &wd);
}
Однако с каждым циклом память продолжает расти, что является верным признаком утечки памяти.
Есть ли проблема с моим пониманием API
или это WinVerifyTrust
функция на самом деле утечка? Я проверяю это на Windows XP Professional SP3
система.
РЕДАКТИРОВАТЬ:
Вот некоторые результаты umdh
:
+ 16812 ( 16992 - 180) 472 allocs BackTraceAD1
+ 467 ( 472 - 5) BackTraceAD1 allocations
ntdll!RtlDebugAllocateHeap+000000E1
ntdll!RtlAllocateHeapSlowly+00000044
ntdll!RtlAllocateHeap+00000E64
kernel32!LocalAlloc+00000058
CRYPT32!operator new+00000011
CRYPT32!I_CryptCreateLruEntry+00000011
CRYPT32!CreateAuthRootAutoUpdateMatchCaches+00000107
CRYPT32!CCertChainEngine::FindAuthRootAutoUpdateMatchingCtlEntries+0000004D
CRYPT32!CChainPathObject::GetAuthRootAutoUpdateUrlStore+000000C9
CRYPT32!CChainPathObject::CChainPathObject+0000030E
CRYPT32!ChainCreatePathObject+00000050
CRYPT32!CCertIssuerList::AddIssuer+0000006A
CRYPT32!CChainPathObject::FindAndAddIssuersFromStoreByMatchType+00000182
CRYPT32!CChainPathObject::FindAndAddIssuersByMatchType+00000096
CRYPT32!CChainPathObject::FindAndAddIssuers+00000023
CRYPT32!CChainPathObject::CChainPathObject+000001F9
CRYPT32!ChainCreatePathObject+00000050
CRYPT32!CCertIssuerList::AddIssuer+0000006A
CRYPT32!CChainPathObject::FindAndAddIssuersFromCacheByMatchType+00000084
CRYPT32!CChainPathObject::FindAndAddIssuersByMatchType+00000023
CRYPT32!CChainPathObject::FindAndAddIssuers+00000063
CRYPT32!CChainPathObject::CChainPathObject+000001F9
CRYPT32!ChainCreatePathObject+00000050
CRYPT32!CCertChainEngine::CreateChainContextFromPathGraph+0000019E
CRYPT32!CCertChainEngine::GetChainContext+00000044
CRYPT32!CertGetCertificateChain+00000060
WINTRUST!_WalkChain+0000019C
WINTRUST!WintrustCertificateTrust+000000B7
WINTRUST!_VerifyTrust+00000144
WINTRUST!WinVerifyTrust+0000004E
SigTest!signature_is_valid+000000DD
+ 10984 ( 10984 - 0) 2 allocs BackTraceBB3
+ 2 ( 2 - 0) BackTraceBB3 allocations
ntdll!RtlDebugAllocateHeap+000000E1
ntdll!RtlAllocateHeapSlowly+00000044
ntdll!RtlAllocateHeap+00000E64
kernel32!LocalAlloc+00000058
CRYPT32!PkiDefaultCryptAlloc+00000011
CRYPT32!CertFindCertificateInCRL+00000051
cryptnet!MicrosoftCertDllVerifyRevocation+00000250
CRYPT32!I_CryptRemainingMilliseconds+0000021B
CRYPT32!CertVerifyRevocation+000000B7
CRYPT32!CChainPathObject::CalculateRevocationStatus+000001F2
CRYPT32!CChainPathObject::CalculateAdditionalStatus+00000147
CRYPT32!CCertChainEngine::CreateChainContextFromPathGraph+00000227
CRYPT32!CCertChainEngine::GetChainContext+00000044
CRYPT32!CertGetCertificateChain+00000060
WINTRUST!_WalkChain+0000019C
WINTRUST!WintrustCertificateTrust+000000B7
WINTRUST!_VerifyTrust+00000144
WINTRUST!WinVerifyTrust+0000004E
SigTest!signature_is_valid+000000DD
SigTest!wmain+00000073
SigTest!__tmainCRTStartup+000001A8
SigTest!wmainCRTStartup+0000000F
kernel32!BaseProcessStart+00000023
Мне кажется, что CRYPT32
утечки функций... или я что-то упускаю.
EDIT2
Вот эволюция памяти для нескольких тысяч циклов:
4 ответа
Я не вижу никакой информации о том, что этот API пропускает. возможно это просто фрагментация кучи в процессе?
Вы можете убедиться в этом, используя umdh, чтобы сделать снимки вашего процесса в моменты времени X и X+delta, а затем проанализировать сравнительное использование кучи в это время. Убедитесь, что все символы доступны для того, чтобы это было наиболее полезным.
Согласно MSDN документации WINTRUST_DATA, WTD_CACHE_ONLY_URL_RETRIEVAL не поддерживается в Windows XP или Windows 2000. Я сомневаюсь, что это как-то связано с явной утечкой, но подумал, что на это стоит обратить внимание.
(Изменить: Глядя на новые графики, я был не прав.)
Основываясь на "I_CryptCreateLruEntry" в стеке вызовов, я предполагаю, что это не утечка памяти; это всего лишь кеширование данных API в ограниченном виде. т.е. не будет расти бесконечно.
LRU с этим именем предполагает, что он хранит полученный сертификат в кэше с наименьшим недавним использованием, чтобы ускорить последующие операции, которые могут включать тот же сертификат.
Если вы запустите код в цикле и обнаружите, что он использует несколько мегабайт и продолжает расти после многих итераций, то, возможно, есть утечка или очень плохо настроенный алгоритм кэширования, но в противном случае я бы сказал, что вам не о чем беспокоиться.
ДА. Если у вас достаточно низкая версия файла crypt32.dll, это очень раздражает утечка памяти.
и установите исправление KB2641690 для исправления