static RVOID processFileIo ( rpcm_tag notifType, rSequence event ) { ProcExtInfo* ctx = NULL; RPNCHAR path = NULL; RPVOID patternCtx = 0; RU8 patternId = 0; RPU8 atomId = NULL; RU32 pid = 0; rSequence newEvent = NULL; UNREFERENCED_PARAMETER( notifType ); if( rSequence_getSTRINGN( event, RP_TAGS_FILE_PATH, &path ) && HbsGetParentAtom( event, &atomId ) && rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) ) { if( rMutex_lock( g_mutex ) ) { obsLib_resetSearchState( g_extensions ); if( obsLib_setTargetBuffer( g_extensions, path, rpal_string_strsize( path ) ) ) { while( obsLib_nextHit( g_extensions, &patternCtx, NULL ) ) { if( NULL != ctx || NULL != ( ctx = getProcContext( atomId ) ) ) { patternId = (RU8)PTR_TO_NUMBER( patternCtx ); if( !IS_FLAG_ENABLED( ctx->extBitMask, (RU64)1 << patternId ) ) { rpal_debug_info( "process " RF_U32 " observed file io " RF_U64, pid, patternId + 1 ); ENABLE_FLAG( ctx->extBitMask, (RU64)1 << patternId ); if( NULL != ( newEvent = rSequence_new() ) ) { HbsSetParentAtom( newEvent, atomId ); rSequence_addRU32( newEvent, RP_TAGS_PROCESS_ID, pid ); rSequence_addRU8( newEvent, RP_TAGS_RULE_NAME, patternId + 1 ); rSequence_addSTRINGN( newEvent, RP_TAGS_FILE_PATH, ctx->processPath ); hbs_publish( RP_TAGS_NOTIFICATION_FILE_TYPE_ACCESSED, newEvent ); rSequence_free( newEvent ); } } } else { rpal_debug_error( "error getting process context" ); break; } } } rMutex_unlock( g_mutex ); } } }
RPRIVATE RVOID dnsUmDiffThread ( rEvent isTimeToStop ) { rSequence notif = NULL; rBlob snapCur = NULL; rBlob snapPrev = NULL; _dnsRecord rec = { 0 }; _dnsRecord* pCurRec = NULL; RU32 i = 0; LibOsPerformanceProfile perfProfile = { 0 }; #ifdef RPAL_PLATFORM_WINDOWS PDNSCACHEENTRY pDnsEntry = NULL; PDNSCACHEENTRY pPrevDnsEntry = NULL; #endif perfProfile.enforceOnceIn = 1; perfProfile.sanityCeiling = MSEC_FROM_SEC( 10 ); perfProfile.lastTimeoutValue = 100; perfProfile.targetCpuPerformance = 0; perfProfile.globalTargetCpuPerformance = GLOBAL_CPU_USAGE_TARGET; perfProfile.timeoutIncrementPerSec = 1; while( !rEvent_wait( isTimeToStop, 0 ) ) { if( kAcq_isAvailable() ) { // If kernel acquisition becomes available, try kernel again. return; } libOs_timeoutWithProfile( &perfProfile, FALSE, isTimeToStop ); 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_strdup( pDnsEntry->pszName ) ) ) { rpal_blob_add( snapCur, &rec, sizeof( rec ) ); } pPrevDnsEntry = pDnsEntry; pDnsEntry = pDnsEntry->pNext; freeCacheEntry( pPrevDnsEntry->pszName, DnsFreeFlat ); freeCacheEntry( pPrevDnsEntry, DnsFreeFlat ); } rpal_sort_array( rpal_blob_getBuffer( snapCur ), rpal_blob_getSize( snapCur ) / sizeof( rec ), sizeof( rec ), _cmpDns ); } #elif defined( RPAL_PLATFORM_MACOSX ) rpal_thread_sleep( MSEC_FROM_SEC( 2 ) ); #endif // Do a general diff of the snapshots to find new entries. if( NULL != snapPrev ) { i = 0; while( !rEvent_wait( isTimeToStop, 0 ) && NULL != ( pCurRec = rpal_blob_arrElem( snapCur, sizeof( rec ), i++ ) ) ) { if( -1 == rpal_binsearch_array( rpal_blob_getBuffer( snapPrev ), rpal_blob_getSize( snapPrev ) / sizeof( rec ), sizeof( rec ), pCurRec, (rpal_ordering_func)_cmpDns ) ) { if( NULL != ( notif = rSequence_new() ) ) { rSequence_addSTRINGN( 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 ); hbs_timestampEvent( notif, 0 ); hbs_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; libOs_timeoutWithProfile( &perfProfile, TRUE, isTimeToStop ); } if( NULL != snapPrev ) { _freeRecords( snapPrev ); rpal_blob_free( snapPrev ); snapPrev = NULL; } }
static RBOOL notifyOfProcess ( RU32 pid, RU32 ppid, RBOOL isStarting, RNATIVESTR optFilePath, RNATIVESTR optCmdLine, RU32 optUserId, RU64 optTs ) { RBOOL isSuccess = FALSE; rSequence info = NULL; rSequence parentInfo = NULL; RU32 tmpUid = 0; RNATIVESTR cleanPath = NULL; // We prime the information with whatever was provided // to us by the kernel acquisition. If not available // we generate using the UM only way. if( 0 != rpal_string_strlenn( optFilePath ) && ( NULL != info || NULL != ( info = rSequence_new() ) ) ) { cleanPath = rpal_file_cleann( optFilePath ); rSequence_addSTRINGN( info, RP_TAGS_FILE_PATH, cleanPath ? cleanPath : optFilePath ); rpal_memory_free( cleanPath ); } if( 0 != rpal_string_strlenn( optCmdLine ) && ( NULL != info || NULL != ( info = rSequence_new() ) ) ) { rSequence_addSTRINGN( info, RP_TAGS_COMMAND_LINE, optCmdLine ); } if( NULL != info ) { info = processLib_getProcessInfo( pid, info ); } else if( !isStarting || NULL == ( info = processLib_getProcessInfo( pid, info ) ) ) { info = rSequence_new(); } if( rpal_memory_isValid( info ) ) { rSequence_addRU32( info, RP_TAGS_PROCESS_ID, pid ); rSequence_addRU32( info, RP_TAGS_PARENT_PROCESS_ID, ppid ); if( 0 != optTs ) { rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobalFromLocal( optTs ) ); } else { rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() ); } if( isStarting ) { if( NULL != ( parentInfo = processLib_getProcessInfo( ppid, NULL ) ) && !rSequence_addSEQUENCE( info, RP_TAGS_PARENT, parentInfo ) ) { rSequence_free( parentInfo ); } } if( isStarting ) { if( KERNEL_ACQ_NO_USER_ID != optUserId && !rSequence_getRU32( info, RP_TAGS_USER_ID, &tmpUid ) ) { rSequence_addRU32( info, RP_TAGS_USER_ID, optUserId ); } if( notifications_publish( RP_TAGS_NOTIFICATION_NEW_PROCESS, info ) ) { isSuccess = TRUE; rpal_debug_info( "new process starting: %d / %d", pid, ppid ); } } else { if( notifications_publish( RP_TAGS_NOTIFICATION_TERMINATE_PROCESS, info ) ) { isSuccess = TRUE; rpal_debug_info( "new process terminating: %d / %d", pid, ppid ); } } rSequence_free( info ); } else { rpal_debug_error( "could not allocate info on new process" ); } return isSuccess; }
static RBOOL notifyOfKernelModule ( KernelAcqModule* module ) { RBOOL isSuccess = FALSE; rSequence notif = NULL; RU32 pathLength = 0; RU32 i = 0; RPNCHAR dirSep = RPAL_FILE_LOCAL_DIR_SEP_N; RPNCHAR cleanPath = NULL; Atom parentAtom = { 0 }; if( NULL != module ) { if( NULL != ( notif = rSequence_new() ) ) { module->ts += MSEC_FROM_SEC( rpal_time_getGlobalFromLocal( 0 ) ); hbs_timestampEvent( notif, module->ts ); parentAtom.key.category = RP_TAGS_NOTIFICATION_NEW_PROCESS; parentAtom.key.process.pid = module->pid; if( atoms_query( &parentAtom, module->ts ) ) { HbsSetParentAtom( notif, parentAtom.id ); } rSequence_addRU32( notif, RP_TAGS_PROCESS_ID, module->pid ); rSequence_addPOINTER64( notif, RP_TAGS_BASE_ADDRESS, (RU64)module->baseAddress ); rSequence_addRU64( notif, RP_TAGS_MEMORY_SIZE, module->imageSize ); if( 0 != ( pathLength = rpal_string_strlen( module->path ) ) ) { cleanPath = rpal_file_clean( module->path ); rSequence_addSTRINGN( notif, RP_TAGS_FILE_PATH, cleanPath ? cleanPath : module->path ); rpal_memory_free( cleanPath ); // For compatibility with user mode we extract the module name. for( i = pathLength - 1; i != 0; i-- ) { if( dirSep[ 0 ] == module->path[ i ] ) { i++; break; } } rSequence_addSTRINGN( notif, RP_TAGS_MODULE_NAME, &( module->path[ i ] ) ); if( hbs_publish( RP_TAGS_NOTIFICATION_MODULE_LOAD, notif ) ) { isSuccess = TRUE; } } rSequence_free( notif ); } } return isSuccess; }
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 ); }