//=============================================================================
//  rMutex API
//=============================================================================
rMutex
    rMutex_create
    (

    )
{
    rMutex mutex = NULL;

    mutex = rpal_memory_alloc( sizeof( _rMutex ) );

    if( rpal_memory_isValid( mutex ) )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        ((_rMutex*)mutex)->hMutex = CreateMutex( NULL, FALSE, NULL );

        if( NULL == ((_rMutex*)mutex)->hMutex )
        {
            rpal_memory_free( mutex );
            mutex = NULL;
        }
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
        pthread_mutex_init( &((_rMutex*)mutex)->hMutex, NULL );
#endif
    }

    return mutex;
}
//=============================================================================
//  rEvent API
//=============================================================================
rEvent
    rEvent_create
    (
        RBOOL isManualReset
    )
{
    _rEvent* evt = NULL;

    evt = rpal_memory_alloc( sizeof( *evt ) );

    if( rpal_memory_isValid( evt ) )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        evt->waitCount = 0;
        
        evt->hEvent = CreateEvent( NULL, isManualReset, FALSE, NULL );
        
        if( NULL == evt->hEvent )
        {
            rpal_memory_free( evt );
            evt = NULL;
        }
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
        pthread_mutex_init( &evt->hMutex, NULL );
        pthread_cond_init( &evt->hCond, NULL );
        evt->isManualReset = isManualReset;
        evt->isOn = FALSE;
#endif
    }

    return (rEvent)evt;
}
Пример #3
0
//=============================================================================
//  Public API
//=============================================================================
HObs
    obsLib_new
    (
        RU32 nMaxMem,
        ObsType searchType
    )
{
    _PHObs obs = NULL;

    obs = rpal_memory_alloc( sizeof( _HObs ) );

    if( rpal_memory_isValid( obs ) )
    {
        obs->root = newNode();
        if( NULL != obs->root )
        {
            obs->currentOffset = 0;
            obs->maxDepth = 0;
            obs->maxMem = nMaxMem;
            obs->searchType = searchType;
            obs->targetBuffer = NULL;
            obs->currentState = NULL;
            obs->curHits = NULL;
            obs->curDepth = 0;
            obs->nPatterns = 0;
        }
        else
        {
            rpal_memory_free( obs );
            obs = NULL;
        }
    }

    return (HObs)obs;
}
//=============================================================================
//  rRwLock API
//=============================================================================
rRwLock
    rRwLock_create
    (

    )
{
    _rRwLock* lock;

    lock = rpal_memory_alloc( sizeof( *lock ) );

    if( rpal_memory_isValid( lock ) )
    {
        lock->evtCanRead = rEvent_create( TRUE );
        lock->evtCanWrite = rEvent_create( TRUE );
        lock->stateLock = rMutex_create();
        lock->readCount = 0;

        if( !rpal_memory_isValid( lock->evtCanRead ) ||
            !rpal_memory_isValid( lock->evtCanWrite ) ||
            !rpal_memory_isValid( lock->stateLock ) )
        {
            rEvent_free( lock->evtCanRead );
            rEvent_free( lock->evtCanWrite );
            rMutex_free( lock->stateLock );
            rpal_memory_free( lock );
            lock = NULL;
        }
        else
        {
            rEvent_set( lock->evtCanRead );
        }
    }

    return (rRwLock)lock;
}
//=============================================================================
//  rRefCount API
//=============================================================================
rRefCount
    rRefCount_create
    (
        rRefCount_freeFunc freeFunc,
        RPVOID pElem,
        RU32 elemSize
    )
{
    _rRefCount* ref = NULL;

    ref = rpal_memory_alloc( sizeof( *ref ) );

    if( rpal_memory_isValid( ref ) )
    {
        ref->mutex = rMutex_create();

        if( rpal_memory_isValid( ref->mutex ) )
        {
            ref->count = 1;
            ref->freeFunc = freeFunc;
            ref->pElem = pElem;
            ref->elemSize = elemSize;
        }
        else
        {
            rpal_memory_free( ref );
            ref = NULL;
        }
    }

    return (rRefCount)ref;
}
Пример #6
0
rStack
    rStack_new
    (
        RU32 elemSize
    )
{
    _prStack stack = NULL;

    stack = rpal_memory_alloc( sizeof( _rStack ) );

    if( NULL != stack )
    {
        stack->blob = rpal_blob_create( 0, 0 );

        if( NULL != stack->blob )
        {
            stack->nElements = 0;
            stack->elemSize = elemSize;

            if( NULL == ( stack->lock = rMutex_create() ) )
            {
                rpal_blob_free( stack->blob );
                rpal_memory_free( stack );
                stack = NULL;
            }
        }
        else
        {
            rpal_memory_free( stack );
            stack = NULL;
        }
    }

    return stack;
}
RPRIVATE
RVOID
    _processSnapshot
    (
        rList snapshot,
        CryptoLib_Hash** prevSnapshot,
        RU32* prevNumElem,
        rpcm_tag elemTag,
        rpcm_tag notifTag
    )
{
    CryptoLib_Hash hash = { 0 };
    RU32 i = 0;
    CryptoLib_Hash* tmpSnap = NULL;
    rSequence elem = NULL;

    if( NULL == prevSnapshot ||
        NULL == prevNumElem )
    {
        return;
    }

    if( NULL != ( tmpSnap = rpal_memory_alloc( sizeof( hash ) * rList_getNumElements( snapshot ) ) ) )
    {
        i = 0;
        while( rList_getSEQUENCE( snapshot, elemTag, &elem ) )
        {
            _elemToHash( elem, &hash );
            tmpSnap[ i ] = hash;

            if( NULL != *prevSnapshot )
            {
                if( ( -1 ) == rpal_binsearch_array( *prevSnapshot,
                                                    *prevNumElem,
                                                    sizeof( hash ),
                                                    &hash,
                                                    (rpal_ordering_func)_cmpHashes ) )
                {
                    hbs_timestampEvent( elem, 0 );
                    hbs_publish( notifTag, elem );
                }
            }

            i++;
        }

        FREE_AND_NULL( *prevSnapshot );
        *prevSnapshot = tmpSnap;
        *prevNumElem = i;
        tmpSnap = NULL;
        rpal_sort_array( *prevSnapshot, *prevNumElem, sizeof( hash ), (rpal_ordering_func)_cmpHashes );
    }
}
Пример #8
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;
}
Пример #9
0
RPCHAR
    liburl_encode
    (
        RPCHAR str
    )
{
    RPCHAR encoded = NULL;

    RU32 index = 0;
    RU32 numToEncode = 0;
    RU32 len = 0;
    RCHAR escaped[ 3 ] = {0};

    if( NULL != str )
    {
        len = rpal_string_strlen( str );

        for( index = 0; index < len; index++ )
        {
            if( !isValidUrlChar( *(str + index) ) )
            {
                numToEncode++;
            }
        }

        encoded = rpal_memory_alloc( len + sizeof(RCHAR) + numToEncode );

        numToEncode = 0;

        if( rpal_memory_isValid( encoded ) )
        {
            for( index = 0; index < len; index++ )
            {
                if( !isValidUrlChar( *(str + index) ) )
                {
                    sprintf( (RPCHAR)&escaped, "%02X", *(str + index) );

                    *(encoded + index + numToEncode) = escaped[ 0 ];
                    numToEncode++;
                    *(encoded + index + numToEncode) = escaped[ 1 ];
                }
                else
                {
                    *(encoded + index + numToEncode) = *(str + index);
                }
            }
        }
    }

    return encoded;
}
static
RBOOL
    assembleRanges
    (
        rList mods,
        _MemRange** pRanges,
        RU32* pNRanges
    )
{
    RBOOL isSuccess = FALSE;
    _MemRange* memRanges = NULL;
    rSequence mod = NULL;
    RU64 base = 0;
    RU64 size = 0;
    RU32 i = 0;

    if( rpal_memory_isValid( mods ) &&
        NULL != pRanges &&
        NULL != pNRanges )
    {
        if( NULL != ( memRanges = rpal_memory_alloc( sizeof( _MemRange ) *
                                                     rList_getNumElements( mods ) ) ) )
        {
            rList_resetIterator( mods );

            while( rList_getSEQUENCE( mods, RP_TAGS_DLL, &mod ) )
            {
                if( rSequence_getPOINTER64( mod, RP_TAGS_BASE_ADDRESS, &base ) &&
                    rSequence_getRU64( mod, RP_TAGS_MEMORY_SIZE, &size ) )
                {
                    memRanges[ i ].base = base;
                    memRanges[ i ].size = size;
                    i++;
                }
            }

            if( rpal_sort_array( memRanges, 
                                 i, 
                                 sizeof( _MemRange ), 
                                 (rpal_ordering_func)rpal_order_RU64 ) )
            {
                isSuccess = TRUE;
                *pRanges = memRanges;
                *pNRanges = i;
            }
        }
    }

    return isSuccess;
}
StatefulEvent*
    SMEvent_new
    (
        rpcm_tag eventType,
        rSequence data
    )
{
    StatefulEvent* event = NULL;

    rSequence wrapper = NULL;

    if( NULL != data )
    {
        if( NULL != ( wrapper = rSequence_new() ) )
        {
            if( NULL != ( event = rpal_memory_alloc( sizeof( *event ) ) ) )
            {
                if( NULL != ( event->ref = rRefCount_create( (rRefCount_freeFunc)_freeEvent, event, sizeof( *event ) ) ) )
                {
                    if( rSequence_addSEQUENCE( wrapper, eventType, data ) )
                    {
                        event->data = wrapper;
                        event->eventType = eventType;
                        rSequence_getTIMESTAMP( data, RP_TAGS_TIMESTAMP, &event->ts );
                    }
                    else
                    {
                        rSequence_free( wrapper );
                    }
                }
                else
                {
                    rpal_memory_free( event );
                    event = NULL;
                    rSequence_free( wrapper );
                }
            }
            else
            {
                rSequence_free( wrapper );
            }
        }
    }

    return event;
}
static
ProcExtInfo*
    getProcContext
    (
        RPU8 atomId
    )
{
    ProcExtInfo* procInfo = NULL;
    RU32 index = 0;

    if( (RU32)-1 != ( index = rpal_binsearch_array( g_procContexts->elements,
                                                    g_procContexts->nElements,
                                                    sizeof( ProcExtInfo* ),
                                                    &atomId,
                                                    (rpal_ordering_func)_cmpContext ) ) )
    {
        procInfo = g_procContexts->elements[ index ];
    }
    else
    {
        if( NULL != ( procInfo = rpal_memory_alloc( sizeof( *procInfo ) ) ) )
        {
            rpal_memory_memcpy( procInfo->atomId, atomId, sizeof( procInfo->atomId ) );

            if( !rpal_vector_add( g_procContexts, procInfo ) )
            {
                rpal_memory_free( procInfo );
                rpal_debug_error( "error adding new process to history" );
                procInfo = NULL;
            }
            else
            {
                rpal_sort_array( g_procContexts->elements, 
                                 g_procContexts->nElements, 
                                 sizeof( ProcExtInfo* ), 
                                 (rpal_ordering_func)_cmpContext );
            }
        }
    }

    return procInfo;
}
Пример #13
0
PObsNode
    newNode
    (

    )
{
    PObsNode node = NULL;

    node = rpal_memory_alloc( sizeof( ObsNode ) + ( DEFAULT_ALLOCATED_PATTERNS * sizeof( RPVOID ) ) );

    if( rpal_memory_isValid( node ) )
    {
        node->nElements = 0;
        node->pSigsHit = NULL;
        node->startOffset = 0;
        node->nAllocated = DEFAULT_ALLOCATED_PATTERNS;
    }

    return node;
}
rString
rpal_stringbuffer_new
(
    RU32 initialSize,
    RU32 growBy
)
{
    _rString* pStr = NULL;

    pStr = rpal_memory_alloc( sizeof( _rString ) );

    if( rpal_memory_isValid( pStr ) )
    {
        pStr->blob = rpal_blob_create( initialSize, growBy );

        if( NULL == pStr->blob )
        {
            rpal_memory_free( pStr );
            pStr = NULL;
        }
    }

    return (rString)pStr;
}
static StatefulMachine*
    _newMachineFrom
    (
        StatefulMachineDescriptor* desc
    )
{
    StatefulMachine* machine = NULL;

    if( NULL != desc )
    {
        if( NULL != ( machine = rpal_memory_alloc( sizeof( *machine ) ) ) )
        {
            machine->desc = desc;
            machine->currentState = 0;
            if( NULL == ( machine->history = rpal_vector_new() ) )
            {
                rpal_memory_free( machine );
                machine = NULL;
            }
        }
    }

    return machine;
}
Пример #16
0
PObsSig
    newSig
    (
        RPU8 pPattern,
        RU32 patternSize,
        RPVOID context
    )
{
    PObsSig sig = NULL;

    if( NULL != pPattern &&
        0 != patternSize )
    {
        sig = rpal_memory_alloc( sizeof( ObsSig ) + patternSize );

        if( rpal_memory_isValid( sig ) )
        {
            sig->pContext = context;
            sig->sigSize = patternSize;
        }
    }

    return sig;
}
static
HObs
    _getModuleDiskStringSample
    (
        RPNCHAR modulePath,
        RU32* pLastScratch,
        rEvent isTimeToStop,
        LibOsPerformanceProfile* perfProfile
    )
{
    HObs sample = NULL;
    RPU8 scratch = NULL;
    rFile hFile = NULL;
    RU32 read = 0;
    RPU8 start = NULL;
    RPU8 end = NULL;
    RU32 toSkip = 0;
    RU32 longestLength = 0;
    RBOOL isUnicode = FALSE;
    RPU8 sampleNumber = 0;
    rBloom stringsSeen = NULL;
    RU64 readOffset = 0;

    UNREFERENCED_PARAMETER( isTimeToStop );

    if( NULL != modulePath &&
        NULL != pLastScratch )
    {
        readOffset = *pLastScratch * _SCRATCH_SIZE;
        if( NULL != ( stringsSeen = rpal_bloom_create( _MAX_DISK_SAMPLE_SIZE, 0.0001 ) ) )
        {
            if( NULL != ( scratch = rpal_memory_alloc( _SCRATCH_SIZE ) ) )
            {
                if( rFile_open( modulePath, &hFile, RPAL_FILE_OPEN_EXISTING |
                                                    RPAL_FILE_OPEN_READ ) )
                {
                    if( readOffset == rFile_seek( hFile, 
                                                  readOffset, 
                                                  rFileSeek_SET ) &&
                        0 != ( read = rFile_readUpTo( hFile, _SCRATCH_SIZE, scratch ) ) )
                    {
                        if( NULL != ( sample = obsLib_new( _MAX_DISK_SAMPLE_SIZE, 0 ) ) )
                        {
                            ( *pLastScratch )++;
                            start = scratch;
                            end = scratch + read;

                            // We parse for strings up to 'read', we don't care about the 
                            // memory boundary, we might truncate some strings but we're
                            // sampling anyway.
                            while( !rEvent_wait( isTimeToStop, 0 ) &&
                                   ( start >= scratch ) && ( start >= scratch ) &&
                                   ( start + _MIN_SAMPLE_STR_LEN ) < ( scratch + read ) &&
                                   _MAX_DISK_SAMPLE_SIZE >= PTR_TO_NUMBER( sampleNumber ) )
                            {
                                libOs_timeoutWithProfile( perfProfile, TRUE, isTimeToStop );

                                isUnicode = FALSE;

                                if( _longestString( (RPCHAR)start,
                                                    (RU32)( end - start ),
                                                    &toSkip,
                                                    &longestLength,
                                                    &isUnicode ) &&
                                    _MIN_SAMPLE_STR_LEN <= longestLength &&
                                    _MAX_SAMPLE_STR_LEN >= longestLength )
                                {
                                    if( rpal_bloom_addIfNew( stringsSeen,
                                                             start,
                                                             longestLength ) )
                                    {
                                        if( obsLib_addPattern( sample,
                                                               start,
                                                               longestLength,
                                                               sampleNumber ) )
                                        {
                                            sampleNumber++;
                                        }
                                    }
                                }

                                start += toSkip;
                            }
                        }
                    }

                    rFile_close( hFile );
                }

                rpal_memory_free( scratch );
            }

            rpal_bloom_destroy( stringsSeen );
        }
    }

    return sample;
}
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;
}
Пример #19
0
static
rString
    assembleOutboundStream
    (
        RpHcp_ModuleId moduleId,
        rList payload,
        RU8 sessionKey[ CRYPTOLIB_SYM_KEY_SIZE ],
        RU8 sessionIv[ CRYPTOLIB_SYM_IV_SIZE ]
    )
{
    rString str = NULL;

    rSequence hdrSeq = NULL;
    rSequence hcpid = NULL;

    rBlob blob = NULL;

    RPCHAR encoded = NULL;

    RPU8 encBuffer = NULL;
    RU64 encSize = 0;

    RPU8 finalBuffer = NULL;
    RU32 finalSize = 0;

    RPCHAR hostName = NULL;

    RBOOL isSuccess = FALSE;

    OBFUSCATIONLIB_DECLARE( payHdr, RP_HCP_CONFIG_PAYLOAD_HDR );

    str = rpal_stringbuffer_new( 0, 0, FALSE );

    if( NULL != str )
    {
        if( NULL != ( hdrSeq = rSequence_new() ) )
        {
            if( NULL != ( hcpid = hcpIdToSeq( g_hcpContext.currentId ) ) )
            {
                // System basic information
                // Host Name
                if( NULL != ( hostName = libOs_getHostName() ) )
                {
                    rSequence_addSTRINGA( hdrSeq, RP_TAGS_HOST_NAME, hostName );
                    rpal_memory_free( hostName );
                }
                else
                {
                    rpal_debug_warning( "could not determine hostname" );
                }

                // Internal IP
                rSequence_addIPV4( hdrSeq, RP_TAGS_IP_ADDRESS, libOs_getMainIp() );

                if( rSequence_addSEQUENCE( hdrSeq, RP_TAGS_HCP_ID, hcpid ) &&
                    rSequence_addRU8( hdrSeq, RP_TAGS_HCP_MODULE_ID, moduleId ) &&
                    rSequence_addBUFFER( hdrSeq, RP_TAGS_SYM_KEY, sessionKey, CRYPTOLIB_SYM_KEY_SIZE ) &&
                    rSequence_addBUFFER( hdrSeq, RP_TAGS_SYM_IV, sessionIv, CRYPTOLIB_SYM_IV_SIZE ) )
                {
                    if( NULL != g_hcpContext.enrollmentToken &&
                        0 != g_hcpContext.enrollmentTokenSize )
                    {
                        rSequence_addBUFFER( hdrSeq, RP_TAGS_HCP_ENROLLMENT_TOKEN, g_hcpContext.enrollmentToken, g_hcpContext.enrollmentTokenSize );
                    }

                    if( NULL != payload )
                    {
                        blob = rpal_blob_create( 0, 0 );
                    }

                    if( NULL == payload ||
                        NULL != blob )
                    {
                        if( rSequence_serialise( hdrSeq, blob ) &&
                            ( NULL == payload ||
                              rList_serialise( payload, blob ) ) )
                        {
                            encSize = compressBound( rpal_blob_getSize( blob ) );
                            encBuffer = rpal_memory_alloc( (RU32)encSize );

                            if( NULL == payload ||
                                NULL != encBuffer )
                            {
                                if( NULL == payload ||
                                    Z_OK == compress( encBuffer, (uLongf*)&encSize, (RPU8)rpal_blob_getBuffer( blob ), rpal_blob_getSize( blob ) ) )
                                {
                                    FREE_N_NULL( blob, rpal_blob_free );

                                    if( NULL == payload ||
                                        CryptoLib_fastAsymEncrypt( encBuffer, (RU32)encSize, getC2PublicKey(), &finalBuffer, &finalSize ) )
                                    {
                                        FREE_N_NULL( encBuffer, rpal_memory_free );

                                        if( NULL == payload ||
                                            base64_encode( finalBuffer, finalSize, &encoded, TRUE ) )
                                        {
                                            isSuccess = TRUE;

                                            if( NULL != payload )
                                            {
                                                FREE_N_NULL( finalBuffer, rpal_memory_free );

                                                DO_IFF( rpal_stringbuffer_add( str, "&" ), isSuccess );

                                                OBFUSCATIONLIB_TOGGLE( payHdr );

                                                DO_IFF( rpal_stringbuffer_add( str, (RPCHAR)payHdr ), isSuccess );
                                                DO_IFF( rpal_stringbuffer_add( str, encoded ), isSuccess );
                                        
                                                OBFUSCATIONLIB_TOGGLE( payHdr );
                                            }

                                            IF_VALID_DO( encoded, rpal_memory_free );
                                        }

                                        IF_VALID_DO( finalBuffer, rpal_memory_free );
                                    }
                                }

                                IF_VALID_DO( encBuffer, rpal_memory_free );
                            }
                        }

                        IF_VALID_DO( blob, rpal_blob_free );
                    }
                }
            }

            rSequence_free( hdrSeq );
        }

        if( !isSuccess )
        {
            rpal_stringbuffer_free( str );
            str = NULL;
        }
    }

    return str;
}
Пример #20
0
RBOOL
    doBeacon
    (
        RpHcp_ModuleId sourceModuleId,
        rList toSend,
        rList* pReceived
    )
{
    RBOOL isSuccess = FALSE;

    RPU8 receivedData = NULL;
    RU32 receivedSize = 0;

    RPU8 encodedData = NULL;

    RPU8 rawPayloadBuff = NULL;
    RU32 rawPayloadSize = 0;
    
    RU32 zError = 0;
    
    RPU8 signature = NULL;
    RPU8 payloadBuff = NULL;
    RU32 payloadSize = 0;

    RU8 sessionKey[ CRYPTOLIB_SYM_KEY_SIZE ] = {0};
    RU8 sessionIv[ CRYPTOLIB_SYM_IV_SIZE ] = {0};

    rString payloadToSend = NULL;

    RU32 decryptedSize = 0;

    RPU8 tmpBuff = NULL;
    RU64 tmpSize = 0;

    OBFUSCATIONLIB_DECLARE( url1, RP_HCP_CONFIG_HOME_URL_PRIMARY );
    OBFUSCATIONLIB_DECLARE( url2, RP_HCP_CONFIG_HOME_URL_SECONDARY );

    RPCHAR effectivePrimary = (RPCHAR)url1;
    RPCHAR effectiveSecondary = (RPCHAR)url2;

    rpal_debug_info( "called by module %d.", sourceModuleId );

    // Pre-generate the session key and iv we want for the session
    CryptoLib_genRandomBytes( sessionKey, sizeof( sessionKey ) );
    CryptoLib_genRandomBytes( sessionIv, sizeof( sessionIv ) );

    // Assemble the stream to send
    payloadToSend = assembleOutboundStream( sourceModuleId, toSend, sessionKey, sessionIv );

    if( NULL != payloadToSend )
    {
        // Send the beacon
        if( NULL == g_hcpContext.primaryUrl )
        {
            OBFUSCATIONLIB_TOGGLE( url1 );
            OBFUSCATIONLIB_TOGGLE( url2 );
        }
        else
        {
            effectivePrimary = g_hcpContext.primaryUrl;
            effectiveSecondary = g_hcpContext.secondaryUrl;
        }

        if( postHttp( effectivePrimary, 
                      rpal_stringbuffer_getString( payloadToSend ), 
                      FALSE, 
                      (RPVOID*)&receivedData, 
                      &receivedSize ) )
        {
            isSuccess = TRUE;
        }
        else if( postHttp( effectiveSecondary, 
                            rpal_stringbuffer_getString( payloadToSend ), 
                            FALSE, 
                            (RPVOID*)&receivedData, 
                            &receivedSize ) )
        {
            isSuccess = TRUE;
            rpal_debug_info( "beacon using secondary home." );
        }
        else
        {
            rpal_debug_warning( "could not contact server." );
        }

        if( NULL == g_hcpContext.primaryUrl )
        {
            OBFUSCATIONLIB_TOGGLE( url1 );
            OBFUSCATIONLIB_TOGGLE( url2 );
        }

        if( isSuccess )
        {
            isSuccess = FALSE;

            if( NULL != receivedData &&
                0 != receivedSize )
            {
                if( NULL != pReceived )
                {
                    *pReceived = NULL;

                    // Process the data received
                    encodedData = findAndCapEncodedDataInBeacon( receivedData, receivedSize );

                    if( NULL != encodedData )
                    {
                        if( stripBeaconEncoding( (RPCHAR)encodedData, &rawPayloadBuff, &rawPayloadSize ) )
                        {
                            if( rawPayloadSize >= CRYPTOLIB_SIGNATURE_SIZE )
                            {
                                // Verify signature
                                signature = rawPayloadBuff;
                                payloadBuff = signature + CRYPTOLIB_SIGNATURE_SIZE;
                                payloadSize = rawPayloadSize - CRYPTOLIB_SIGNATURE_SIZE;

                                if( verifyC2Signature( payloadBuff, payloadSize, signature ) )
                                {
                                    // Remove the symetric crypto using the session key
                                    if( CryptoLib_symDecrypt( payloadBuff, payloadSize, sessionKey, sessionIv, &decryptedSize ) )
                                    {
                                        // Remove the compression                        
                                        tmpSize = rpal_ntoh32( *(RU32*)payloadBuff );

                                        if( 0 != tmpSize &&
                                                (-1) != tmpSize )
                                        {
                                            tmpBuff = rpal_memory_alloc( (RSIZET)tmpSize );

                                            if( rpal_memory_isValid( tmpBuff ) )
                                            {
                                                if( Z_OK == ( zError = uncompress( tmpBuff, 
                                                                (uLongf*)&tmpSize, 
                                                                payloadBuff + sizeof( RU32 ), 
                                                                payloadSize - sizeof( RU32 ) ) ) )
                                                {
                                                    // Payload is valid, turn it into a sequence to return
                                                    if( rList_deserialise( pReceived, tmpBuff, (RU32)tmpSize, NULL ) )
                                                    {
                                                        rpal_debug_info( "success." );
                                                        isSuccess = TRUE;
                                                    }
                                                    else
                                                    {
                                                        rpal_debug_error( "could not deserialise list." );
                                                    }
                                                }
                                                else
                                                {
                                                    rpal_debug_error( "could not decompress received data: %d (%d bytes).", zError, payloadSize );
                                                }

                                                rpal_memory_free( tmpBuff );
                                            }
                                            else
                                            {
                                                rpal_debug_error( "could not allocate memory for data received, asking for: %d.", tmpSize );
                                            }
                                        }
                                        else
                                        {
                                            rpal_debug_error( "invalid size field in decrypted data." );
                                        }
                                    }
                                    else
                                    {
                                        rpal_debug_error( "failed to decrypt received data." );
                                    }
                                }
                                else
                                {
                                    rpal_debug_error( "signature verification failed." );
                                }
                            }
                            else
                            {
                                rpal_debug_error( "stripped payload failed sanity check." );
                            }
                            
                            rpal_memory_free( rawPayloadBuff );
                        }
                        else
                        {
                            rpal_debug_error( "could not strip BASE64 encoding." );
                        }
                    }
                    else
                    {
                        rpal_debug_error( "could not find the encoded data." );
                    }
                }
                else
                {
                    rpal_debug_info( "not interested in the returned data." );
                    isSuccess = TRUE;
                }

                FREE_AND_NULL( receivedData );
                receivedSize = 0;
            }
            else
            {
                rpal_debug_warning( "no data received from the server." );
                isSuccess = FALSE;
            }
        }

        rpal_stringbuffer_free( payloadToSend );
    }
    else
    {
        rpal_debug_error( "failed to generate payload for beacon." );
    }

    return isSuccess;
}
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;
}
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;
}
Пример #23
0
RBOOL
    processMessage
    (
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;
    RU8 command = 0;
    rSequence idSeq = NULL;
    rpHCPId tmpId = { 0 };
    rpHCPId emptyId = { 0 };
    RU64 tmpTime = 0;
    rThread hQuitThread = 0;

    rpHCPIdentStore identStore = {0};
    RPU8 token = NULL;
    RU32 tokenSize = 0;

    OBFUSCATIONLIB_DECLARE( store, RP_HCP_CONFIG_IDENT_STORE );

    if( NULL != seq )
    {
        if( rSequence_getRU8( seq, RP_TAGS_OPERATION, &command ) )
        {
            rpal_debug_info( "Received command 0x%0X.", command );
            switch( command )
            {
            case RP_HCP_COMMAND_LOAD_MODULE:
                isSuccess = loadModule( &g_hcpContext, seq );
                break;
            case RP_HCP_COMMAND_UNLOAD_MODULE:
                isSuccess = unloadModule( &g_hcpContext, seq );
                break;
            case RP_HCP_COMMAND_SET_HCP_ID:
                if( rSequence_getSEQUENCE( seq, RP_TAGS_HCP_IDENT, &idSeq ) )
                {
                    tmpId = seqToHcpId( idSeq );

                    if( 0 != rpal_memory_memcmp( &emptyId, &tmpId, sizeof( emptyId ) ) )
                    {
                        g_hcpContext.currentId = tmpId;
                        
                        OBFUSCATIONLIB_TOGGLE( store );
                        
                        if( rSequence_getBUFFER( seq, RP_TAGS_HCP_ENROLLMENT_TOKEN, &token, &tokenSize ) )
                        {
                            identStore.agentId = tmpId;

                            if( saveHcpId( (RPNCHAR)store, &identStore, token, tokenSize ) )
                            {
                                isSuccess = TRUE;
                            }

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

                            if( NULL != ( g_hcpContext.enrollmentToken = rpal_memory_alloc( tokenSize ) ) )
                            {
                                rpal_memory_memcpy( g_hcpContext.enrollmentToken, token, tokenSize );
                                g_hcpContext.enrollmentTokenSize = tokenSize;

                                isSuccess = TRUE;
                            }
                        }
                        else
                        {
                            rpal_debug_warning( "hcp id is missing token" );
                        }

                        OBFUSCATIONLIB_TOGGLE( store );
                    }
                }
                break;
            case RP_HCP_COMMAND_SET_GLOBAL_TIME:
                if( rSequence_getTIMESTAMP( seq, RP_TAGS_TIMESTAMP, &tmpTime ) )
                {
                    rpal_time_setGlobalOffset( tmpTime - rpal_time_getLocal() );
                    isSuccess = TRUE;
                }
                break;
            case RP_HCP_COMMAND_QUIT:
                if( 0 != ( hQuitThread = rpal_thread_new( thread_quitAndCleanup, NULL ) ) )
                {
                    rpal_thread_free( hQuitThread );
                    isSuccess = TRUE;
                }
                break;
            case RP_HCP_COMMAND_UPGRADE:
                isSuccess = upgradeHcp( seq );
                break;
            default:
                break;
            }

            if( isSuccess )
            {
                rpal_debug_info( "Command was successful." );
            }
            else
            {
                rpal_debug_warning( "Command was not successful." );
            }
        }
    }

    return isSuccess;
}
Пример #24
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 RBOOL
    getSnapshot
    (
        processEntry* toSnapshot
    )
{
    RBOOL isSuccess = FALSE;
    RU32 i = 0;

    if( NULL != toSnapshot )
    {
        rpal_memory_zero( toSnapshot, sizeof( g_snapshot_1 ) );
    }

    if( NULL != toSnapshot )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        HANDLE hSnapshot = NULL;
        PROCESSENTRY32W procEntry = { 0 };
        procEntry.dwSize = sizeof( procEntry );

        if( INVALID_HANDLE_VALUE != ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) )
        {
            if( Process32FirstW( hSnapshot, &procEntry ) )
            {
                isSuccess = TRUE;

                do
                {
                    if( 0 == procEntry.th32ProcessID )
                    {
                        continue;
                    }

                    toSnapshot[ i ].pid = procEntry.th32ProcessID;
                    toSnapshot[ i ].ppid = procEntry.th32ParentProcessID;
                    i++;
                } while( Process32NextW( hSnapshot, &procEntry ) &&
                         MAX_SNAPSHOT_SIZE > i );
            }

            CloseHandle( hSnapshot );
        }
