RPRIVATE_TESTABLE RBOOL loadModule ( rpHCPContext* hcpContext, rSequence seq ) { RBOOL isSuccess = FALSE; RU32 moduleIndex = (RU32)(-1); RPU8 tmpBuff = NULL; RU32 tmpSize = 0; RPU8 tmpSig = NULL; RU32 tmpSigSize = 0; rpal_thread_func pEntry = NULL; rpHCPModuleContext* modContext = NULL; OBFUSCATIONLIB_DECLARE( entryName, RP_HCP_CONFIG_MODULE_ENTRY ); OBFUSCATIONLIB_DECLARE( recvMessage, RP_HCP_CONFIG_MODULE_RECV_MESSAGE ); if( NULL != seq && NULL != hcpContext ) { for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ ) { if( 0 == hcpContext->modules[ moduleIndex ].hThread ) { // Found an empty spot break; } } } if( RP_HCP_CONTEXT_MAX_MODULES != moduleIndex && (RU32)(-1) != moduleIndex ) { // We got an empty spot for our module if( rSequence_getRU8( seq, RP_TAGS_HCP_MODULE_ID, &(hcpContext->modules[ moduleIndex ].id ) ) && rSequence_getBUFFER( seq, RP_TAGS_BINARY, &tmpBuff, &tmpSize ) && rSequence_getBUFFER( seq, RP_TAGS_SIGNATURE, &tmpSig, &tmpSigSize ) && CRYPTOLIB_SIGNATURE_SIZE == tmpSigSize ) { // We got the data, now verify the buffer signature if( CryptoLib_verify( tmpBuff, tmpSize, getRootPublicKey(), tmpSig ) ) { // Ready to load the module rpal_debug_info( "loading module in memory" ); hcpContext->modules[ moduleIndex ].hModule = MemoryLoadLibrary( tmpBuff, tmpSize ); if( NULL != hcpContext->modules[ moduleIndex ].hModule ) { OBFUSCATIONLIB_TOGGLE( entryName ); pEntry = (rpal_thread_func)MemoryGetProcAddress( hcpContext->modules[ moduleIndex ].hModule, (RPCHAR)entryName ); OBFUSCATIONLIB_TOGGLE( entryName ); if( NULL != pEntry ) { modContext = &(hcpContext->modules[ moduleIndex ].context); modContext->pCurrentId = &( hcpContext->currentId ); modContext->func_sendHome = doSend; modContext->isTimeToStop = rEvent_create( TRUE ); modContext->rpalContext = rpal_Context_get(); modContext->isOnlineEvent = hcpContext->isCloudOnline; if( NULL != modContext->isTimeToStop ) { hcpContext->modules[ moduleIndex ].isTimeToStop = modContext->isTimeToStop; OBFUSCATIONLIB_TOGGLE( recvMessage ); hcpContext->modules[ moduleIndex ].func_recvMessage = (rpHCPModuleMsgEntry)MemoryGetProcAddress( hcpContext->modules[ moduleIndex ].hModule, (RPCHAR)recvMessage ); OBFUSCATIONLIB_TOGGLE( recvMessage ); hcpContext->modules[ moduleIndex ].hThread = rpal_thread_new( pEntry, modContext ); if( 0 != hcpContext->modules[ moduleIndex ].hThread ) { CryptoLib_hash( tmpBuff, tmpSize, &(hcpContext->modules[ moduleIndex ].hash ) ); hcpContext->modules[ moduleIndex ].isOsLoaded = FALSE; isSuccess = TRUE; } else { rpal_debug_warning( "Error creating handler thread for new module." ); } } } else { rpal_debug_warning( "Could not find new module's entry point." ); } } else { rpal_debug_warning( "Error loading module in memory." ); } } else { rpal_debug_warning( "New module signature invalid." ); } } else { rpal_debug_warning( "Could not find core module components to load." ); } // Main cleanup if( !isSuccess ) { if( NULL != modContext ) { IF_VALID_DO( modContext->isTimeToStop, rEvent_free ); } if( NULL != hcpContext->modules[ moduleIndex ].hModule ) { MemoryFreeLibrary( hcpContext->modules[ moduleIndex ].hModule ); } rpal_memory_zero( &(hcpContext->modules[ moduleIndex ] ), sizeof( hcpContext->modules[ moduleIndex ] ) ); } } else { rpal_debug_error( "Could not find a spot for new module, or invalid module id!" ); } return isSuccess; }
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; }