static RVOID kernelModeDiff ( rEvent isTimeToStop ) { RU32 i = 0; RU32 nScratch = 0; RU32 nProcessEntries = 0; KernelAcqProcess new_from_kernel[ 200 ] = { 0 }; processEntry tracking_user[ MAX_SNAPSHOT_SIZE ] = { 0 }; while( !rEvent_wait( isTimeToStop, 1000 ) ) { nScratch = ARRAY_N_ELEM( new_from_kernel ); rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) ); if( !kAcq_getNewProcesses( new_from_kernel, &nScratch ) ) { rpal_debug_warning( "kernel acquisition for new processes failed" ); g_is_kernel_failure = TRUE; break; } for( i = 0; i < nScratch; i++ ) { notifyOfProcess( new_from_kernel[ i ].pid, new_from_kernel[ i ].ppid, TRUE, new_from_kernel[ i ].path, new_from_kernel[ i ].cmdline, new_from_kernel[ i ].uid, new_from_kernel[ i ].ts ); if( nProcessEntries >= ARRAY_N_ELEM( tracking_user ) - 1 ) { continue; } tracking_user[ nProcessEntries ].pid = new_from_kernel[ i ].pid; tracking_user[ nProcessEntries ].ppid = new_from_kernel[ i ].ppid; nProcessEntries++; } for( i = 0; i < nProcessEntries; i++ ) { if( !processLib_isPidInUse( tracking_user[ i ].pid ) ) { notifyOfProcess( tracking_user[ i ].pid, tracking_user[ i ].ppid, FALSE, NULL, NULL, KERNEL_ACQ_NO_USER_ID, 0 ); if( nProcessEntries != i + 1 ) { rpal_memory_memmove( &(tracking_user[ i ]), &(tracking_user[ i + 1 ]), nProcessEntries - i + 1 ); } nProcessEntries--; } } } }
static RPVOID processDiffThread ( rEvent isTimeToStop, RPVOID ctx ) { processEntry* currentSnapshot = g_snapshot_1; processEntry* previousSnapshot = g_snapshot_2; processEntry* tmpSnapshot = NULL; RBOOL isFirstSnapshots = TRUE; RU32 i = 0; RU32 j = 0; RBOOL isFound = FALSE; RU32 nThLoop = 0; RU32 currentTimeout = 0; UNREFERENCED_PARAMETER( ctx ); while( !rEvent_wait( isTimeToStop, currentTimeout ) ) { tmpSnapshot = currentSnapshot; currentSnapshot = previousSnapshot; previousSnapshot = tmpSnapshot; if( getSnapshot( currentSnapshot ) ) { if( isFirstSnapshots ) { isFirstSnapshots = FALSE; continue; } // Diff to find new processes for( i = 0; i < MAX_SNAPSHOT_SIZE; i++ ) { isFound = FALSE; if( 0 == currentSnapshot[ i ].pid ) { break; } for( j = 0; j < MAX_SNAPSHOT_SIZE; j++ ) { if( 0 == previousSnapshot[ j ].pid ) { break; } if( previousSnapshot[ j ].pid == currentSnapshot[ i ].pid ) { isFound = TRUE; break; } } if( !isFound ) { if( !notifyOfProcess( currentSnapshot[ i ].pid, currentSnapshot[ i ].ppid, TRUE ) ) { rpal_debug_warning( "error reporting new process: %d", currentSnapshot[ i ].pid ); } } } // Diff to find terminated processes for( i = 0; i < MAX_SNAPSHOT_SIZE; i++ ) { isFound = FALSE; if( 0 == previousSnapshot[ i ].pid ) { break; } for( j = 0; j < MAX_SNAPSHOT_SIZE; j++ ) { if( 0 == currentSnapshot[ j ].pid ) { break; } if( previousSnapshot[ i ].pid == currentSnapshot[ j ].pid ) { isFound = TRUE; break; } } if( !isFound ) { if( !notifyOfProcess( previousSnapshot[ i ].pid, previousSnapshot[ i ].ppid, FALSE ) ) { rpal_debug_warning( "error reporting terminated process: %d", previousSnapshot[ i ].pid ); } } } } nThLoop++; if( 0 == nThLoop % 20 ) { #ifdef RPAL_PLATFORM_WINDOWS // The Windows API is much more efficient than on Nix so we can affort // going faster between our diffs. currentTimeout = libOs_getUsageProportionalTimeout( 500 ) + 100; #else currentTimeout = libOs_getUsageProportionalTimeout( 800 ) + 200; #endif } } return NULL; }
static RVOID userModeDiff ( rEvent isTimeToStop ) { processEntry snapshot_1[ MAX_SNAPSHOT_SIZE ] = { 0 }; processEntry snapshot_2[ MAX_SNAPSHOT_SIZE ] = { 0 }; processEntry* currentSnapshot = snapshot_1; processEntry* previousSnapshot = snapshot_2; processEntry* tmpSnapshot = NULL; RBOOL isFirstSnapshots = TRUE; RU32 i = 0; RBOOL isFound = FALSE; RU32 nTmpElem = 0; RU32 nCurElem = 0; RU32 nPrevElem = 0; LibOsPerformanceProfile perfProfile = { 0 }; perfProfile.enforceOnceIn = 1; perfProfile.sanityCeiling = MSEC_FROM_SEC( 10 ); perfProfile.lastTimeoutValue = 100; perfProfile.targetCpuPerformance = 0; perfProfile.globalTargetCpuPerformance = GLOBAL_CPU_USAGE_TARGET; perfProfile.timeoutIncrementPerSec = 10; while( !rEvent_wait( isTimeToStop, 0 ) && ( !kAcq_isAvailable() || g_is_kernel_failure ) ) { libOs_timeoutWithProfile( &perfProfile, FALSE ); tmpSnapshot = currentSnapshot; currentSnapshot = previousSnapshot; previousSnapshot = tmpSnapshot; nTmpElem = nCurElem; nCurElem = nPrevElem; nPrevElem = nTmpElem; if( getSnapshot( currentSnapshot, &nCurElem ) ) { if( isFirstSnapshots ) { isFirstSnapshots = FALSE; continue; } // Diff to find new processes for( i = 0; i < nCurElem; i++ ) { isFound = FALSE; if( (RU32)( -1 ) != rpal_binsearch_array( previousSnapshot, nPrevElem, sizeof( processEntry ), &(currentSnapshot[ i ].pid), (rpal_ordering_func)rpal_order_RU32 ) ) { isFound = TRUE; } if( !isFound ) { if( !notifyOfProcess( currentSnapshot[ i ].pid, currentSnapshot[ i ].ppid, TRUE, NULL, NULL, KERNEL_ACQ_NO_USER_ID, 0 ) ) { rpal_debug_warning( "error reporting new process: %d", currentSnapshot[ i ].pid ); } } } // Diff to find terminated processes for( i = 0; i < nPrevElem; i++ ) { isFound = FALSE; if( (RU32)( -1 ) != rpal_binsearch_array( currentSnapshot, nCurElem, sizeof( processEntry ), &(previousSnapshot[ i ].pid), (rpal_ordering_func)rpal_order_RU32 ) ) { isFound = TRUE; } if( !isFound ) { if( !notifyOfProcess( previousSnapshot[ i ].pid, previousSnapshot[ i ].ppid, FALSE, NULL, NULL, KERNEL_ACQ_NO_USER_ID, 0 ) ) { rpal_debug_warning( "error reporting terminated process: %d", previousSnapshot[ i ].pid ); } } } } libOs_timeoutWithProfile( &perfProfile, TRUE ); } }