298991 string in log ! lets write quick and ditry perl script to calculate sizes of leaked blocks:
my $state = 0; my($str, %dict, $size); while( $str = <> ) { chomp $str; last if ( $str eq '' ); if ( ! $state ) { $state = 1 if ( $str =~ /^-----/ ); next; } $str = substr($str, 72, 10); $str =~ s/^\s+//g; $str =~ s/\s+$//g; $size = hex($str); next if ( !$size ); $dict{$size} += 1; } # dump results my $iter; foreach $iter ( sort { $dict{$b} <=> $dict{$a} } keys %dict ) { printf("%X %d\n", $iter, $dict{$iter}); }results are encouraging:
A0 80659
4D0 80596
20 54034
10 53737
it seems that we have pairs of leaked objects with size 0xa0 and 0x4d0. with my partial structs matcher we can find two appropriate candidates - WTSINFOA (size 0x90) and WTSCLIENTA (size 0x4b0). Also can check in IDA content of some blocks - yep, almost certainly they are our found structs.
Qiuck search in source code gives only place where WTSINFOA used - function genLoggedInUsers:
PWTS_SESSION_INFO_1 pSessionInfo;
unsigned long count;
unsigned long level = 1;
auto res = WTSEnumerateSessionsEx(
WTS_CURRENT_SERVER_HANDLE, &level, 0, &pSessionInfo, &count);
for (size_t i = 0; i < count; i++) {
Row r;
char* sessionInfo = nullptr;
unsigned long bytesRet = 0;
res = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
pSessionInfo[i].SessionId,
WTSSessionInfo,
&sessionInfo,
&bytesRet);
...
auto wtsSession = (PWTSINFO)sessionInfo;
...
if (clientInfo != nullptr) {
WTSFreeMemoryEx(WTSTypeSessionInfoLevel1, clientInfo, count);
clientInfo = nullptr;
}
if (sessionInfo != nullptr) {
WTSFreeMemoryEx(WTSTypeSessionInfoLevel1, sessionInfo, count);
sessionInfo = nullptr;
}
}
all seems fine - memory allocated in WTSQuerySessionInformation and free at end of cycle. Can you guess what wrong here ? ok, I could not too
So finally rtfm:
To free the returned buffer, call the WTSFreeMemory function
Yep, this memory leak caused wrong using of windows API functions. Interesting would find this bug existing code analyzers like pvs studio or coverity ?
You mean they used WTSFreeMemoryEx instead of WTSFreeMemory?
ОтветитьУдалитьyes
ОтветитьУдалить