static RVOID processCodeIdentW ( RPWCHAR name, RPU8 pFileHash, RU64 codeSize, rSequence originalEvent ) { CodeIdent ident = { 0 }; rSequence notif = NULL; ident.codeSize = codeSize; if( NULL != name ) { CryptoLib_hash( name, rpal_string_strlenw( name ) * sizeof( RWCHAR ), ident.nameHash ); } if( NULL != pFileHash ) { rpal_memory_memcpy( ident.fileHash, pFileHash, CRYPTOLIB_HASH_SIZE ); } if( rpal_bloom_addIfNew( knownCode, &ident, sizeof( ident ) ) ) { if( NULL != ( notif = rSequence_new() ) ) { hbs_markAsRelated( originalEvent, notif ); if( rSequence_addSTRINGW( notif, RP_TAGS_FILE_PATH, name ) && rSequence_addBUFFER( notif, RP_TAGS_HASH, pFileHash, CRYPTOLIB_HASH_SIZE ) && rSequence_addRU32( notif, RP_TAGS_MEMORY_SIZE, (RU32)codeSize ) && rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) ) { notifications_publish( RP_TAGS_NOTIFICATION_CODE_IDENTITY, notif ); } rSequence_free( notif ); } } }
static RPVOID dnsDiffThread ( rEvent isTimeToStop, RPVOID ctx ) { RU32 nThLoop = 0; RU32 currentTimeout = 0; rSequence notif = NULL; rBlob snapCur = NULL; rBlob snapPrev = NULL; _dnsRecord rec = { 0 }; _dnsRecord* pCurRec = NULL; _dnsRecord* pPrevRec = NULL; RU32 i = 0; RU32 j = 0; RBOOL isNew = FALSE; #ifdef RPAL_PLATFORM_WINDOWS PDNSCACHEENTRY pDnsEntry = NULL; PDNSCACHEENTRY pPrevDnsEntry = NULL; #endif UNREFERENCED_PARAMETER( ctx ); while( !rEvent_wait( isTimeToStop, currentTimeout ) ) { if( NULL != ( snapCur = rpal_blob_create( 0, 10 * sizeof( rec ) ) ) ) { #ifdef RPAL_PLATFORM_WINDOWS if( TRUE == getCache( &pDnsEntry ) ) { while( NULL != pDnsEntry ) { rec.flags = pDnsEntry->dwFlags; rec.type = pDnsEntry->wType; if( NULL != ( rec.name = rpal_string_strdupw( pDnsEntry->pszName ) ) ) { rpal_blob_add( snapCur, &rec, sizeof( rec ) ); } pPrevDnsEntry = pDnsEntry; pDnsEntry = pDnsEntry->pNext; freeCacheEntry( pPrevDnsEntry->pszName, DnsFreeFlat ); freeCacheEntry( pPrevDnsEntry, DnsFreeFlat ); } } #endif // Do a general diff of the snapshots to find new entries. if( NULL != snapPrev ) { i = 0; while( NULL != ( pCurRec = rpal_blob_arrElem( snapCur, sizeof( rec ), i++ ) ) ) { isNew = TRUE; j = 0; while( NULL != ( pPrevRec = rpal_blob_arrElem( snapPrev, sizeof( rec ), j++ ) ) ) { if( pCurRec->flags == pPrevRec->flags && pCurRec->type == pPrevRec->type && 0 == rpal_string_strcmpw( pCurRec->name, pPrevRec->name ) ) { isNew = FALSE; break; } } if( isNew && !rEvent_wait( isTimeToStop, 0 ) ) { if( NULL != ( notif = rSequence_new() ) ) { rSequence_addSTRINGW( notif, RP_TAGS_DOMAIN_NAME, pCurRec->name ); rSequence_addRU16( notif, RP_TAGS_DNS_TYPE, pCurRec->type ); rSequence_addRU32( notif, RP_TAGS_DNS_FLAGS, pCurRec->flags ); rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ); notifications_publish( RP_TAGS_NOTIFICATION_DNS_REQUEST, notif ); rSequence_free( notif ); } } } } } if( NULL != snapPrev ) { _freeRecords( snapPrev ); rpal_blob_free( snapPrev ); snapPrev = NULL; } snapPrev = snapCur; snapCur = NULL; nThLoop++; if( 0 == nThLoop % 20 ) { currentTimeout = libOs_getUsageProportionalTimeout( MSEC_FROM_SEC( 10 ) ) + MSEC_FROM_SEC( 5 ); } rpal_thread_sleep( currentTimeout ); } if( NULL != snapPrev ) { _freeRecords( snapPrev ); rpal_blob_free( snapPrev ); snapPrev = NULL; } return NULL; }
RPRIVATE RVOID _searchForStrings ( rList stringsFound, rList searchStrings, RPU8 pBuff, RU64 size, RU64 baseAddr, RU32 minLength, RU32 maxLength ) { RPU8 pCurr; RPU8 pEnd; RPCHAR pStartStr = NULL; RBOOL isChar; RPU16 pwCurr; RPU16 pwEnd; RBOOL isWChar; RPWCHAR pwStartStr = NULL; RPWCHAR thisStrW = NULL; rSequence newFoundStr; pCurr = pBuff; pEnd = pBuff + size; // currently we only deal with NULL terminated strings // start with ascii strings... while( pCurr < pEnd ) { isChar = rpal_string_isprint( *pCurr ); if( NULL == pStartStr && isChar ) // found the begining of a string { pStartStr = (RPCHAR)pCurr; } else if( NULL != pStartStr && ( !isChar || 0 == *pCurr ) ) // found the end of a string { // is string NULL or Non-Ascii terminated if( 0 == *pCurr || !rpal_string_charIsAscii( *pCurr ) ) { // Null terminate it so we can use it like a normal string *pCurr = 0; // strlen is really pCurr - pStartStr if( (RU32)( (RPCHAR)pCurr - pStartStr ) >= minLength && (RU32)( (RPCHAR)pCurr - pStartStr ) <= maxLength ) // is string long enough { // convert string to wide char for comparision if( NULL != ( thisStrW = rpal_string_atow( pStartStr ) ) ) { if( _isStringInList( searchStrings, thisStrW ) && NULL != ( newFoundStr = rSequence_new() ) ) { rSequence_addSTRINGW( newFoundStr, RP_TAGS_STRING, thisStrW ); rSequence_addRU64( newFoundStr, RP_TAGS_MEMORY_ADDRESS, baseAddr + ( (RPU8)pStartStr - pBuff ) ); if( !rList_addSEQUENCE( stringsFound, newFoundStr ) ) { rSequence_free( newFoundStr ); } } rpal_memory_free( thisStrW ); } } } pStartStr = NULL; } pCurr++; } // Now look for Unicode strings pwCurr = (RPU16)pBuff; pwEnd = pwCurr + ( size / 2 ); while( pwCurr < pwEnd ) { isWChar = rpal_string_isprintW( *pwCurr ); if( NULL == pwStartStr && isWChar ) // found the begining of a string { pwStartStr = (RPWCHAR)pwCurr; } else if( NULL != pwStartStr && ( !isWChar || 0 == *pwCurr ) ) // found the end of a string { // is string NULL terminated if( 0 == *pwCurr ) { // wcslen is really pCurr - pStartStr if( (RU32)( (RPWCHAR)pwCurr - pwStartStr ) >= minLength && (RU32)( (RPWCHAR)pwCurr - pwStartStr ) <= maxLength ) // is string long enough { if( _isStringInList( searchStrings, pwStartStr ) && NULL != ( newFoundStr = rSequence_new() ) ) { rSequence_addSTRINGW( newFoundStr, RP_TAGS_STRING, pwStartStr ); rSequence_addRU64( newFoundStr, RP_TAGS_MEMORY_ADDRESS, baseAddr + ( (RPU8)pwStartStr - pBuff ) ); if( !rList_addSEQUENCE( stringsFound, newFoundStr ) ) { rSequence_free( newFoundStr ); } } } } pwStartStr = NULL; } pwCurr++; } }
static RVOID processCodeIdentW ( RPWCHAR name, CryptoLib_Hash* pFileHash, RU64 codeSize, rSequence originalEvent ) { CodeIdent ident = { 0 }; rSequence notif = NULL; rSequence sig = NULL; RBOOL isSigned = FALSE; RBOOL isVerifiedLocal = FALSE; RBOOL isVerifiedGlobal = FALSE; ident.codeSize = codeSize; if( NULL != name ) { CryptoLib_hash( name, rpal_string_strlenw( name ) * sizeof( RWCHAR ), &ident.nameHash ); } if( NULL != pFileHash ) { rpal_memory_memcpy( &ident.fileHash, pFileHash, sizeof( *pFileHash ) ); } if( rMutex_lock( g_mutex ) ) { if( rpal_bloom_addIfNew( g_knownCode, &ident, sizeof( ident ) ) ) { rMutex_unlock( g_mutex ); if( NULL != ( notif = rSequence_new() ) ) { hbs_markAsRelated( originalEvent, notif ); if( ( rSequence_addSTRINGW( notif, RP_TAGS_FILE_PATH, name ) || rSequence_addSTRINGW( notif, RP_TAGS_DLL, name ) || rSequence_addSTRINGW( notif, RP_TAGS_EXECUTABLE, name ) ) && rSequence_addRU32( notif, RP_TAGS_MEMORY_SIZE, (RU32)codeSize ) && rSequence_addTIMESTAMP( notif, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ) ) { if( NULL != pFileHash ) { rSequence_addBUFFER( notif, RP_TAGS_HASH, (RPU8)pFileHash, sizeof( *pFileHash ) ); } if( libOs_getSignature( name, &sig, ( OSLIB_SIGNCHECK_NO_NETWORK | OSLIB_SIGNCHECK_CHAIN_VERIFICATION ), &isSigned, &isVerifiedLocal, &isVerifiedGlobal ) ) { if( !rSequence_addSEQUENCE( notif, RP_TAGS_SIGNATURE, sig ) ) { rSequence_free( sig ); } } notifications_publish( RP_TAGS_NOTIFICATION_CODE_IDENTITY, notif ); } rSequence_free( notif ); } } else { rMutex_unlock( g_mutex ); } } }