bool init_plugin(void *self) { printf("Initializing taint plugin\n"); plugin_ptr = self; panda_cb pcb; panda_enable_memcb(); panda_disable_tb_chaining(); pcb.guest_hypercall = guest_hypercall_callback; panda_register_callback(self, PANDA_CB_GUEST_HYPERCALL, pcb); pcb.before_block_exec_invalidate_opt = before_block_exec_invalidate_opt; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC_INVALIDATE_OPT, pcb); /* pcb.replay_handle_packet = handle_packet; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_HANDLE_PACKET, pcb); */ panda_arg_list *args = panda_get_args("taint2"); tainted_pointer = !panda_parse_bool(args, "no_tp"); inline_taint = panda_parse_bool(args, "inline"); if (inline_taint) { printf("taint2: Inlining taint ops by default.\n"); } else { printf("taint2: Instructed not to inline taint ops.\n"); } if (panda_parse_bool(args, "binary")) mode = TAINT_BINARY_LABEL; if (panda_parse_bool(args, "word")) granularity = TAINT_GRANULARITY_WORD; optimize_llvm = panda_parse_bool(args, "opt"); panda_require("callstack_instr"); assert(init_callstack_instr_api()); return true; }
bool init_plugin(void *self) { #if defined(TARGET_I386) if (cs_open(CS_ARCH_X86, CS_MODE_32, &cs_handle_32) != CS_ERR_OK) #if defined(TARGET_X86_64) if (cs_open(CS_ARCH_X86, CS_MODE_64, &cs_handle_64) != CS_ERR_OK) #endif #elif defined(TARGET_ARM) if (cs_open(CS_ARCH_ARM, CS_MODE_ARM, &cs_handle_32) != CS_ERR_OK) #elif defined(TARGET_PPC) if (cs_open(CS_ARCH_PPC, CS_MODE_32, &cs_handle_32) != CS_ERR_OK) #endif return false; // Need details in capstone to have instruction groupings cs_option(cs_handle_32, CS_OPT_DETAIL, CS_OPT_ON); #if defined(TARGET_X86_64) cs_option(cs_handle_64, CS_OPT_DETAIL, CS_OPT_ON); #endif panda_cb pcb; panda_enable_memcb(); panda_enable_precise_pc(); pcb.after_block_translate = after_block_translate; panda_register_callback(self, PANDA_CB_AFTER_BLOCK_TRANSLATE, pcb); pcb.after_block_exec = after_block_exec; panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb); pcb.before_block_exec = before_block_exec; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); return true; }
bool init_plugin(void *self) { panda_cb pcb; printf("Initializing plugin memstrings\n"); panda_arg_list *args = panda_get_args("memstrings"); const char *prefix = panda_parse_string(args, "name", "memstrings"); min_strlen = panda_parse_ulong(args, "len", 4); char matchfile[128] = {}; sprintf(matchfile, "%s_strings.txt.gz", prefix); mem_report = gzopen(matchfile, "w"); if(!mem_report) { printf("Couldn't write report:\n"); perror("fopen"); return false; } // Need this to get EIP with our callbacks panda_enable_precise_pc(); // Enable memory logging panda_enable_memcb(); pcb.virt_mem_write = mem_write_callback; panda_register_callback(self, PANDA_CB_VIRT_MEM_WRITE, pcb); pcb.virt_mem_read = mem_read_callback; panda_register_callback(self, PANDA_CB_VIRT_MEM_READ, pcb); return true; }
bool init_plugin(void *self) { int i; char *sclog_filename = NULL; args = panda_get_args("syscalls"); if (args != NULL) { for (i = 0; i < args->nargs; i++) { // Format is syscall:file=<file> if (0 == strncmp(args->list[i].key, "file", 4)) { sclog_filename = args->list[i].value; } } } if (!sclog_filename) { fprintf(stderr, "warning: Plugin 'syscalls' uses argument: -panda-arg syscalls:file=<file>\nusing default log file %s\n", DEFAULT_LOG_FILE); char *scdef=new char[strlen(DEFAULT_LOG_FILE)+1]; strcpy(scdef,DEFAULT_LOG_FILE); sclog_filename=scdef; } plugin_log = fopen(sclog_filename, "w"); if(!plugin_log) { fprintf(stderr, "Couldn't open %s. Abort.\n",sclog_filename); return false; } // Don't bother if we're not on a supported target #if defined(TARGET_I386) || defined(TARGET_ARM) panda_cb pcb; pcb.insn_translate = translate_callback; panda_register_callback(self, PANDA_CB_INSN_TRANSLATE, pcb); pcb.insn_exec = exec_callback; panda_register_callback(self, PANDA_CB_INSN_EXEC, pcb); pcb.before_block_exec_invalidate_opt = returned_check_callback; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC_INVALIDATE_OPT, pcb); #else fwrite(stderr,"The syscalls plugin is not currently supported on this platform.\n"); return false; #endif #if defined(TARGET_ARM) syscalls::register_call_fork(vmi_fork_callback); syscalls::register_call_execve(vmi_execve_callback); syscalls::register_call_do_mmap2(vmi_do_mmap2_callback); syscalls::register_call_sys_prctl(vmi_sys_prctl_callback); syscalls::register_call_clone(vmi_clone_callback); #endif syscalls_plugin_self = self; return true; }
// this is called from stringsearch upon a match void tstringsearch_match(CPUState *env, target_ulong pc, target_ulong addr, uint8_t *matched_string, uint32_t matched_string_length, bool is_write) { // determine if the search string is sitting in memory, starting at addr - (strlen-1) // first, grab that string out of memory target_ulong p = addr - (matched_string_length-1); uint8_t thestring[MAX_STRLEN*2]; panda_virtual_memory_rw(env, p, thestring, matched_string_length, 0); printf ("tstringsearch: thestring = ["); for (unsigned i=0; i<matched_string_length; i++) { if (isprint(thestring[i])) { printf("%c", thestring[i]); } else { printf("."); } } printf ("]\ntstringsearch: "); for (unsigned i=0; i<matched_string_length; i++) { printf ("%02x ", thestring[i]); } printf ("\n"); // now compare it to the search string // NOTE: this is a write, so the final byte of the string hasn't yet been // written to memory since write callback is at start of fn. // thus, the matched_string_length - 1. // yes, we can get this right. but, meh. if ((memcmp((char *)thestring, (char *)matched_string, matched_string_length-1)) == 0) { printf ("tstringsearch: string in memory @ 0x%lx\n", (long unsigned int) p); // ok this is ugly. save pc, buffer addr and len the_pc = pc; the_buf = p; the_len = matched_string_length; // this should enable tstringsearch_label_on = true; if (first_time) { first_time = false; // add a callback for taint processor st panda_cb pcb; pcb.phys_mem_before_read = tstringsearch_label; panda_register_callback(plugin_self, PANDA_CB_PHYS_MEM_BEFORE_READ, pcb); pcb.phys_mem_after_write = tstringsearch_label_write; panda_register_callback(plugin_self, PANDA_CB_PHYS_MEM_AFTER_WRITE, pcb); } } }
bool init_plugin(void *self) { printf("Initializing taint plugin\n"); plugin_ptr = self; panda_cb pcb; panda_enable_memcb(); panda_disable_tb_chaining(); pcb.guest_hypercall = guest_hypercall_callback; panda_register_callback(self, PANDA_CB_GUEST_HYPERCALL, pcb); #ifndef CONFIG_SOFTMMU pcb.user_after_syscall = user_after_syscall; panda_register_callback(self, PANDA_CB_USER_AFTER_SYSCALL, pcb); #endif return true; }
bool init_plugin(void *self) { panda_arg_list *args; args = panda_get_args("rehosting"); kernel_filename = panda_parse_string(args, "kernel", ""); assert (kernel_filename != NULL); assert (strlen(kernel_filename) > 0); // this is where we will blit the kernel into memory const char *base_addr_str = panda_parse_string(args, "base", ""); if (strnlen(base_addr_str,10) != 0) { base_addr = strtoul(base_addr_str, NULL, 16); } // and this is the entry point const char *entry_addr_str = panda_parse_string(args, "entry", ""); if (strnlen(entry_addr_str,10) != 0) { entry_addr = strtoul(entry_addr_str, NULL, 16); } printf ("rehosting: kernel=[%s]\n", kernel_filename); printf ("rehosting: base=0x%x entry=0x%x\n", base_addr, entry_addr); #if defined(TARGET_I386) panda_cb pcb; pcb.before_block_exec_invalidate_opt = blit_kernel; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC_INVALIDATE_OPT, pcb); return true; #else return false; #endif }
bool init_plugin(void *self) { panda_cb pcb; printf("Initializing plugin tapindex\n"); // Need this to get EIP with our callbacks panda_enable_precise_pc(); // Enable memory logging panda_enable_memcb(); pcb.virt_mem_read = mem_read_callback; panda_register_callback(self, PANDA_CB_VIRT_MEM_READ, pcb); pcb.virt_mem_write = mem_write_callback; panda_register_callback(self, PANDA_CB_VIRT_MEM_WRITE, pcb); return true; }
bool init_plugin(void *self) { // panda_require("callstack_instr"); // assert (init_callstack_instr_api()); panda_cb pcb; pcb.after_block_exec = dead_data_after_block_exec; panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb); panda_require("taint2"); assert (init_taint2_api()); return true; }
bool init_plugin(void* self) { panda_cb pcb; panda_arg_list* panda_args = panda_get_args("mmio_trace"); fn_str = panda_parse_string_opt(panda_args, "out_log", nullptr, "File to write MMIO trace log to."); if (!fn_str) { std::cerr << "No \'out_log\' specified, MMIO R/W will not be logged!" << std::endl; } panda_enable_precise_pc(); pcb.after_mmio_read = buffer_mmio_read; panda_register_callback(self, PANDA_CB_MMIO_AFTER_READ, pcb); pcb.after_mmio_write = buffer_mmio_write; panda_register_callback(self, PANDA_CB_MMIO_AFTER_WRITE, pcb); return true; }
bool init_plugin(void *self) { #ifdef CONFIG_SOFTMMU // this sets up the taint api fn ptrs so we have access bool x = init_taint_api(); assert (x==true); panda_cb pcb; pcb.before_block_exec = taint_compute_numbers_before_block_exec; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); pcb.after_block_exec = taint_compute_numbers_after_block_exec; panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb); return true; #else fprintf(stderr, "tcn plugin does not support linux-user mode\n"); return false; #endif }
bool init_plugin(void *self) { init_callstack_instr_api(); panda_cb pcb = { .before_block_exec = before_block_exec }; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); panda_arg_list *args = panda_get_args("printstack"); blockpc = panda_parse_ulong(args, "pc", 0); if (blockpc == 0) return false; return true; }
bool init_plugin(void *self) { printf("Initializing plugin file_taint\n"); panda_arg_list *args; args = panda_get_args("file_taint"); taint_filename = panda_parse_string(args, "filename", "abc123"); positional_labels = panda_parse_bool(args, "pos"); // used to just find the names of files that get no_taint = panda_parse_bool(args, "notaint"); prob_label_u32 = panda_parse_double(args, "prob_label_u32", 0.0); end_label = panda_parse_ulong(args, "max_num_labels", 1000000); end_label = panda_parse_ulong(args, "end", end_label); start_label = panda_parse_ulong(args, "start", 0); first_instr = panda_parse_uint64(args, "first_instr", 0); printf ("taint_filename = [%s]\n", taint_filename); printf ("positional_labels = %d\n", positional_labels); printf ("no_taint = %d\n", no_taint); printf ("prob_label_u32 = %.3f\n", prob_label_u32); printf ("end_label = %d\n", end_label); printf ("first_instr = %" PRId64 " \n", first_instr); panda_require("syscalls2"); // this sets up the taint api fn ptrs so we have access if (!no_taint) { panda_require("taint2"); assert(init_taint2_api()); if (first_instr == 0) { taint2_enable_taint(); } } panda_cb pcb; if (first_instr > 0) { // only need this callback if we are turning on taint late pcb.before_block_translate = file_taint_enable; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_TRANSLATE, pcb); } #if defined(TARGET_I386) PPP_REG_CB("syscalls2", on_sys_open_enter, open_enter); PPP_REG_CB("syscalls2", on_sys_open_return, open_return); PPP_REG_CB("syscalls2", on_sys_read_enter, read_enter); PPP_REG_CB("syscalls2", on_sys_read_return, read_return); #endif return true; }
bool init_plugin(void *self) { printf ("Initializing plugin coverage\n"); panda_arg_list *args = panda_get_args("coverage"); process_name = panda_parse_string(args, "process", ""); panda_require("osi"); // this sets up OS introspection API assert(init_osi_api()); panda_cb pcb; pcb.before_block_exec = coverage_before_block_exec; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); return true; }
bool init_plugin(void *self) { #if defined(TARGET_I386) && !defined(TARGET_X86_64) printf("Initializing plugin pri_simple\n"); //panda_arg_list *args = panda_get_args("pri_taint"); panda_require("pri"); assert(init_pri_api()); //panda_require("dwarfp"); //assert(init_dwarfp_api()); PPP_REG_CB("pri", on_before_line_change, on_line_change); //PPP_REG_CB("pri", on_fn_start, on_fn_start); { panda_cb pcb; pcb.virt_mem_write = virt_mem_write; panda_register_callback(self,PANDA_CB_VIRT_MEM_WRITE,pcb); pcb.virt_mem_read = virt_mem_read; panda_register_callback(self,PANDA_CB_VIRT_MEM_READ,pcb); } #endif return true; }
bool init_plugin(void *self) { panda_cb pcb; printf("Initializing plugin correlatetaps\n"); if(!init_callstack_instr_api()) return false; // Need this to get EIP with our callbacks panda_enable_precise_pc(); // Enable memory logging panda_enable_memcb(); pcb.virt_mem_write = mem_write_callback; panda_register_callback(self, PANDA_CB_VIRT_MEM_WRITE, pcb); return true; }
bool init_plugin(void *self) { #ifdef OSI_PROC_EVENTS panda_cb pcb; pcb.after_PGD_write = vmi_pgd_changed; panda_register_callback(self, PANDA_CB_VMI_PGD_CHANGED, pcb); #endif // figure out what kind of os introspection is needed and grab it? assert (!(panda_os_type == OST_UNKNOWN)); if (panda_os_type == OST_LINUX) { // sadly, all of this is to find kernelinfo.conf file char *progname = gargv[0]; if (progname[0] == '/') { // absolute path, yay! } else { // relative path char *cwd = get_current_dir_name(); char *rel_progname = strdup(progname); progname = (char *) malloc(256); sprintf (progname, "%s/%s", cwd, rel_progname); } char *progdir = strdup(progname); progdir = dirname(progdir); char kconfgroup[512]; sprintf (kconfgroup, "%s-%d", panda_os_details, panda_os_bits); char kconfile[256]; snprintf (kconfile, 256, "%s/../panda_plugins/osi_linux/kernelinfo.conf", progdir); char *kconfile2 = realpath( kconfile, NULL); printf ("kconfile [%s]\n", kconfile2); char osi_linux_arg[512]; sprintf (osi_linux_arg, "osi_linux:kconf_file=%s", kconfile2); panda_add_arg(osi_linux_arg, strlen(osi_linux_arg)); sprintf (osi_linux_arg, "osi_linux:kconf_group=%s", panda_os_details); panda_add_arg(osi_linux_arg, strlen(osi_linux_arg)); printf ("osi grabbing linux introspection backend. osi_linux arg [%s]\n", osi_linux_arg); panda_require("osi_linux"); } if (panda_os_type == OST_WINDOWS) { printf("osi grabbing windows introspection backend\n"); panda_require("win7x86intro"); panda_require("wintrospection"); } return true; }
bool init_plugin(void *self) { //panda_arg_list *args = panda_get_args("loaded"); panda_require("osi_linux"); assert(init_osi_linux_api()); panda_require("osi"); assert(init_osi_api()); panda_require("syscalls2"); #if defined(TARGET_I386) { panda_cb pcb; pcb.before_block_exec = osi_foo; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); } PPP_REG_CB("syscalls2", on_sys_mmap_pgoff_return, linux_mmap_pgoff_return); #else fprintf(stderr, "The loaded plugin is not currently supported on this platform.\n"); return false; #endif return true; }
bool init_plugin(void *self) { printf("Initializing plugin llvm_trace\n"); // Look for llvm_trace:base=dir for (int i = 0; i < panda_argc; i++) { if(0 == strncmp(panda_argv[i], "llvm_trace", 10)) { basedir = strrchr(panda_argv[i], '='); if (basedir) basedir++; // advance past '=' } } if (basedir == NULL) { basedir = default_basedir; } if (tubtf_on) { char tubtf_path[256]; strcpy(tubtf_path, basedir); strcat(tubtf_path, "/tubtf.log"); tubtf_open(tubtf_path, TUBTF_COLW_64); panda_enable_precise_pc(); } else { // XXX: unsafe string manipulations char memlog_path[256]; char funclog_path[256]; strcpy(memlog_path, basedir); strcat(memlog_path, "/llvm-memlog.log"); open_memlog(memlog_path); strcpy(funclog_path, basedir); strcat(funclog_path, "/llvm-functions.log"); funclog = fopen(funclog_path, "w"); } panda_cb pcb; panda_enable_memcb(); pcb.before_block_exec = before_block_exec; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); pcb.after_block_exec = after_block_exec; panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb); pcb.phys_mem_read = phys_mem_read_callback; panda_register_callback(self, PANDA_CB_PHYS_MEM_READ, pcb); pcb.phys_mem_write = phys_mem_write_callback; panda_register_callback(self, PANDA_CB_PHYS_MEM_WRITE, pcb); pcb.cb_cpu_restore_state = cb_cpu_restore_state; panda_register_callback(self, PANDA_CB_CPU_RESTORE_STATE, pcb); #ifndef CONFIG_SOFTMMU pcb.user_after_syscall = user_after_syscall; panda_register_callback(self, PANDA_CB_USER_AFTER_SYSCALL, pcb); #endif if (!execute_llvm){ panda_enable_llvm(); } llvm::llvm_init(); panda_enable_llvm_helpers(); /* * Run instrumentation pass over all helper functions that are now in the * module, and verify module. */ llvm::Module *mod = tcg_llvm_ctx->getModule(); for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){ if (i->isDeclaration()){ continue; } PIFP->runOnFunction(*i); } std::string err; if(verifyModule(*mod, llvm::AbortProcessAction, &err)){ printf("%s\n", err.c_str()); exit(1); } return true; }
bool init_plugin(void *self) { panda_cb pcb; int i; char *tblog_filename = NULL; args = panda_get_args("sample"); if (args != NULL) { for (i = 0; i < args->nargs; i++) { // Format is sample:file=<file> if (0 == strncmp(args->list[i].key, "file", 4)) { tblog_filename = args->list[i].value; } else if (0 == strncmp(args->list[i].key, "easter", 9)) { // Second parameter just to show how it's done if (0 == strncmp(args->list[i].value, "egg", 3)) { printf( " _____ \n" " .' '. \n" " / \\\n" "Y Y\n" "|v^v^v^v^v^v|\n" "|===========|\n" "|v^v^v^v^v^v|\n" "Y Y\n" " \\ /\n" " '._____.' \n"); } } } } if (!tblog_filename) { fprintf(stderr, "Plugin 'sample' needs argument: -panda-arg sample:file=<file>\n"); return false; } plugin_log = fopen(tblog_filename, "w"); if(!plugin_log) return false; // In general you should always register your callbacks last, because // if you return false your plugin will be unloaded and there may be stale // pointers hanging around. pcb.guest_hypercall = guest_hypercall_callback; panda_register_callback(self, PANDA_CB_GUEST_HYPERCALL, pcb); pcb.after_block_exec = after_block_callback; panda_register_callback(self, PANDA_CB_AFTER_BLOCK_EXEC, pcb); pcb.before_block_exec = before_block_callback; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); pcb.monitor = monitor_callback; panda_register_callback(self, PANDA_CB_MONITOR, pcb); pcb.insn_translate = translate_callback; panda_register_callback(self, PANDA_CB_INSN_TRANSLATE, pcb); pcb.insn_exec = exec_callback; panda_register_callback(self, PANDA_CB_INSN_EXEC, pcb); #ifdef CONFIG_ANDROID pcb.before_loadvm = before_loadvm_callback; panda_register_callback(self, PANDA_CB_BEFORE_REPLAY_LOADVM, pcb); #endif return true; }
void __taint_enable_taint(void) { if(taintEnabled) {return;} printf ("__taint_enable_taint\n"); taintJustEnabled = true; taintEnabled = true; panda_cb pcb; pcb.before_block_exec = before_block_exec; panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); pcb.after_block_exec = after_block_exec; panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_EXEC, pcb); pcb.phys_mem_read = phys_mem_read_callback; panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_READ, pcb); pcb.phys_mem_write = phys_mem_write_callback; panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_WRITE, pcb); pcb.cb_cpu_restore_state = cb_cpu_restore_state; panda_register_callback(plugin_ptr, PANDA_CB_CPU_RESTORE_STATE, pcb); // for hd and network taint #ifdef CONFIG_SOFTMMU pcb.replay_hd_transfer = cb_replay_hd_transfer_taint; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_HD_TRANSFER, pcb); pcb.replay_net_transfer = cb_replay_net_transfer_taint; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_NET_TRANSFER, pcb); pcb.replay_before_cpu_physical_mem_rw_ram = cb_replay_cpu_physical_mem_rw_ram; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_BEFORE_CPU_PHYSICAL_MEM_RW_RAM, pcb); #endif panda_enable_precise_pc(); //before_block_exec requires precise_pc for panda_current_asid if (!execute_llvm){ panda_enable_llvm(); } llvm::llvm_init(); panda_enable_llvm_helpers(); /* * Run instrumentation pass over all helper functions that are now in the * module, and verify module. */ llvm::Module *mod = tcg_llvm_ctx->getModule(); for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){ if (i->isDeclaration()){ continue; } #if defined(TARGET_ARM) //TODO: Fix handling of ARM's cpu_reset() helper // Currently, we skip instrumenting it, because we generate invalid LLVM bitcode if we try std::string modname = i->getName().str(); if (modname == "cpu_reset_llvm"){ printf("Skipping instrumentation of cpu_reset\n"); continue; } #endif PIFP->runOnFunction(*i); } std::string err; if(verifyModule(*mod, llvm::AbortProcessAction, &err)){ printf("%s\n", err.c_str()); exit(1); } /* * Taint processor initialization */ //uint32_t ram_size = 536870912; // 500MB each #ifdef TARGET_X86_64 // this is only for the fast bitmap which we currently aren't using for // 64-bit, it only supports 32-bit //XXX FIXME uint64_t ram_size = 0; #else uint32_t ram_size = 0xffffffff; //guest address space -- QEMU user mode #endif uint64_t hd_size = 536870912; uint64_t io_size = 536870912; uint16_t num_vals = 2000; // LLVM virtual registers //XXX assert this shadow = tp_init(hd_size, ram_size, io_size, num_vals); if (shadow == NULL){ printf("Error initializing shadow memory...\n"); exit(1); } taintfpm = new llvm::FunctionPassManager(tcg_llvm_ctx->getModule()); // Add the taint analysis pass to our taint pass manager llvm::FunctionPass *taintfp = llvm::createPandaTaintFunctionPass(15*1048576/* global taint op buffer size, 10MB */, NULL /* existing taint cache */); PTFP = static_cast<llvm::PandaTaintFunctionPass*>(taintfp); taintfpm->add(taintfp); taintfpm->doInitialization(); // Populate taint cache with helper function taint ops for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){ if (i->isDeclaration()){ continue; } PTFP->runOnFunction(*i); } }
void enable_taint(){ panda_cb pcb; pcb.before_block_exec = before_block_exec; panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); pcb.after_block_exec = after_block_exec; panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_EXEC, pcb); pcb.phys_mem_read = phys_mem_read_callback; panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_READ, pcb); pcb.phys_mem_write = phys_mem_write_callback; panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_WRITE, pcb); pcb.cb_cpu_restore_state = cb_cpu_restore_state; panda_register_callback(plugin_ptr, PANDA_CB_CPU_RESTORE_STATE, pcb); if (!execute_llvm){ panda_enable_llvm(); } llvm::llvm_init(); panda_enable_llvm_helpers(); /* * Run instrumentation pass over all helper functions that are now in the * module, and verify module. */ llvm::Module *mod = tcg_llvm_ctx->getModule(); for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){ if (i->isDeclaration()){ continue; } PIFP->runOnFunction(*i); } std::string err; if(verifyModule(*mod, llvm::AbortProcessAction, &err)){ printf("%s\n", err.c_str()); exit(1); } /* * Taint processor initialization */ //uint32_t ram_size = 536870912; // 500MB each #ifdef TARGET_X86_64 // this is only for the fast bitmap which we currently aren't using for // 64-bit, it only supports 32-bit //XXX FIXME uint64_t ram_size = 0; #else uint32_t ram_size = 0xffffffff; //guest address space -- QEMU user mode #endif uint64_t hd_size = 536870912; uint64_t io_size = 536870912; uint16_t num_vals = 2000; // LLVM virtual registers //XXX assert this shadow = tp_init(hd_size, ram_size, io_size, num_vals); if (shadow == NULL){ printf("Error initializing shadow memory...\n"); exit(1); } taintfpm = new llvm::FunctionPassManager(tcg_llvm_ctx->getModule()); // Add the taint analysis pass to our taint pass manager llvm::FunctionPass *taintfp = llvm::createPandaTaintFunctionPass(15*1048576/* global taint op buffer size, 10MB */, NULL /* existing taint cache */); PTFP = static_cast<llvm::PandaTaintFunctionPass*>(taintfp); taintfpm->add(taintfp); taintfpm->doInitialization(); // Populate taint cache with helper function taint ops for (llvm::Module::iterator i = mod->begin(); i != mod->end(); i++){ if (i->isDeclaration()){ continue; } PTFP->runOnFunction(*i); } }
bool init_plugin(void *self) { printf("Initializing taint plugin\n"); plugin_ptr = self; panda_cb pcb; panda_enable_memcb(); panda_disable_tb_chaining(); pcb.guest_hypercall = guest_hypercall_callback; panda_register_callback(self, PANDA_CB_GUEST_HYPERCALL, pcb); pcb.replay_handle_packet = handle_packet; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_HANDLE_PACKET, pcb); #ifndef CONFIG_SOFTMMU pcb.user_after_syscall = user_after_syscall; panda_register_callback(self, PANDA_CB_USER_AFTER_SYSCALL, pcb); #endif tob_io_thread = tob_new(tob_io_thread_max_size); panda_arg_list *args = panda_get_args("taint"); int i; if (NULL != args) { for (i = 0; i < args->nargs; i++) { if (0 == strncmp(args->list[i].key, "max_taintset_card", 17)) { max_taintset_card = atoi(args->list[i].value); printf ("max_taintset_card = %d\n", max_taintset_card); } if (0 == strncmp(args->list[i].key, "max_taintset_compute_number", 24)) { max_taintset_compute_number = atoi(args->list[i].value); printf ("max_taintset_compute_number = %d\n", max_taintset_compute_number); } if (0 == strncmp(args->list[i].key, "compute_is_delete", 17)) { compute_is_delete = 1; } if (0 == strncmp(args->list[i].key, "label_incoming_network", 22)) { taint_label_incoming_network_traffic = 1; } if (0 == strncmp(args->list[i].key, "query_outgoing_network", 22)) { taint_query_outgoing_network_traffic = 1; } if (0 == strncmp(args->list[i].key, "no_tainted_pointer", 18)) { tainted_pointer = 0; } if (0 == strncmp(args->list[i].key, "label_mode", 10)) { if (0 == strncmp(args->list[i].value, "binary", 6)){ taint_label_mode = TAINT_BINARY_LABEL; } else if (0 == strncmp(args->list[i].value, "byte", 4)){ taint_label_mode = TAINT_BYTE_LABEL; } else { printf("Invalid taint label_mode. Using default byte label.\n"); taint_label_mode = TAINT_BYTE_LABEL; } } if (0 == strncmp (args->list[i].key, "tainted_instructions", 20)) { tainted_instructions = 1; } } } if (taint_label_mode == TAINT_BYTE_LABEL){ printf("Taint: running in byte labeling mode.\n"); } else if (taint_label_mode == TAINT_BINARY_LABEL){ printf("Taint: running in binary labeling mode.\n"); } printf ("max_taintset_card = %d\n", max_taintset_card); printf ("max_taintset_compute_number = %d\n", max_taintset_compute_number); printf ("taint_label_incoming_network_traffic = %d\n", taint_label_incoming_network_traffic); printf ("taint_query_outgoing_network_traffic = %d\n", taint_query_outgoing_network_traffic); printf ("tainted_pointer = %d\n", tainted_pointer); printf ("compute_is_delete = %d\n", compute_is_delete); printf ("done initializing taint plugin\n"); return true; }
bool init_plugin(void *self) { printf("Initializing plugin file_taint\n"); #ifdef TARGET_I386 panda_cb pcb; panda_arg_list *args; args = panda_get_args("file_taint"); taint_filename = panda_parse_string(args, "filename", "abc123"); positional_labels = panda_parse_bool(args, "pos"); no_taint = panda_parse_bool(args, "notaint"); end_label = panda_parse_ulong(args, "max_num_labels", 1000000); end_label = panda_parse_ulong(args, "end", end_label); start_label = panda_parse_ulong(args, "start", 0); enable_taint_on_open = panda_parse_bool(args, "enable_taint_on_open"); first_instr = panda_parse_uint64(args, "first_instr", 0); taint_stdin = panda_parse_string(args, "use_stdin_for", nullptr); printf ("taint_filename = [%s]\n", taint_filename); printf ("positional_labels = %d\n", positional_labels); printf ("no_taint = %d\n", no_taint); printf ("end_label = %d\n", end_label); printf ("first_instr = %" PRId64 " \n", first_instr); // you must use '-os os_name' cmdline arg! assert (!(panda_os_type == OST_UNKNOWN)); panda_require("osi"); assert(init_osi_api()); panda_require("syscalls2"); if (taint_stdin) { printf("tainting stdin\n"); assert (panda_os_type == OST_LINUX); } if (panda_os_type == OST_LINUX) { panda_require("osi_linux"); assert(init_osi_linux_api()); PPP_REG_CB("syscalls2", on_sys_open_enter, linux_open_enter); PPP_REG_CB("syscalls2", on_sys_read_enter, linux_read_enter); PPP_REG_CB("syscalls2", on_sys_read_return, linux_read_return); PPP_REG_CB("syscalls2", on_sys_pread64_enter, linux_pread_enter); PPP_REG_CB("syscalls2", on_sys_pread64_return, linux_pread_return); } if (panda_os_type == OST_WINDOWS) { panda_require("wintrospection"); assert(init_wintrospection_api()); PPP_REG_CB("syscalls2", on_NtOpenFile_enter, windows_open_enter); PPP_REG_CB("syscalls2", on_NtOpenFile_return, windows_open_return); PPP_REG_CB("syscalls2", on_NtCreateFile_enter, windows_create_enter); PPP_REG_CB("syscalls2", on_NtCreateFile_return, windows_create_return); PPP_REG_CB("syscalls2", on_NtReadFile_enter, windows_read_enter); PPP_REG_CB("syscalls2", on_NtReadFile_return, windows_read_return); } // this sets up the taint api fn ptrs so we have access if (!no_taint) { if (debug) printf("file_taint: initializing taint2 plugin\n"); panda_require("taint2"); assert(init_taint2_api()); if (!enable_taint_on_open && first_instr == 0) { if (debug) printf("file_taint: turning on taint at replay beginning\n"); taint2_enable_taint(); } } if (!no_taint && first_instr > 0) { if (debug) printf ("file_taint: turning on taint at instruction %" PRId64 "\n", first_instr); // only need this callback if we are turning on taint late pcb.before_block_translate = file_taint_enable; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_TRANSLATE, pcb); } pcb.before_block_exec = osi_foo; panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); #else printf ("file_taint: only works for x86 target (really just 32-bit)\n"); return false; #endif return true; }
void __taint2_enable_taint(void) { if(taintEnabled) {return;} printf ("taint2: __taint_enable_taint\n"); taintEnabled = true; panda_cb pcb; pcb.after_block_translate = after_block_translate; panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_TRANSLATE, pcb); pcb.before_block_exec_invalidate_opt = before_block_exec_invalidate_opt; panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC_INVALIDATE_OPT, pcb); pcb.before_block_exec = before_block_exec; panda_register_callback(plugin_ptr, PANDA_CB_BEFORE_BLOCK_EXEC, pcb); pcb.after_block_exec = after_block_exec; panda_register_callback(plugin_ptr, PANDA_CB_AFTER_BLOCK_EXEC, pcb); pcb.phys_mem_read = phys_mem_read_callback; panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_READ, pcb); pcb.phys_mem_write = phys_mem_write_callback; panda_register_callback(plugin_ptr, PANDA_CB_PHYS_MEM_WRITE, pcb); /* pcb.cb_cpu_restore_state = cb_cpu_restore_state; panda_register_callback(plugin_ptr, PANDA_CB_CPU_RESTORE_STATE, pcb); // for hd and network taint pcb.replay_hd_transfer = cb_replay_hd_transfer_taint; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_HD_TRANSFER, pcb); pcb.replay_net_transfer = cb_replay_net_transfer_taint; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_NET_TRANSFER, pcb); pcb.replay_before_cpu_physical_mem_rw_ram = cb_replay_cpu_physical_mem_rw_ram; panda_register_callback(plugin_ptr, PANDA_CB_REPLAY_BEFORE_CPU_PHYSICAL_MEM_RW_RAM, pcb); */ panda_enable_precise_pc(); //before_block_exec requires precise_pc for panda_current_asid if (!execute_llvm){ panda_enable_llvm(); } panda_enable_llvm_helpers(); /* * Taint processor initialization */ shadow = tp_init(TAINT_BYTE_LABEL, TAINT_GRANULARITY_BYTE); if (shadow == NULL){ printf("Error initializing shadow memory...\n"); exit(1); } // Initialize memlog. memset(&taint_memlog, 0, sizeof(taint_memlog)); llvm::Module *mod = tcg_llvm_ctx->getModule(); FPM = tcg_llvm_ctx->getFunctionPassManager(); // Add the taint analysis pass to our taint pass manager PTFP = new llvm::PandaTaintFunctionPass(shadow, &taint_memlog); FPM->add(PTFP); if (optimize_llvm) { printf("taint2: Adding default optimizations (-O1).\n"); llvm::PassManagerBuilder Builder; Builder.OptLevel = 1; Builder.SizeLevel = 0; Builder.populateFunctionPassManager(*FPM); } FPM->doInitialization(); // Populate module with helper function taint ops for (auto i = mod->begin(); i != mod->end(); i++){ if (!i->isDeclaration()) PTFP->runOnFunction(*i); } printf("taint2: Done processing helper functions for taint.\n"); std::string err; if(verifyModule(*mod, llvm::AbortProcessAction, &err)){ printf("%s\n", err.c_str()); exit(1); } //tcg_llvm_write_module(tcg_llvm_ctx, "/tmp/llvm-mod.bc"); printf("taint2: Done verifying module. Running...\n"); }