#elif defined( RPAL_PLATFORM_LINUX )
        RWCHAR procDir[] = _WCH( "/proc/" );
        rDir hProcDir = NULL;
        rFileInfo finfo = {0};

        if( rDir_open( (RPWCHAR)&procDir, &hProcDir ) )
        {
            isSuccess = TRUE;

            while( rDir_next( hProcDir, &finfo ) &&
                   MAX_SNAPSHOT_SIZE > i )
            {
                if( rpal_string_wtoi( (RPWCHAR)finfo.fileName, &( toSnapshot[ i ].pid ) )
                    && 0 != toSnapshot[ i ].pid )
                {
                    i++;
                }
            }

            rDir_close( hProcDir );
        }
#elif defined( RPAL_PLATFORM_MACOSX )
        int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
        struct kinfo_proc* infos = NULL;
        size_t size = 0;
        int ret = 0;
        int j = 0;

        if( 0 == ( ret = sysctl( mib, ARRAY_N_ELEM( mib ), infos, &size, NULL, 0 ) ) )
        {
            if( NULL != ( infos = rpal_memory_alloc( size ) ) )
            {
                while( 0 != ( ret = sysctl( mib, ARRAY_N_ELEM( mib ), infos, &size, NULL, 0 ) ) && ENOMEM == errno )
                {
                    if( NULL == ( infos = rpal_memory_realloc( infos, size ) ) )
                    {
                        break;
                    }
                }
            }
        }

        if( 0 == ret && NULL != infos )
        {
            isSuccess = TRUE;
            size = size / sizeof( struct kinfo_proc );
            for( j = 0; j < size; j++ )
            {
                toSnapshot[ i ].pid = infos[ j ].kp_proc.p_pid;
                toSnapshot[ i ].ppid = infos[ j ].kp_eproc.e_ppid;
                i++;
            }

            if( NULL != infos )
            {
                rpal_memory_free( infos );
                infos = NULL;
            }
        }
#endif
    }

    return isSuccess;
}