diff --git a/panda/plugins/pri_taint/pri_taint.cpp b/panda/plugins/pri_taint/pri_taint.cpp index 981c235d8f7..7f478196ba1 100644 --- a/panda/plugins/pri_taint/pri_taint.cpp +++ b/panda/plugins/pri_taint/pri_taint.cpp @@ -40,13 +40,11 @@ void uninit_plugin(void *); int get_loglevel() ; void set_loglevel(int new_loglevel); } -bool linechange_taint = true; -bool hypercall_taint = true; -bool chaff_bugs = false; -Panda__SrcInfoPri *si = NULL; + const char *global_src_filename = NULL; uint64_t global_src_linenum; unsigned global_ast_loc_id; +uint64_t global_funcaddr; bool debug = false; #define dprintf(...) if (debug) { printf(__VA_ARGS__); fflush(stdout); } @@ -115,13 +113,13 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con CPUState *cpu = first_cpu; CPUArchState *env = (CPUArchState *)cpu->env_ptr; bool is_strnlen = ((int) buf_len == -1); - hwaddr phys = loc_t == LocMem ? panda_virt_to_phys(cpu, buf) : 0; - ram_addr_t RamOffset = RAM_ADDR_INVALID; + extern ram_addr_t ram_size; + target_ulong phys = loc_t == LocMem ? panda_virt_to_phys(cpu, buf) : 0; - if (phys == (hwaddr)-1 || PandaPhysicalAddressToRamOffset(&RamOffset, phys, false) != MEMTX_OK) return; + if (phys == -1 || phys > ram_size) return; if (debug) { - printf("Querying \"%s\": " TARGET_FMT_lu " bytes @ 0x" TARGET_FMT_lx " phys 0x" TARGET_FMT_plx ", strnlen=%d", astnodename, buf_len, buf, phys, is_strnlen); + //printf("Querying \"%s\": " TARGET_FMT_lu " bytes @ 0x" TARGET_FMT_lx " phys 0x" TARGET_FMT_plx ", strnlen=%d", astnodename, buf_len, buf, phys, is_strnlen); print_membytes(cpu, buf, is_strnlen? 32 : buf_len); printf("\n"); } @@ -129,7 +127,7 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con uint8_t bytes[LAVA_TAINT_QUERY_MAX_LEN] = {0}; target_ulong len = std::min(buf_len, LAVA_TAINT_QUERY_MAX_LEN); if (is_strnlen) { - panda_physical_memory_read(phys, bytes, LAVA_TAINT_QUERY_MAX_LEN); + panda_physical_memory_rw(phys, bytes, LAVA_TAINT_QUERY_MAX_LEN, false); for (int i = 0; i < LAVA_TAINT_QUERY_MAX_LEN; i++) { if (bytes[i] == '\0') { len = i; @@ -151,12 +149,12 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con // is there *any* taint on this extent uint32_t num_tainted = 0; for (uint32_t i = 0; i < len; i++) { - Addr a = loc_t == LocMem ? make_maddr(RamOffset + i) : make_greg(buf, i); /* HACK: presumes for the same physical page ram_addr_t(x + i) == ram_addr_t(x) + i */ + Addr a = loc_t == LocMem ? make_maddr(phys + i) : make_greg(buf, i); if (taint2_query(a)) num_tainted++; } // If nothing's tainted and we aren't doing chaff bugs, return. - if (!chaff_bugs && num_tainted == 0) return; + if (num_tainted == 0) return; // 1. write the pandalog entry that tells us something was tainted on this extent Panda__TaintQueryPri tqh = PANDA__TAINT_QUERY_PRI__INIT; @@ -180,7 +178,8 @@ void lava_taint_query(target_ulong buf, LocType loc_t, target_ulong buf_len, con // 2. iterate over the bytes in the extent and pandalog detailed info about taint std::vector tq; for (uint32_t offset = 0; offset < len; offset++) { - Addr a = loc_t == LocMem ? make_maddr(RamOffset + offset) : make_greg(buf, offset); /* HACK: presumes for the same physical page ram_addr_t(x + i) == ram_addr_t(x) + i */ + uint32_t pa_indexed = phys + offset; + Addr a = loc_t == LocMem ? make_maddr(pa_indexed) : make_greg(buf, offset); if (taint2_query(a)) { if (loc_t == LocMem) { dprintf("\"%s\" @ 0x" TARGET_FMT_lx " is tainted\n", astnodename, buf + offset); @@ -215,10 +214,11 @@ struct args { const char *src_filename; uint64_t src_linenum; unsigned ast_loc_id; + uint64_t funcaddr; }; #if defined(TARGET_I386) -void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc, void *in_args){ +void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc, void *in_args) { if (!taint2_enabled()) return; // lava autogenerated variables start with this string @@ -239,6 +239,7 @@ void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc global_src_filename = args->src_filename; global_src_linenum = args->src_linenum; global_ast_loc_id = args->ast_loc_id; + global_funcaddr = args->funcaddr; //target_ulong guest_dword; //std::string ty_string = std::string(var_ty); //size_t num_derefs = std::count(ty_string.begin(), ty_string.end(), '*'); @@ -263,9 +264,9 @@ void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc default: assert(1==0); } - free(si); + // free(si); } - +/* void on_line_change(CPUState *cpu, target_ulong pc, const char *file_Name, const char *funct_name, unsigned long long lno){ if (taint2_enabled()){ struct args args = {cpu, file_Name, lno, 0}; @@ -280,21 +281,34 @@ void on_fn_start(CPUState *cpu, target_ulong pc, const char *file_Name, const ch pri_funct_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args); } +// Trace logging in the level of source code +void hypercall_log_trace(unsigned ast_loc_id) { + Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; + Panda__SourceTraceId stid = PANDA__SOURCE_TRACE_ID__INIT; + stid.ast_loc_id = ast_loc_id; + ple.source_trace_id = &stid; + pandalog_write_entry(&ple); +} +*/ #ifdef TARGET_I386 // Support all features of label and query program bool i386_hypercall_callback(CPUState *cpu){ bool ret = false; CPUArchState *env = (CPUArchState*)cpu->env_ptr; - if (taint2_enabled() && pandalog) { + if (taint2_enabled()) { // LAVA Hypercall target_ulong addr = panda_virt_to_phys(cpu, env->regs[R_EAX]); if ((int)addr == -1) { printf ("panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%x paddr=0x%x\n", (uint32_t) env->regs[R_EAX], (uint32_t) addr); } - else { + else if (pandalog) { PandaHypercallStruct phs; panda_virtual_memory_rw(cpu, env->regs[R_EAX], (uint8_t *) &phs, sizeof(phs), false); + + uint64_t funcaddr = 0; + panda_virtual_memory_rw(cpu, phs.info, (uint8_t*)&funcaddr, sizeof(target_ulong), false); + if (phs.magic == 0xabcd) { // if the phs action is a pri_query point, see // lava/include/pirate_mark_lava.h @@ -303,16 +317,16 @@ bool i386_hypercall_callback(CPUState *cpu){ SrcInfo info; int rc = pri_get_pc_source_info(cpu, pc, &info); if (!rc) { - struct args args = {cpu, info.filename, info.line_number, phs.src_filename}; + struct args args = {cpu, info.filename, info.line_number, phs.src_filename, funcaddr}; dprintf("panda hypercall: [%s], " "ln: %4ld, pc @ 0x" TARGET_FMT_lx "\n", info.filename, info.line_number,pc); pri_funct_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args); - //pri_all_livevar_iter(cpu, pc, (liveVarCB) pfun, (void *)&args); //lava_attack_point(phs); } ret = true; + // hypercall_log_trace(phs.src_filename); } } else { @@ -325,7 +339,7 @@ bool i386_hypercall_callback(CPUState *cpu){ #endif // TARGET_I386 -bool guest_hypercall_callback(CPUState *cpu){ +bool guest_hypercall_callback(CPUState *cpu) { #ifdef TARGET_I386 return i386_hypercall_callback(cpu); #endif @@ -354,33 +368,26 @@ bool init_plugin(void *self) { #if defined(TARGET_I386) panda_arg_list *args = panda_get_args("pri_taint"); - hypercall_taint = panda_parse_bool_opt(args, "hypercall", "Register tainting on a panda hypercall callback"); - linechange_taint = panda_parse_bool_opt(args, "linechange", "Register tainting on every line change in the source code (default)"); - chaff_bugs = panda_parse_bool_opt(args, "chaff", "Record untainted extents for chaff bugs."); - // default linechange_taint to true if there is no hypercall taint - if (!hypercall_taint) - linechange_taint = true; + debug = panda_parse_bool_opt(args, "debug", "enable debug output"); + panda_require("callstack_instr"); assert(init_callstack_instr_api()); panda_require("pri"); assert(init_pri_api()); panda_require("dwarf2"); assert(init_dwarf2_api()); - panda_require("taint2"); assert(init_taint2_api()); - if (hypercall_taint) { - panda_cb pcb; - pcb.guest_hypercall = guest_hypercall_callback; - panda_register_callback(self, PANDA_CB_GUEST_HYPERCALL, pcb); - } - if (linechange_taint){ - PPP_REG_CB("pri", on_before_line_change, on_line_change); - } + panda_cb pcb; + pcb.guest_hypercall = guest_hypercall_callback; + panda_register_callback(self, PANDA_CB_GUEST_HYPERCALL, pcb); + return true; +#else + printf("This plugin is only supported on x86\n"); + return false; //taint2_track_taint_state(); #endif - return true; } diff --git a/panda/plugins/taint2/taint2_hypercalls.h b/panda/plugins/taint2/taint2_hypercalls.h index 1b7ac13e164..9c4dd86fd39 100644 --- a/panda/plugins/taint2/taint2_hypercalls.h +++ b/panda/plugins/taint2/taint2_hypercalls.h @@ -46,7 +46,6 @@ extern "C" { #endif bool guest_hypercall_callback(CPUState *cpu); bool guest_hypercall_warning_callback(CPUState *cpu); -void lava_attack_point(PandaHypercallStruct phs); #ifdef __cplusplus } #endif