static
RVOID
    processCodeIdentA
    (
        RPCHAR name,
        RPU8 pFileHash,
        RU64 codeSize,
        rSequence originalEvent
    )
{
    CodeIdent ident = { 0 };
    rSequence notif = NULL;

    ident.codeSize = codeSize;

    if( NULL != name )
    {
        CryptoLib_hash( name, rpal_string_strlen( name ) * sizeof( RCHAR ), 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_addSTRINGA( notif, RP_TAGS_FILE_NAME, 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 RVOID
    _elemToHash
    (
        rSequence elem,
        CryptoLib_Hash* pHash
    )
{
    rBlob blob = NULL;

    if( rpal_memory_isValid( elem ) &&
        NULL != pHash &&
        NULL != ( blob = rpal_blob_create( 0, 0 ) ) )
    {
        if( rSequence_serialise( elem, blob ) )
        {
            CryptoLib_hash( (CryptoLib_Hash*)rpal_blob_getBuffer( blob ), rpal_blob_getSize( blob ), pHash );
        }

        rpal_blob_free( blob );
    }
}
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 );
        }
    }
}
示例#4
0
RPRIVATE_TESTABLE
RBOOL 
    loadModule
    (
        rpHCPContext* hcpContext,
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;

    RU32 moduleIndex = (RU32)(-1);

    RPU8 tmpBuff = NULL;
    RU32 tmpSize = 0;

    RPU8 tmpSig = NULL;
    RU32 tmpSigSize = 0;

    rpal_thread_func pEntry = NULL;

    rpHCPModuleContext* modContext = NULL;

    OBFUSCATIONLIB_DECLARE( entryName, RP_HCP_CONFIG_MODULE_ENTRY );
    OBFUSCATIONLIB_DECLARE( recvMessage, RP_HCP_CONFIG_MODULE_RECV_MESSAGE );

    if( NULL != seq &&
        NULL != hcpContext )
    {
        for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
        {
            if( 0 == hcpContext->modules[ moduleIndex ].hThread )
            {
                // Found an empty spot
                break;
            }
        }
    }

    if( RP_HCP_CONTEXT_MAX_MODULES != moduleIndex &&
        (RU32)(-1) != moduleIndex )
    {
        // We got an empty spot for our module
        if( rSequence_getRU8( seq, 
                              RP_TAGS_HCP_MODULE_ID, 
                              &(hcpContext->modules[ moduleIndex ].id ) ) &&
            rSequence_getBUFFER( seq,
                                 RP_TAGS_BINARY, 
                                 &tmpBuff, 
                                 &tmpSize ) &&
            rSequence_getBUFFER( seq,
                                 RP_TAGS_SIGNATURE,
                                 &tmpSig,
                                 &tmpSigSize ) &&
            CRYPTOLIB_SIGNATURE_SIZE == tmpSigSize )
        {
            // We got the data, now verify the buffer signature
            if( CryptoLib_verify( tmpBuff, tmpSize, getRootPublicKey(), tmpSig ) )
            {
                // Ready to load the module
                rpal_debug_info( "loading module in memory" );
                hcpContext->modules[ moduleIndex ].hModule = MemoryLoadLibrary( tmpBuff, tmpSize );

                if( NULL != hcpContext->modules[ moduleIndex ].hModule )
                {
                    OBFUSCATIONLIB_TOGGLE( entryName );

                    pEntry = (rpal_thread_func)MemoryGetProcAddress( hcpContext->modules[ moduleIndex ].hModule,
                                                            (RPCHAR)entryName );

                    OBFUSCATIONLIB_TOGGLE( entryName );

                    if( NULL != pEntry )
                    {
                        modContext = &(hcpContext->modules[ moduleIndex ].context);

                        modContext->pCurrentId = &( hcpContext->currentId );
                        modContext->func_sendHome = doSend;
                        modContext->isTimeToStop = rEvent_create( TRUE );
                        modContext->rpalContext = rpal_Context_get();
                        modContext->isOnlineEvent = hcpContext->isCloudOnline;

                        if( NULL != modContext->isTimeToStop )
                        {
                            hcpContext->modules[ moduleIndex ].isTimeToStop = modContext->isTimeToStop;

                            OBFUSCATIONLIB_TOGGLE( recvMessage );
                            hcpContext->modules[ moduleIndex ].func_recvMessage =
                                    (rpHCPModuleMsgEntry)MemoryGetProcAddress( hcpContext->modules[ moduleIndex ].hModule,
                                                                               (RPCHAR)recvMessage );
                            OBFUSCATIONLIB_TOGGLE( recvMessage );

                            hcpContext->modules[ moduleIndex ].hThread = rpal_thread_new( pEntry, modContext );

                            if( 0 != hcpContext->modules[ moduleIndex ].hThread )
                            {
                                CryptoLib_hash( tmpBuff, tmpSize, &(hcpContext->modules[ moduleIndex ].hash ) );
                                hcpContext->modules[ moduleIndex ].isOsLoaded = FALSE;
                                isSuccess = TRUE;
                            }
                            else
                            {
                                rpal_debug_warning( "Error creating handler thread for new module." );
                            }
                        }
                    }
                    else
                    {
                        rpal_debug_warning( "Could not find new module's entry point." );
                    }
                }
                else
                {
                    rpal_debug_warning( "Error loading module in memory." );
                }
            }
            else
            {
                rpal_debug_warning( "New module signature invalid." );
            }
        }
        else
        {
            rpal_debug_warning( "Could not find core module components to load." );
        }

        // Main cleanup
        if( !isSuccess )
        {
            if( NULL != modContext )
            {
                IF_VALID_DO( modContext->isTimeToStop, rEvent_free );
            }

            if( NULL != hcpContext->modules[ moduleIndex ].hModule )
            {
                MemoryFreeLibrary( hcpContext->modules[ moduleIndex ].hModule );
            }

            rpal_memory_zero( &(hcpContext->modules[ moduleIndex ] ),
                              sizeof( hcpContext->modules[ moduleIndex ] ) );
        }
    }
    else
    {
        rpal_debug_error( "Could not find a spot for new module, or invalid module id!" );
    }

    return isSuccess;
}
static RPVOID
    trackerDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    _volEntry* prevVolumes = NULL;
    RU32 nVolumes = 0;
    rList snapshot = NULL;
    rList prevSnapshot = NULL;
    _volEntry* newVolumes = NULL;
    RU32 nNewVolumes = 0;
    rSequence volume = NULL;
    rBlob serial = NULL;
    RU32 i = 0;
    LibOsPerformanceProfile perfProfile = { 0 };

    UNREFERENCED_PARAMETER( ctx );

    perfProfile.enforceOnceIn = 1;
    perfProfile.sanityCeiling = MSEC_FROM_SEC( 10 );
    perfProfile.lastTimeoutValue = 10;
    perfProfile.targetCpuPerformance = 0;
    perfProfile.globalTargetCpuPerformance = GLOBAL_CPU_USAGE_TARGET;
    perfProfile.timeoutIncrementPerSec = 1;
    
    while( !rEvent_wait( isTimeToStop, 0 ) )
    {
        libOs_timeoutWithProfile( &perfProfile, FALSE );

        if( NULL != ( snapshot = libOs_getVolumes() ) )
        {
            if( NULL != ( newVolumes = rpal_memory_alloc( sizeof( *newVolumes ) *
                                                          rList_getNumElements( snapshot ) ) ) )
            {
                nNewVolumes = 0;

                while( !rEvent_wait( isTimeToStop, 0 ) &&
                       rList_getSEQUENCE( snapshot, RP_TAGS_VOLUME, &volume ) )
                {
                    libOs_timeoutWithProfile( &perfProfile, TRUE );

                    if( NULL != ( serial = rpal_blob_create( 0, 0 ) ) )
                    {
                        if( rSequence_serialise( volume, serial ) &&
                            CryptoLib_hash( rpal_blob_getBuffer( serial ),
                                            rpal_blob_getSize( serial ), 
                                            &( newVolumes[ nNewVolumes ].hash ) ) )
                        {
                            newVolumes[ nNewVolumes ].volume = volume;

                            if( NULL != prevVolumes &&
                                ( -1 ) == rpal_binsearch_array( prevVolumes,
                                                                nVolumes,
                                                                sizeof( *prevVolumes ),
                                                                &( newVolumes[ nNewVolumes ] ),
                                                                (rpal_ordering_func)_cmpHashes ) )
                            {
                                notifications_publish( RP_TAGS_NOTIFICATION_VOLUME_MOUNT, volume );
                                rpal_debug_info( "new volume mounted" );
                            }

                            nNewVolumes++;
                        }

                        rpal_blob_free( serial );
                    }
                }

                if( !rEvent_wait( isTimeToStop, 0 ) )
                {
                    rpal_sort_array( newVolumes,
                                     nNewVolumes,
                                     sizeof( *newVolumes ),
                                     (rpal_ordering_func)_cmpHashes );

                    for( i = 0; i < nVolumes; i++ )
                    {
                        libOs_timeoutWithProfile( &perfProfile, TRUE );

                        if( ( -1 ) == rpal_binsearch_array( newVolumes,
                                                            nNewVolumes,
                                                            sizeof( *newVolumes ),
                                                            &( prevVolumes[ i ].hash ),
                                                            (rpal_ordering_func)_cmpHashes ) )
                        {
                            notifications_publish( RP_TAGS_NOTIFICATION_VOLUME_UNMOUNT,
                                                   prevVolumes[ i ].volume );
                            rpal_debug_info( "volume unmounted" );
                        }
                    }
                }
            }

            if( NULL != prevSnapshot )
            {
                rList_free( prevSnapshot );
            }
            prevSnapshot = snapshot;
            if( NULL != prevVolumes )
            {
                rpal_memory_free( prevVolumes );
            }
            prevVolumes = newVolumes;
            nVolumes = nNewVolumes;
        }
    }
    
    if( NULL != prevSnapshot )
    {
        rList_free( prevSnapshot );
    }
    if( NULL != prevVolumes )
    {
        rpal_memory_free( prevVolumes );
    }

    return NULL;
}
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 );
        }
    }
}