Утечка памяти при проверке подписи Authenticode исполняемых файлов? - PullRequest
4 голосов
/ 01 ноября 2010

Я использую 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

Вот эволюция памяти для некоторых тысячпетли: alt text

Ответы [ 4 ]

0 голосов
/ 15 ноября 2012

YES.Если у вас достаточно низкая версия файла crypt32.dll, это очень раздражающая утечка памяти.

см. http://social.technet.microsoft.com/Forums/en-US/itproxpsp/thread/c11530e8-56e2-4bb3-a887-f7809e644861

и установите исправление KB2641690 для исправления

0 голосов
/ 26 ноября 2010

(Правка: глядя на новые графики, я ошибся.)

Основываясь на "I_CryptCreateLruEntry" в стеке вызовов, я предполагаю, что это не утечка памяти;это просто API-интерфейс кеширования данных в ограниченной форме.то есть он не будет расти бесконечно.

LRU с этим именем предполагает сохранение сертификата, полученного в наименее недавно использованном кэше , чтобы ускорить последующие операции, в которых может использоваться тот же сертификат..

Если вы запускаете код в цикле и обнаруживаете, что он использует несколько мегабайт и продолжает расти после многих итераций, то, возможно, есть утечка или очень плохо настроенный алгоритм кэширования, но в противном случае я бы сказал, что вывероятно, не о чем беспокоиться.

0 голосов
/ 23 мая 2012

Согласно документации MSDN для WINTRUST_DATA , WTD_CACHE_ONLY_URL_RETRIEVAL не поддерживается в Windows XP или Windows 2000. Я сомневаюсь, что это имеет какое-либо отношение к явной утечке, но подумал, что на это стоит обратить внимание.

0 голосов
/ 01 ноября 2010

Я не вижу никакой информации о том, что этот API пропускает. возможно это просто фрагментация кучи в процессе?

Вы можете убедиться в этом, используя umdh , чтобы сделать снимки вашего процесса во время X и дельта X +, а затем проанализировать сравнительное использование кучи в это время. Убедитесь, что все символы доступны для того, чтобы это было наиболее полезным.

...