RPRIVATE RVOID mem_find_handle ( rpcm_tag eventType, rSequence event ) { RPNCHAR needle = NULL; rList handleList; UNREFERENCED_PARAMETER( eventType ); if( rpal_memory_isValid( event ) ) { if( rSequence_getSTRINGN( event, RP_TAGS_HANDLE_NAME, &needle ) ) { rSequence_unTaintRead( event ); if( NULL != ( handleList = processLib_getHandles( 0, TRUE, needle ) ) ) { if( !rSequence_addLIST( event, RP_TAGS_HANDLES, handleList ) ) { rList_free( handleList ); } } else { rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() ); rpal_debug_error( "failed to get handles for pid 0x%x.", 0 ); } } hbs_timestampEvent( event, 0 ); hbs_publish( RP_TAGS_NOTIFICATION_MEM_FIND_HANDLE_REP, event ); } }
static RVOID processFile ( rSequence notif ) { RPCHAR fileA = NULL; RPWCHAR fileW = NULL; RPU8 fileContent = NULL; RU32 fileSize = 0; CryptoLib_Hash hash = { 0 }; if( NULL != notif ) { obsLib_resetSearchState( matcherA ); obsLib_resetSearchState( matcherW ); if( ( rSequence_getSTRINGA( notif, RP_TAGS_FILE_PATH, &fileA ) && obsLib_setTargetBuffer( matcherA, fileA, ( rpal_string_strlen( fileA ) + 1 ) * sizeof( RCHAR ) ) && obsLib_nextHit( matcherA, NULL, NULL ) ) || ( rSequence_getSTRINGW( notif, RP_TAGS_FILE_PATH, &fileW ) && obsLib_setTargetBuffer( matcherW, fileW, ( rpal_string_strlenw( fileW ) + 1 ) * sizeof( RWCHAR ) ) && obsLib_nextHit( matcherW, NULL, NULL ) ) ) { // This means it's a file of interest. if( ( NULL != fileA && ( ( DOCUMENT_MAX_SIZE >= rpal_file_getSize( fileA, TRUE ) && rpal_file_read( fileA, (RPVOID*)&fileContent, &fileSize, TRUE ) && CryptoLib_hash( fileContent, fileSize, &hash ) ) || CryptoLib_hashFileA( fileA, &hash, TRUE ) ) ) || ( NULL != fileW && ( ( DOCUMENT_MAX_SIZE >= rpal_file_getSizew( fileW, TRUE ) && rpal_file_readw( fileW, (RPVOID*)&fileContent, &fileSize, TRUE ) && CryptoLib_hash( fileContent, fileSize, &hash ) ) || CryptoLib_hashFileW( fileW, &hash, TRUE ) ) ) ) { // We acquired the hash, either by reading the entire file in memory // which we will use for caching, or if it was too big by hashing it // sequentially on disk. rSequence_unTaintRead( notif ); rSequence_addBUFFER( notif, RP_TAGS_HASH, (RPU8)&hash, sizeof( hash ) ); notifications_publish( RP_TAGS_NOTIFICATION_NEW_DOCUMENT, notif ); } if( rMutex_lock( cacheMutex ) ) { if( NULL == fileContent || !rSequence_addBUFFER( notif, RP_TAGS_FILE_CONTENT, fileContent, fileSize ) || !HbsRingBuffer_add( documentCache, notif ) ) { rSequence_free( notif ); } rMutex_unlock( cacheMutex ); } else { rSequence_free( notif ); } if( NULL != fileContent ) { rpal_memory_free( fileContent ); } } else { rSequence_free( notif ); } } }
static RVOID processHashedEvent ( rpcm_tag notifType, rSequence event ) { RPWCHAR nameW = NULL; RPCHAR nameA = NULL; CryptoLib_Hash* pHash = NULL; CryptoLib_Hash localHash = { 0 }; UNREFERENCED_PARAMETER( notifType ); if( rpal_memory_isValid( event ) ) { if( rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &nameA ) || rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &nameW ) || rSequence_getSTRINGA( event, RP_TAGS_DLL, &nameA ) || rSequence_getSTRINGW( event, RP_TAGS_DLL, &nameW ) || rSequence_getSTRINGA( event, RP_TAGS_EXECUTABLE, &nameA ) || rSequence_getSTRINGW( event, RP_TAGS_EXECUTABLE, &nameW ) ) { rSequence_getBUFFER( event, RP_TAGS_HASH, (RPU8*)&pHash, NULL ); if( NULL != nameA ) { if( NULL == pHash ) { if( _MAX_FILE_HASH_SIZE < rpal_file_getSize( nameA, TRUE ) ) { rSequence_unTaintRead( event ); rSequence_addRU32( event, RP_TAGS_ERROR, RPAL_ERROR_FILE_TOO_LARGE ); if( rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &nameA ) || rSequence_getSTRINGA( event, RP_TAGS_DLL, &nameA ) || rSequence_getSTRINGA( event, RP_TAGS_EXECUTABLE, &nameA ) ) { // Find the name again with shortcircuit } } else if( CryptoLib_hashFileA( nameA, &localHash, TRUE ) ) { pHash = &localHash; } } processCodeIdentA( nameA, pHash, 0, event ); } else if( NULL != nameW ) { if( NULL == pHash ) { if( _MAX_FILE_HASH_SIZE < rpal_file_getSizew( nameW, TRUE ) ) { rSequence_unTaintRead( event ); rSequence_addRU32( event, RP_TAGS_ERROR, RPAL_ERROR_FILE_TOO_LARGE ); if( rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &nameW ) || rSequence_getSTRINGW( event, RP_TAGS_DLL, &nameW ) || rSequence_getSTRINGW( event, RP_TAGS_EXECUTABLE, &nameW ) ) { // Find the name again with shortcircuit } } else if( CryptoLib_hashFileW( nameW, &localHash, TRUE ) ) { pHash = &localHash; } } processCodeIdentW( nameW, pHash, 0, event ); } } } }
RPRIVATE RVOID mem_map ( rpcm_tag eventType, rSequence event ) { RU32 pid; rList memMapList = NULL; rList modulesList = NULL; rSequence modEntry = NULL; rSequence memEntry = NULL; RPNCHAR tmpModName = NULL; RPNCHAR tmpModPath = NULL; RU64 memStart = 0; RU64 memSize = 0; RU64 modStart = 0; RU64 modSize = 0; RPU8 atom = NULL; RU32 atomSize = 0; UNREFERENCED_PARAMETER( eventType ); if( rpal_memory_isValid( event ) ) { if( rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) || ( rSequence_getBUFFER( event, RP_TAGS_HBS_THIS_ATOM, &atom, &atomSize ) && HBS_ATOM_ID_SIZE == atomSize && 0 != ( pid = atoms_getPid( atom ) ) ) ) { if( NULL != ( memMapList = processLib_getProcessMemoryMap( pid ) ) ) { // Try to enhance the raw map if( NULL != ( modulesList = processLib_getProcessModules( pid ) ) ) { // Looking for memory pages within the known module rList_resetIterator( memMapList ); while( rList_getSEQUENCE( memMapList, RP_TAGS_MEMORY_REGION, &memEntry ) ) { if( rSequence_getPOINTER64( memEntry, RP_TAGS_BASE_ADDRESS, &memStart ) && rSequence_getRU64( memEntry, RP_TAGS_MEMORY_SIZE, &memSize ) ) { tmpModName = NULL; tmpModPath = NULL; rList_resetIterator( modulesList ); while( rList_getSEQUENCE( modulesList, RP_TAGS_DLL, &modEntry ) ) { if( rSequence_getPOINTER64( modEntry, RP_TAGS_BASE_ADDRESS, &modStart ) && rSequence_getRU64( modEntry, RP_TAGS_MEMORY_SIZE, &modSize ) ) { if( memStart >= modStart && memStart <= ( modStart + modSize ) ) { // Match, we get just the basic info rSequence_getSTRINGN( modEntry, RP_TAGS_MODULE_NAME, &tmpModName ); rSequence_getSTRINGN( modEntry, RP_TAGS_FILE_PATH, &tmpModPath ); break; } } else { break; } } // I can assert that the strings read from the memEntry WILL NOT be used // hereon since doing so would be dangerous as I am about to modify // the memEntry sequence after the read and therefore those pointers // may not be good anymore after this point. rSequence_unTaintRead( memEntry ); if( NULL != tmpModName ) { rSequence_addSTRINGN( memEntry, RP_TAGS_MODULE_NAME, tmpModName ); } if( NULL != tmpModPath ) { rSequence_addSTRINGN( memEntry, RP_TAGS_FILE_PATH, tmpModPath ); } } } rList_resetIterator( memMapList ); rList_free( modulesList ); } if( !rSequence_addLIST( event, RP_TAGS_MEMORY_MAP, memMapList ) ) { rList_free( memMapList ); } } else { rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() ); } } } hbs_timestampEvent( event, 0 ); hbs_publish( RP_TAGS_NOTIFICATION_MEM_MAP_REP, event ); }
static RVOID processNewModule ( rpcm_tag notifType, rSequence event ) { RPWCHAR nameW = NULL; RPCHAR nameA = NULL; CryptoLib_Hash fileHash = { 0 }; RU64 size = 0; UNREFERENCED_PARAMETER( notifType ); if( rpal_memory_isValid( event ) ) { if( rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &nameA ) || rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &nameW ) ) { if( ( NULL != nameA && _MAX_FILE_HASH_SIZE < rpal_file_getSize( nameA, TRUE ) ) || ( NULL != nameW && _MAX_FILE_HASH_SIZE < rpal_file_getSizew( nameW, TRUE ) ) ) { // We already read from the event, but we will be careful. rSequence_unTaintRead( event ); rSequence_addRU32( event, RP_TAGS_ERROR, RPAL_ERROR_FILE_TOO_LARGE ); // We need to re-get the paths in case adding the error triggered // a change in the structure. if( rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &nameA ) || rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &nameW ) ) { // Find the name again with shortcircuit } } else { if( NULL != nameA && !CryptoLib_hashFileA( nameA, &fileHash, TRUE ) ) { rpal_debug_info( "unable to fetch file hash for ident" ); } if( NULL != nameW && !CryptoLib_hashFileW( nameW, &fileHash, TRUE ) ) { rpal_debug_info( "unable to fetch file hash for ident" ); } } rSequence_getRU64( event, RP_TAGS_MEMORY_SIZE, &size ); if( NULL != nameA ) { processCodeIdentA( nameA, &fileHash, size, event ); } else if( NULL != nameW ) { processCodeIdentW( nameW, &fileHash, size, event ); } } } }