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; }
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, ®ion ) ) { 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, ®ion ) ) { 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; }