static void tracing_proc_start(procmod_Callback_Params * params) { /* If tracingbyname, check if this is the process to trace. If so, start the trace */ if (procname_is_set()) { if (procname_match(params->lmm.name)) { uint32_t pid = params->lmm.pid; // Start tracing do_tracing_internal(pid, tracefile); monitor_printf(default_mon, "Tracing %s\n", procname_get()); // No need to keep monitoring process name procname_clear(); } } /* If tracing child and first child then trace child instead of parent and enable logging */ if (tracing_child && trackproc_found_child()) { uint32_t curr_pid = trackproc_get_current_pid(); if ((trackproc_find_pid(curr_pid) != -1) && (curr_pid != trackproc_get_root_pid())) { uint32_t child_cr3 = find_cr3(curr_pid); if (0 == child_cr3) { monitor_printf(default_mon, "CR3 for child process %d not found\n",curr_pid); } else { decaf_plugin->monitored_cr3 = child_cr3; tracepid = curr_pid; tracecr3 = child_cr3; monitor_printf(default_mon, "Now tracing child process. PID: %d CR3: 0x%08x\n", curr_pid, child_cr3); skip_trace_write = 0; tracing_child = 0; } } } }
static status_t vmi_init_private( vmi_instance_t *vmi, uint32_t flags, unsigned long id, char *name, vmi_config_t *config) { uint32_t access_mode = flags & 0x0000FFFF; uint32_t init_mode = flags & 0x00FF0000; uint32_t config_mode = flags & 0xFF000000; status_t status = VMI_FAILURE; /* allocate memory for instance structure */ *vmi = (vmi_instance_t) safe_malloc(sizeof(struct vmi_instance)); memset(*vmi, 0, sizeof(struct vmi_instance)); /* initialize instance struct to default values */ dbprint("LibVMI Version 0.9_alpha\n"); //TODO change this with each release /* save the flags and init mode */ (*vmi)->flags = flags; (*vmi)->init_mode = init_mode; (*vmi)->config = config; (*vmi)->config_mode = config_mode; /* setup the caches */ pid_cache_init(*vmi); sym_cache_init(*vmi); rva_cache_init(*vmi); v2p_cache_init(*vmi); /* connecting to xen, kvm, file, etc */ if (VMI_FAILURE == set_driver_type(*vmi, access_mode, id, name)) { goto error_exit; } /* resolve the id and name */ if (VMI_FAILURE == set_id_and_name(*vmi, access_mode, id, name)) { goto error_exit; } /* driver-specific initilization */ if (VMI_FAILURE == driver_init(*vmi)) { goto error_exit; } dbprint("--completed driver init.\n"); /* we check VMI_INIT_COMPLETE first as VMI_INIT_PARTIAL is not exclusive */ if (init_mode & VMI_INIT_COMPLETE) { /* init_complete requires configuration */ if(VMI_CONFIG_NONE & (*vmi)->config_mode) { /* falling back to VMI_CONFIG_GLOBAL_FILE_ENTRY is unsafe here as the config pointer is probably NULL */ goto error_exit; } /* read and parse the config file */ else if ( (VMI_CONFIG_STRING & (*vmi)->config_mode || VMI_CONFIG_GLOBAL_FILE_ENTRY & (*vmi)->config_mode) && VMI_FAILURE == read_config_file(*vmi)) { goto error_exit; } /* read and parse the ghashtable */ else if (VMI_CONFIG_GHASHTABLE & (*vmi)->config_mode && VMI_FAILURE == read_config_ghashtable(*vmi)) { dbprint("--failed to parse ghashtable\n"); goto error_exit; } /* setup the correct page offset size for the target OS */ if (VMI_FAILURE == init_page_offset(*vmi)) { goto error_exit; } /* get the memory size */ if (driver_get_memsize(*vmi, &(*vmi)->size) == VMI_FAILURE) { errprint("Failed to get memory size.\n"); goto error_exit; } dbprint("**set size = %"PRIu64" [0x%"PRIx64"]\n", (*vmi)->size, (*vmi)->size); /* determine the page sizes and layout for target OS */ // Find the memory layout. If this fails, then proceed with the // OS-specific heuristic techniques. (*vmi)->pae = (*vmi)->pse = (*vmi)->lme = (*vmi)->cr3 = 0; (*vmi)->page_mode = VMI_PM_UNKNOWN; status = get_memory_layout(*vmi, &((*vmi)->page_mode), &((*vmi)->cr3), &((*vmi)->pae), &((*vmi)->pse), &((*vmi)->lme)); if (VMI_FAILURE == status) { dbprint ("**Failed to get memory layout for VM. Trying heuristic method.\n"); // fall-through } // if // Heuristic method if (!(*vmi)->cr3) { (*vmi)->cr3 = find_cr3((*vmi)); dbprint("**set cr3 = 0x%.16"PRIx64"\n", (*vmi)->cr3); } // if /* setup OS specific stuff */ if (VMI_OS_LINUX == (*vmi)->os_type) { status = linux_init(*vmi); } else if (VMI_OS_WINDOWS == (*vmi)->os_type) { status = windows_init(*vmi); } /* Enable event handlers only if we're in a consistent state */ if((status == VMI_SUCCESS) && (init_mode & VMI_INIT_EVENTS)){ events_init(*vmi); } return status; } else if (init_mode & VMI_INIT_PARTIAL) { init_page_offset(*vmi); driver_get_memsize(*vmi, &(*vmi)->size); /* Enable event handlers */ if(init_mode & VMI_INIT_EVENTS){ events_init(*vmi); } return VMI_SUCCESS; } error_exit: return status; }
int tracing_start(uint32_t pid, const char *filename) { /* Copy trace filename to global variable */ strncpy(tracename, filename, 128); /* Set name for functions file */ snprintf(functionsname, 128, "%s.functions", filename); /* If previous trace did not close properly, close files now */ if (tracelog) close_trace(tracelog); if (tracenetlog) fclose(tracenetlog); /* Initialize trace file */ tracelog = fopen(filename, "w"); if (0 == tracelog) { perror("tracing_start"); tracepid = 0; tracecr3 = 0; return -1; } setvbuf(tracelog, filebuf, _IOFBF, FILEBUFSIZE); /* Initialize netlog file */ char netname[128]; snprintf(netname, 128, "%s.netlog", filename); tracenetlog = fopen(netname, "w"); if (0 == tracenetlog) { perror("tracing_start"); tracepid = 0; tracecr3 = 0; return -1; } else { fprintf(tracenetlog, "Flow Off Data\n"); fflush(tracenetlog); } /* Set PID and CR3 of the process to be traced */ tracecr3 = find_cr3(pid); if (0 == tracecr3) { monitor_printf(default_mon, "CR3 for PID %d not found. Tracing all processes!\n",pid); tracepid = -1; } else { tracepid = pid; } monitor_printf(default_mon, "PID: %d CR3: 0x%08x\n", tracepid, tracecr3); /* Initialize disassembler */ xed2_init(); /* Clear trace statistics */ clear_trace_stats(); /* Clear skip taint flags */ init_st(); /* Initialize hooks only for this process */ decaf_plugin->monitored_cr3 = tracecr3; /* Get system start usage */ if (getrusage(RUSAGE_SELF, &startUsage) != 0) monitor_printf (default_mon, "Could not get start usage\n"); // If tracing child, load process tracking hooks if (tracing_child) { trackproc_start(pid); load_hooks_in_plugin(&tracecr3, "group_process.so", hook_dirname); } /* Register block and instruction callbacks */ block_begin_cb_handle = DECAF_register_callback(DECAF_BLOCK_BEGIN_CB, tracing_block_begin, NULL); insn_begin_cb_handle = DECAF_register_callback(DECAF_INSN_BEGIN_CB, tracing_insn_begin, &should_monitor); insn_end_cb_handle = DECAF_register_callback(DECAF_INSN_END_CB, tracing_insn_end, &should_monitor); return 0; }