static
RPVOID
    continuousMemScan
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    RU32 thisProcId = 0;
    YaraMatchContext matchContext = { 0 };
    RU32 scanError = 0;

    UNREFERENCED_PARAMETER( ctx );

    thisProcId = processLib_getCurrentPid();

    while( !rEvent_wait( isTimeToStop, 0 ) )
    {
        // Wait until we have global rules to look for.
        if( rMutex_lock( g_global_rules_mutex ) )
        {
            if( NULL == g_global_rules )
            {
                rMutex_unlock( g_global_rules_mutex );
                rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 30 ) );
                continue;
            }
            rMutex_unlock( g_global_rules_mutex );
        }

        if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
        {
            curProc = processes;
            while( 0 != curProc->pid )
            {
                // We can't examine our own memory for the risk of tripping on the sigs themselves.
                if( curProc->pid == thisProcId ) continue;

                rpal_debug_info( "yara scanning pid %d", curProc->pid );

                matchContext.pid = curProc->pid;
                matchContext.processInfo = NULL;
                matchContext.moduleInfo = NULL;

                scanError = _scanProcessWith( curProc->pid, &matchContext, NULL, isTimeToStop );

                rSequence_free( matchContext.processInfo );

                if( rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 30 ) ) ) { break; }

                curProc++;
            }

            rpal_memory_free( processes );
        }
    }

    yr_finalize_thread();

    return NULL;
}
RPRIVATE
RVOID
    mem_find_string
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    RU32 currentPid = 0;
    rList searchStrings = NULL;
    rList processes = NULL;
    rSequence process = NULL;
    processLibProcEntry* pids = NULL;
    RU32 nCurrent = 0;
    RU32 minLength = 5;
    RU32 maxLength = 128;

    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 ) ) ) ) &&
            rSequence_getLIST( event, RP_TAGS_STRINGSW, &searchStrings ) )
        {
            currentPid = processLib_getCurrentPid();

            if( NULL != ( processes = rList_new( RP_TAGS_PROCESS, RPCM_SEQUENCE ) ) )
            {
                if( 0 != pid )
                {
                    if( NULL != ( process = _findStringsInProcess( pid, 
                                                                   searchStrings, 
                                                                   minLength, 
                                                                   maxLength ) ) )
                    {
                        if( !rList_addSEQUENCE( processes, process ) )
                        {
                            rSequence_free( process );
                        }
                    }
                }
                else
                {
                    if( NULL != ( pids = processLib_getProcessEntries( TRUE ) ) )
                    {
                        while( 0 != pids[ nCurrent ].pid )
                        {
                            if( currentPid != pids[ nCurrent ].pid )
                            {
                                if( NULL != ( process = _findStringsInProcess( pids[ nCurrent ].pid, 
                                                                               searchStrings, 
                                                                               minLength, 
                                                                               maxLength ) ) )
                                {
                                    if( !rList_addSEQUENCE( processes, process ) )
                                    {
                                        rSequence_free( process );
                                    }
                                }
                            }

                            nCurrent++;
                        }

                        rpal_memory_free( pids );
                    }
                }

                if( !rSequence_addLIST( event, RP_TAGS_PROCESSES, processes ) )
                {
                    rList_free( processes );
                }
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_FIND_STRING_REP, event );
    }
}