// // restart_tasks // void restart_tasks (CUTS::Task_Manager_ptr daemon) { VERBOSE_MESSAGE ((LM_INFO, "restarting %d tasks\n", CLIENT_OPTIONS ()->restart_list_.size ())); ACE_Unbounded_Set <ACE_CString>:: const_iterator iter (CLIENT_OPTIONS ()->restart_list_); CORBA::String_var taskname; for ( ; !iter.done (); iter ++) { VERBOSE_MESSAGE ((LM_INFO, "terminating task <%s>\n", (*iter).c_str ())); taskname = CORBA::string_dup ((*iter).c_str ()); if (daemon->task_restart (taskname.in ()) == 0) { VERBOSE_MESSAGE ((LM_INFO, "successfully restarted task <%s>\n", (*iter).c_str ())); } else { ACE_ERROR ((LM_ERROR, "failed to restart task <%s>\n", (*iter).c_str ())); } } }
bool process_attach() { int rununder_mask; int should_inject; bool takeover = true; #if VERBOSE int len; char exename[MAX_PATH]; #endif /* FIXME: append to event log to indicate we're in the address space */ VERBOSE_MESSAGE("inside preinject dll\n"); ntdll_init(); #ifndef PARAMS_IN_REGISTRY /* i#85/PR 212034: use config files */ config_init(); #endif #if VERBOSE len = GetModuleFileName(NULL, exename, MAX_PATH); ASSERT(len > 0); #endif #if 0 /* PR 314367: re-enable once it all works */ # ifndef X64 /* PR 253431: one method of injecting 64-bit DR into a WOW64 process is * via 32-bit AppInit drpreinject. * x64 configuration takes precedence over wow64. */ if (is_wow64_process(NT_CURRENT_PROCESS)) { should_inject = systemwide_should_preinject_64(NULL, &rununder_mask); if (((INJECT_TRUE & should_inject) != 0) && ((INJECT_EXPLICIT & should_inject) == 0) && !is_safe_mode() && parameters_present(true)) { VERBOSE_MESSAGE("<"PRODUCT_NAME" is taking over process %d (%s) as x64>\n", GetCurrentProcessId(), exename); check_for_run_once(NULL, rununder_mask); /* we commit to x64 takeover based on there being a positive * rununder setting and an AUTOINJECT entry. if the AUTOINJECT * turns out to be invalid, we'll try the 32-bit. */ takeover = !load_dynamorio_lib(true); } } # endif #endif /* 0 */ if (takeover) { should_inject = systemwide_should_preinject(NULL, &rununder_mask); if (((INJECT_TRUE & should_inject) == 0) || ((INJECT_EXPLICIT & should_inject) != 0) || is_safe_mode() || !parameters_present(IF_NOT_X64(false))) { /* not taking over */ VERBOSE_MESSAGE(PRODUCT_NAME " is NOT taking over process %d (%s)\n", GetCurrentProcessId(), exename); } else { /* yes, load in dynamo to take over! */ VERBOSE_MESSAGE("<" PRODUCT_NAME " is taking over process %d (%s)>\n", GetCurrentProcessId(), exename); check_for_run_once(NULL, rununder_mask); load_dynamorio_lib(IF_NOT_X64(false)); } } ntdll_exit(); /* i#1522: self-unloading messes up the win8+ loader so we return false instead */ if (running_on_win8_or_later()) return false; else return true; }
static bool load_dynamorio_lib(IF_NOT_X64(bool x64_in_wow64)) { HMODULE dll = NULL; char path[MAX_PATH]; #ifdef DEBUG char msg[3 * MAX_PATH]; #endif int retval = -1; /* failure */ #ifndef X64 bool wow64 = is_wow64_process(NT_CURRENT_PROCESS); if (x64_in_wow64) { ASSERT(wow64); retval = get_parameter_64(PARAM_STR(DYNAMORIO_VAR_AUTOINJECT), path, MAX_PATH); } else #endif retval = get_parameter(PARAM_STR(DYNAMORIO_VAR_AUTOINJECT), path, MAX_PATH); if (IS_GET_PARAMETER_SUCCESS(retval)) { dr_marker_t mark; VERBOSE_MESSAGE("Loading \"%hs\"", path); /* The read_and_verify_dr_marker is the canonical check for dr in a * process, we double check against GetModuleHandle here just to be * extra safe (in case dr failed to initialize before). Note that * GetModuleHandle won't find dr's dll if we implement certian -hide * or early_injection proposals. */ if (read_and_verify_dr_marker(GetCurrentProcess(), &mark) != DR_MARKER_FOUND && GetModuleHandle(DYNAMORIO_LIBRARY_NAME) == NULL #ifndef X64 /* these ifdefs are rather ugly: just export all routines in x64 builds? */ && /* check for 64-bit as well */ (!wow64 || read_and_verify_dr_marker_64(GetCurrentProcess(), &mark) != DR_MARKER_FOUND) /* FIXME PR 251677: need 64-bit early injection to fully test * read_and_verify_dr_marker_64 */ #endif ) { /* OK really going to load dr now, verify that we are injecting * early enough (i.e. user32.dll is statically linked). This * presumes preinject is only used with app_init injection which is * currently the case. FIXME - should we also check_sole_thread * here? We can't really handle more then one thread when dr is * loading, but this can happen with early remote injected threads * many of which (CTRL) are relatively harmless. */ LDR_MODULE *mod = get_ldr_module_by_name(L"user32.dll"); ASSERT(mod != NULL); if (ldr_module_statically_linked(mod)) { #ifndef X64 if (x64_in_wow64) dll = load_library_64(path); else #endif dll = LoadLibrary(path); } else { /* FIXME - would be really nice to communicate this back to * the controller. */ #ifdef DEBUG _snprintf(msg, BUFFER_SIZE_ELEMENTS(msg), PRODUCT_NAME " Error: improper injection - " PRODUCT_NAME " (%s) can't inject into process %s (%s) (user32.dll " "not statically linked)\n", path, get_application_name(), get_application_pid()); NULL_TERMINATE_BUFFER(msg); display_error(msg); #endif } } else { /* notify failure only in debug builds, otherwise just return */ #ifdef DEBUG /* with early injection this becomes even more likely */ if (read_and_verify_dr_marker(GetCurrentProcess(), &mark) == DR_MARKER_FOUND # ifndef X64 || (wow64 && read_and_verify_dr_marker_64(GetCurrentProcess(), &mark) == DR_MARKER_FOUND) # endif ) { /* ok, early injection should always beat this */ # if VERBOSE /* can't readily tell what was expected */ _snprintf(msg, BUFFER_SIZE_ELEMENTS(msg), PRODUCT_NAME " ok if early injection, otherwise ERROR: " "double injection, " PRODUCT_NAME " (%s) is already loaded " "in process %s (%s), continuing\n", path, get_application_name(), get_application_pid()); NULL_TERMINATE_BUFFER(msg); display_error(msg); # endif /* VERBOSE */ } else { /* if GetModuleHandle finds us but we don't have a marker * we may have failed somehow */ _snprintf(msg, BUFFER_SIZE_ELEMENTS(msg), PRODUCT_NAME " Error: failed injection, " PRODUCT_NAME " (%s) is " "loaded but not initialized in process %s (%s), continuing\n", path, get_application_name(), get_application_pid()); NULL_TERMINATE_BUFFER(msg); display_error(msg); } #endif /* DEBUG */ return false; } } else path[0] = 0; if (dll == NULL) { #ifdef DEBUG int err = GetLastError(); _snprintf(msg, BUFFER_SIZE_ELEMENTS(msg), PRODUCT_NAME " Error %d loading %s\n", err, path); NULL_TERMINATE_BUFFER(msg); display_error(msg); #endif return false; } else { int_func_t init_func; void_func_t take_over_func; int res; #ifndef X64 if (x64_in_wow64) { init_func = (int_func_t)(ptr_uint_t) /*we know <4GB*/ get_proc_address_64((uint64)dll, "dynamorio_app_init"); take_over_func = (void_func_t)(ptr_uint_t) /*we know <4GB*/ get_proc_address_64((uint64)dll, "dynamorio_app_take_over"); VERBOSE_MESSAGE("dynamorio_app_init: 0x%08x; dynamorio_app_take_over: " "0x%08x\n", init_func, take_over_func); } else { #endif init_func = (int_func_t)GetProcAddress(dll, "dynamorio_app_init"); take_over_func = (void_func_t)GetProcAddress(dll, "dynamorio_app_take_over"); #ifndef X64 } #endif if (init_func == NULL || take_over_func == NULL) { /* unload the library so that it's clear DR is not in control * (o/w the DR library is in the process and it's not clear * what's going on) */ #ifndef X64 if (x64_in_wow64) { # ifdef DEBUG bool ok = # endif free_library_64(dll); ASSERT(ok); } else #endif FreeLibrary(dll); #ifdef DEBUG display_error("Error getting " PRODUCT_NAME " functions\n"); #endif return false; } VERBOSE_MESSAGE("about to inject dynamorio"); #ifndef X64 if (x64_in_wow64) res = switch_modes_and_call(init_func, NULL, NULL, NULL); else #endif res = (*init_func)(); VERBOSE_MESSAGE("dynamorio_app_init() returned %d\n", res); #ifndef X64 if (x64_in_wow64) switch_modes_and_call(take_over_func, NULL, NULL, NULL); else #endif (*take_over_func)(); VERBOSE_MESSAGE("inside " PRODUCT_NAME " now\n"); } return true; }
// // main // int main (int argc, char * argv []) { try { // initalize the ORB CORBA::ORB_var orb = CORBA::ORB_init (argc, argv); if (parse_args (argc, argv) != 0) return 1; // Resolve the initiale reference to the Node_Daemon VERBOSE_MESSAGE ((LM_DEBUG, "resolving initial reference to NodeDaemon\n")); ::CORBA::Object_var obj = orb->resolve_initial_references ("NodeDaemon"); ::CORBA::String_var strobj = orb->object_to_string (obj.in ()); if (::CORBA::is_nil (obj.in ())) { ACE_ERROR_RETURN (( LM_ERROR, "failed to resolved initial reference to NodeDaemon\n"), 1); } // Narrow the generic object to a CUTS/Node_Daemon object. VERBOSE_MESSAGE ((LM_DEBUG, "extracting node daemon from object reference\n")); CUTS::Task_Manager_var daemon = CUTS::Task_Manager::_narrow (obj.in ()); if (::CORBA::is_nil (daemon.in ())) { ACE_ERROR_RETURN ((LM_ERROR, "object was not a %s\n", daemon->_interface_repository_id ()), 1); } // Spawn the specified task. if (ACE_OS::strlen (CLIENT_OPTIONS ()->task_start_.id.in ()) != 0 && ACE_OS::strlen (CLIENT_OPTIONS ()->task_start_.executable.in ()) != 0) { daemon->task_spawn (CLIENT_OPTIONS ()->task_start_); } // Terminate all the specified tasks. terminate_tasks (daemon.in ()); // Restart all the specified tasks. restart_tasks (daemon.in ()); if (CLIENT_OPTIONS ()->reset_) daemon->reset (); // Destroy the ORB. VERBOSE_MESSAGE ((LM_DEBUG, "destroying the ORB\n")); orb->destroy (); return 0; } catch (::CORBA::Exception & ex) { ACE_ERROR ((LM_ERROR, "%s\n", ex._info ().c_str ())); } catch (...) { ACE_ERROR ((LM_ERROR, "*** error: caught unknown exception\n")); } return 1; }