RPRIVATE
RVOID
    mem_read
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid;
    RU64 baseAddr;
    RU32 memSize;
    RPVOID mem;

    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_getRU64( event, RP_TAGS_BASE_ADDRESS, &baseAddr ) &&
            rSequence_getRU32( event, RP_TAGS_MEMORY_SIZE, &memSize ) )
        {
            if( processLib_getProcessMemory( pid, (RPVOID)rpal_ULongToPtr( baseAddr ), memSize, &mem, TRUE ) )
            {
                rSequence_addBUFFER( event, RP_TAGS_MEMORY_DUMP, (RPU8)mem, memSize );
                rpal_memory_free( mem );
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
                rpal_debug_error( "failed to get memory (base address = 0x%llx, size = 0x%x ) for pid 0x%x.", 
                                  baseAddr, 
                                  memSize, 
                                  pid );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_READ_REP, event );
    }
}
RPRIVATE
RVOID
    mem_handles
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid;
    rList handleList;

    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 != ( handleList = processLib_getHandles( pid, TRUE, NULL ) ) )
            {
                if( !rSequence_addLIST( event, RP_TAGS_HANDLES, handleList ) )
                {
                    rList_free( handleList );
                }
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_HANDLES_REP, event );
    }
}
RPRIVATE
RVOID
    mem_find_handle
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RPNCHAR needle = NULL;
    rList handleList;

    UNREFERENCED_PARAMETER( eventType );

    if( rpal_memory_isValid( event ) )
    {
        if( rSequence_getSTRINGN( event, RP_TAGS_HANDLE_NAME, &needle ) )
        {
            rSequence_unTaintRead( event );

            if( NULL != ( handleList = processLib_getHandles( 0, TRUE, needle ) ) )
            {
                if( !rSequence_addLIST( event, RP_TAGS_HANDLES, handleList ) )
                {
                    rList_free( handleList );
                }
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
                rpal_debug_error( "failed to get handles for pid 0x%x.", 0 );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_FIND_HANDLE_REP, event );
    }
}
static
RU32
    _checkMemoryForStringSample
    (
        HObs sample,
        RU32 pid,
        RPVOID moduleBase,
        RU64 moduleSize,
        rEvent isTimeToStop,
        LibOsPerformanceProfile* perfProfile
    )
{
    RPU8 pMem = NULL;
    RU8* sampleList = NULL;
    RPU8 sampleNumber = 0;
    RU32 nSamples = 0;
    RU32 nSamplesFound = (RU32)(-1);

    UNREFERENCED_PARAMETER( isTimeToStop );

    if( NULL != sample &&
        0 != pid &&
        NULL != moduleBase &&
        0 != moduleSize &&
        _MIN_DISK_SAMPLE_SIZE <= ( nSamples = obsLib_getNumPatterns( sample ) ) )
    {
        if( NULL != ( sampleList = rpal_memory_alloc( sizeof( RU8 ) * nSamples ) ) )
        {
            rpal_memory_zero( sampleList, sizeof( RU8 ) * nSamples );

            if( processLib_getProcessMemory( pid, moduleBase, moduleSize, (RPVOID*)&pMem, TRUE ) )
            {
                if( obsLib_setTargetBuffer( sample, pMem, (RU32)moduleSize ) )
                {
                    while( !rEvent_wait( isTimeToStop, 0 ) &&
                           obsLib_nextHit( sample, (RPVOID*)&sampleNumber, NULL ) )
                    {
                        libOs_timeoutWithProfile( perfProfile, TRUE, isTimeToStop );

                        if( sampleNumber < (RPU8)NUMBER_TO_PTR( nSamples ) &&
                            0 == sampleList[ (RU32)PTR_TO_NUMBER( sampleNumber ) ] )
                        {
                            sampleList[ (RU32)PTR_TO_NUMBER( sampleNumber ) ] = 1;
                            nSamplesFound++;
                        }
                    }
                }

                rpal_memory_free( pMem );
            }
            else
            {
                rpal_debug_info( "failed to get memory for %d: 0x%016X ( 0x%016X ) error %d", 
                                 pid, 
                                 moduleBase, 
                                 moduleSize,
                                 rpal_error_getLast() );
            }

            rpal_memory_free( sampleList );
        }
    }

    return nSamplesFound;
}
static
RU32
    _krnlSendReceive
    (
        RU32 op,
        RPU8 pArgs,
        RU32 argsSize,
        RPU8 pResult,
        RU32 resultSize,
        RU32* pSizeUsed
    )
{
    RU32 error = (RU32)(-1);
    RU32 nRetries = 1;

    // Check whether this particular function is available on
    // this platform via kernel.
    if( op >= KERNEL_ACQ_OP_COUNT ||
        !g_platform_availability[ op ] )
    {
        return error;
    }

    if( rMutex_lock( g_km_mutex ) )
    {
        while( 0 != nRetries )
        {
#ifdef RPAL_PLATFORM_MACOSX
            KernelAcqCommand cmd = { 0 };
            cmd.pArgs = pArgs;
            cmd.argsSize = argsSize;
            cmd.pResult = pResult;
            cmd.resultSize = resultSize;
            cmd.pSizeUsed = pSizeUsed;
            fd_set readset = { 0 };
            struct timeval timeout = { 0 };
            int waitVal = 0;

            error = setsockopt( g_km_socket, SYSPROTO_CONTROL, op, &cmd, sizeof( cmd ) );
#elif defined( RPAL_PLATFORM_WINDOWS )
            RU32 ioBufferSize = sizeof( KernelAcqCommand ) + argsSize;
            RPU8 ioBuffer = NULL;
            KernelAcqCommand* pCmd = NULL;

            if( NULL != ( ioBuffer = rpal_memory_alloc( ioBufferSize ) ) )
            {
                pCmd = (KernelAcqCommand*)ioBuffer;
                pCmd->op = op;
                pCmd->dataOffset = sizeof( KernelAcqCommand );
                pCmd->argsSize = argsSize;
                if( NULL != pArgs && 0 != argsSize )
                {
                    rpal_memory_memcpy( pCmd->data, pArgs, argsSize );
                }

                if( DeviceIoControl( g_km_handle,
                                     (DWORD)IOCTL_EXCHANGE_DATA,
                                     ioBuffer,
                                     ioBufferSize,
                                     pResult,
                                     resultSize,
                                     (LPDWORD)pSizeUsed,
                                     NULL ) )
                {
                    error = 0;
                }
                else
                {
                    error = rpal_error_getLast();
                }

                rpal_memory_free( ioBuffer );
            }
            else
            {
                error = RPAL_ERROR_NOT_ENOUGH_MEMORY;
            }
#else
            UNREFERENCED_PARAMETER( op );
            UNREFERENCED_PARAMETER( pArgs );
            UNREFERENCED_PARAMETER( argsSize );
            UNREFERENCED_PARAMETER( pResult );
            UNREFERENCED_PARAMETER( resultSize );
            UNREFERENCED_PARAMETER( pSizeUsed );
            break;
#endif

            // Success, return in.
            if( 0 == error )
            {
                break;
            }

            // Looks like we had a failure, this may be a sign from the kernel
            // that it must unload, so we'll give it a chance and toggle our
            // connection.
            _kAcq_deinit( FALSE );
            if( !_kAcq_init( FALSE ) )
            {
                break;
            }
            nRetries--;
        }
        rMutex_unlock( g_km_mutex );
    }

    return error;
}
예제 #6
0
RBOOL
    rpHostCommonPlatformLib_load
    (
        RPNCHAR modulePath,
        RU32 moduleId
    )
{
    RBOOL isSuccess = FALSE;

    RU32 moduleIndex = 0;
    rpal_thread_func pEntry = NULL;
    rpHCPModuleContext* modContext = NULL;
    RPCHAR errorStr = NULL;

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

    if( NULL != modulePath )
    {
        for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
        {
            if( 0 == g_hcpContext.modules[ moduleIndex ].hThread )
            {
                // Found an empty spot
#ifdef RPAL_PLATFORM_WINDOWS
                g_hcpContext.modules[ moduleIndex ].hModule = LoadLibraryW( modulePath );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                g_hcpContext.modules[ moduleIndex ].hModule = dlopen( modulePath, RTLD_NOW | RTLD_LOCAL );
#endif
                if( NULL != g_hcpContext.modules[ moduleIndex ].hModule )
                {
                    OBFUSCATIONLIB_TOGGLE( entrypoint );
#ifdef RPAL_PLATFORM_WINDOWS
                    pEntry = (rpal_thread_func)GetProcAddress( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule, 
                                                               (RPCHAR)entrypoint );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                    pEntry = (rpal_thread_func)dlsym( g_hcpContext.modules[ moduleIndex ].hModule, (RPCHAR)entrypoint );
#endif
                    OBFUSCATIONLIB_TOGGLE( entrypoint );

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

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

                        if( NULL != modContext->isTimeToStop )
                        {
                            g_hcpContext.modules[ moduleIndex ].id = (RpHcp_ModuleId)moduleId;
                            g_hcpContext.modules[ moduleIndex ].isTimeToStop  = modContext->isTimeToStop;
                            OBFUSCATIONLIB_TOGGLE( recvMessage );
#ifdef RPAL_PLATFORM_WINDOWS
                            g_hcpContext.modules[ moduleIndex ].func_recvMessage = 
                                    (rpHCPModuleMsgEntry)GetProcAddress( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule,
                                                                         (RPCHAR)recvMessage );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                            g_hcpContext.modules[ moduleIndex ].func_recvMessage = 
                                    (rpHCPModuleMsgEntry)dlsym( g_hcpContext.modules[ moduleIndex ].hModule, (RPCHAR)recvMessage );
#endif
                            OBFUSCATIONLIB_TOGGLE( recvMessage );
                            g_hcpContext.modules[ moduleIndex ].hThread = rpal_thread_new( pEntry, modContext );

                            if( 0 != g_hcpContext.modules[ moduleIndex ].hThread )
                            {
                                g_hcpContext.modules[ moduleIndex ].isOsLoaded = TRUE;
                                isSuccess = TRUE;
                                rpal_debug_info( "module %S successfully loaded manually.", modulePath );
                            }
                        }
                    }
                    else
                    {
#ifdef RPAL_PLATFORM_WINDOWS
                        FreeLibrary( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                        dlclose( g_hcpContext.modules[ moduleIndex ].hModule );
#endif
                        g_hcpContext.modules[ moduleIndex ].hModule = NULL;
                        rpal_debug_error( "Could not manually finding the entry point to a module!" );
                    }
                }
                else
                {
#if defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                    errorStr = dlerror();
#endif
                    rpal_debug_error( "Could not manually load module %S: %X %s", 
                                      modulePath, 
                                      rpal_error_getLast(), 
                                      errorStr );
                }

                break;
            }
        }
    }
    //forceCrash();
    return isSuccess;
}
RPRIVATE
RVOID
    mem_strings
    (
        rpcm_tag eventType,
        rSequence event
    )
{
    RU32 pid = 0;
    rList memMapList = NULL;
    rSequence region = NULL;
    RU64 memBase = 0;
    RU64 memSize = 0;
    RPU8 pRegion = NULL;
    rList stringsAList = NULL;
    rList stringsWList = NULL;
    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 ) ) ) )
        {
            if( NULL != ( memMapList = processLib_getProcessMemoryMap( pid ) ) &&
                ( NULL != ( stringsAList = rList_new( RP_TAGS_STRINGSA, RPCM_STRINGA ) ) ) &&
                ( NULL != ( stringsWList = rList_new( RP_TAGS_STRINGSW, RPCM_STRINGW ) ) ) )
            {
                while( rList_getSEQUENCE( memMapList, RP_TAGS_MEMORY_REGION, &region ) )
                {
                    if( rSequence_getPOINTER64( region, RP_TAGS_BASE_ADDRESS, &memBase ) &&
                        rSequence_getRU64( region, RP_TAGS_MEMORY_SIZE, &memSize ) )
                    {
                        if( processLib_getProcessMemory( pid, 
                                                         (RPVOID)rpal_ULongToPtr( memBase ), 
                                                         memSize, 
                                                         (RPVOID*)&pRegion,
                                                         TRUE ) )
                        {
                            // now search for strings inside this region
                            _getStringsList( stringsAList, stringsWList, pRegion, memSize, minLength, maxLength );

                            rpal_memory_free( pRegion );
                        }
                    }
                }

                if( !rSequence_addLIST( event, RP_TAGS_STRINGSA, stringsAList ) )
                {
                    rList_free( stringsAList );
                }
                if( !rSequence_addLIST( event, RP_TAGS_STRINGSW, stringsWList ) )
                {
                    rList_free( stringsWList );
                }
            }
            else
            {
                rSequence_addRU32( event, RP_TAGS_ERROR, rpal_error_getLast() );
            }

            if( NULL != memMapList )
            {
                rList_free( memMapList );
            }
        }

        hbs_timestampEvent( event, 0 );
        hbs_publish( RP_TAGS_NOTIFICATION_MEM_STRINGS_REP, event );
    }
}
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 );
}
        RPRIVATE
