int file_taint_enable(CPUState *cpu, target_ulong pc) { if (!no_taint && !taint2_enabled()) { uint64_t ins = rr_get_guest_instr_count(); if (ins > first_instr) { taint2_enable_taint(); if (debug) printf (" enabled taint2 @ ins %" PRId64 "\n", ins); } } return 0; }
// turn on taint at right instr count int tstringsearch_enable_taint(CPUState *env, target_ulong pc) { // enable taint if close to instruction count uint64_t ic = rr_get_guest_instr_count(); if (!taint2_enabled()) { if (ic + 100 > enable_taint_instr_count) { printf ("enabling taint at instr count %" PRIu64 "\n", ic); taint2_enable_taint(); } } return 0; }
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; }
int file_taint_enable(CPUState *env, target_ulong pc) { if (!no_taint && !taint_is_enabled) { uint64_t ins = replay_get_guest_instr_count(); // printf ("ins= %" PRId64 " first_ins = %" PRId64" %d\n", // ins, first_instr, (ins > first_instr) ); if (ins > first_instr) { taint_is_enabled = true; taint2_enable_taint(); printf (" @ ins %" PRId64 "\n", ins); } } return 0; }
void open_enter(CPUState *cpu, target_ulong pc, std::string filename, int32_t flags, int32_t mode) { if (!filename.empty()) { if (debug) printf ("open_enter: saw open of [%s]\n", filename.c_str()); } if (filename.find(taint_filename) != std::string::npos) { saw_open = true; printf ("saw open of file we want to taint: [%s] insn %" PRId64 "\n", taint_filename, rr_get_guest_instr_count()); the_asid = panda_current_asid(cpu); if (enable_taint_on_open && !no_taint && !taint2_enabled()) { uint64_t ins = rr_get_guest_instr_count(); taint2_enable_taint(); if (debug) printf ("file_taint: enabled taint2 @ ins %" PRId64 "\n", ins); } } }
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"); use_taint2 = !panda_parse_bool(args, "taint1"); // used to just find the names of files that get no_taint = panda_parse_bool(args, "notaint"); printf ("taint_filename = [%s]\n", taint_filename); printf ("positional_labels = %d\n", positional_labels); panda_require("syscalls2"); // this sets up the taint api fn ptrs so we have access if (!no_taint) { if (use_taint2) { panda_require("taint2"); assert(init_taint2_api()); taint2_enable_taint(); } else { panda_require("taint"); assert(init_taint_api()); taint_enable_taint(); } } #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 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; }
int guest_hypercall_callback(CPUState *cpu) { #if defined(TARGET_I386) CPUArchState *env = (CPUArchState*)cpu->env_ptr; if (taintEnabled) { if (EAX == 7 || EAX == 8) { target_ulong buf_start = EBX; target_ulong buf_len = ECX; long label = EDI; if (R_EAX == 7) { // Standard buffer label printf("taint2: single taint label\n"); taint2_add_taint_ram_single_label(cpu, (uint64_t)buf_start, (int)buf_len, label); } else if (R_EAX == 8) { // Positional buffer label printf("taint2: positional taint label\n"); taint2_add_taint_ram_pos(cpu, (uint64_t)buf_start, (int)buf_len, label); } } else { // LAVA Hypercall target_ulong addr = panda_virt_to_phys(cpu, env->regs[R_EAX]); if ((int)addr == -1) { // if EAX is not a valid ptr, then it is unlikely that this is a // PandaHypercall which requires EAX to point to a block of memory // defined by PandaHypercallStruct printf ("cpuid with invalid ptr in EAX: vaddr=0x%x paddr=0x%x. Probably not a Panda Hypercall\n", (uint32_t) env->regs[R_EAX], (uint32_t) addr); } else if (pandalog) { PandaHypercallStruct phs; panda_virtual_memory_rw(cpu, env->regs[R_EAX], (uint8_t *) &phs, sizeof(phs), false); if (phs.magic == 0xabcd) { if (phs.action == 11) { // it's a lava query taint_query_hypercall(phs); } else if (phs.action == 12) { // it's an attack point sighting lava_attack_point(phs); } else if (phs.action == 13) { // it's a pri taint query point // do nothing and let pri_taint with hypercall // option handle it } else if (phs.action == 14) { // reserved for taint-exploitability } else { printf("Unknown hypercall action %d\n", phs.action); } } else { printf ("Invalid magic value in PHS struct: %x != 0xabcd.\n", phs.magic); } } } } return 1; #elif defined(TARGET_ARM) // R0 is command (label or query) // R1 is buf_start // R2 is length // R3 is offset (not currently implemented) CPUArchState *env = (CPUArchState*)cpu->env_ptr; if (env->regs[0] == 7 || env->regs[0] == 8) { //Taint label if (!taintEnabled) { printf("Taint plugin: Label operation detected @ %lu\n", rr_get_guest_instr_count()); printf("Enabling taint processing\n"); taint2_enable_taint(); } // FIXME: do labeling here. } else if (env->regs[0] == 9) { //Query taint on label if (taintEnabled) { printf("Taint plugin: Query operation detected @ %lu\n", rr_get_guest_instr_count()); } } return 1; #else // other architectures return 0; #endif }