rSequence
    _findStringsInProcess
    (
        RU32 pid,
        rList searchStrings,
        RU32 minLength,
        RU32 maxLength
    )
{
    rSequence info = NULL;

    rList memMapList = NULL;
    rSequence region = NULL;
    RU64 memBase = 0;
    RU64 memSize = 0;
    RPU8 pRegion = NULL;
    rList stringsFound = NULL;

    if( NULL != searchStrings )
    {
        if( NULL != ( info = rSequence_new() ) )
        {
            rSequence_addRU32( info, RP_TAGS_PROCESS_ID, pid );

            if( NULL != ( memMapList = processLib_getProcessMemoryMap( pid ) ) &&
                ( NULL != ( stringsFound = rList_new( RP_TAGS_STRINGSW, RPCM_SEQUENCE ) ) ) )
            {
                while( rList_getSEQUENCE( memMapList, RP_TAGS_MEMORY_REGION, &region ) )
                {
                    if( rSequence_getPOINTER64( region, RP_TAGS_BASE_ADDRESS, &memBase ) &&
                        rSequence_getRU64( region, RP_TAGS_MEMORY_SIZE, &memSize ) )
                    {
                        if( processLib_getProcessMemory( pid, 
                                                         (RPVOID)rpal_ULongToPtr( memBase ), 
                                                         memSize, 
                                                         (RPVOID*)&pRegion, 
                                                         TRUE ) )
                        {
                            // now search for strings inside this region
                            _searchForStrings( stringsFound, 
                                               searchStrings, 
                                               pRegion, 
                                               memSize, 
                                               memBase, 
                                               minLength, 
                                               maxLength);

                            rpal_memory_free( pRegion );
                        }
                    }
                }

                if( !rSequence_addLIST( info, RP_TAGS_STRINGS_FOUND, stringsFound ) )
                {
                    rList_free( stringsFound );
                }
            }
            else
            {
                rSequence_addRU32( info, RP_TAGS_ERROR, rpal_error_getLast() );
            }

            if( NULL != memMapList )
            {
                rList_free( memMapList );
            }
        }
    }

    return info;
}