// hypercall-initiated taint query of some src-level extent void lava_taint_query (PandaHypercallStruct phs) { extern CPUState *cpu_single_env; CPUState *env = cpu_single_env; if (taintEnabled && (taint2_num_labels_applied() > 0)){ // okay, taint is on and some labels have actually been applied // is there *any* taint on this extent uint32_t num_tainted = 0; for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { num_tainted ++; } } } if (num_tainted) { // ok at least one byte in the extent is tainted // 1. write the pandalog entry that tells us something was tainted on this extent Panda__TaintQueryHypercall *tqh = (Panda__TaintQueryHypercall *) malloc (sizeof (Panda__TaintQueryHypercall)); *tqh = PANDA__TAINT_QUERY_HYPERCALL__INIT; tqh->buf = phs.buf; tqh->len = phs.len; tqh->num_tainted = num_tainted; // obtain the actual data out of memory // NOTE: first 32 bytes only! uint32_t data[32]; uint32_t n = phs.len; if (32 < phs.len) n = 32; for (uint32_t i=0; i<n; i++) { data[i] = 0; uint8_t c; panda_virtual_memory_rw(env, phs.buf+i, &c, 1, false); data[i] = c; } tqh->n_data = n; tqh->data = data; Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.taint_query_hypercall = tqh; pandalog_write_entry(&ple); free(tqh); // 2. write out src-level info lava_src_info_pandalog(phs); // 3. write out callstack info callstack_pandalog(); // 4. iterate over the bytes in the extent and pandalog detailed info about taint for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { __taint2_query_pandalog(a); } } } } } }
void label_byte(CPUState *env, target_ulong virt_addr, uint32_t label_num) { target_phys_addr_t pa = panda_virt_to_phys(env, virt_addr); if (pandalog) { Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.has_taint_label_virtual_addr = 1; ple.has_taint_label_physical_addr = 1; ple.has_taint_label_number = 1; ple.taint_label_virtual_addr = virt_addr; ple.taint_label_physical_addr = pa; if (positional_labels) { ple.taint_label_number = label_num; } else { ple.taint_label_number = 1; } pandalog_write_entry(&ple); } if (!no_taint) { if (positional_labels) { taint2_label_ram(pa, label_num); } else { taint2_label_ram(pa, 1); } } }
int tstringsearch_label(CPUState *env, target_ulong pc, target_ulong addr, target_ulong size) { tstringsearch_enable_taint(env, pc); if (tstringsearch_label_on == false) { return 0; } if (!done_labeling && pc == the_pc) { printf ("\n****************************************************************************\n"); printf ("applying taint labels to search string of length %d @ p=0x" TARGET_FMT_lx "\n", the_len, the_buf); printf ("******************************************************************************\n"); // label that buffer int i; for (i=0; i<the_len; i++) { target_ulong va = the_buf + i; hwaddr pa = panda_virt_to_phys(env, va); if (pa != (hwaddr) -1) { if (positional_tainting) { taint2_label_ram(pa, i); } else { taint2_label_ram(pa, 10); } } } tstringsearch_label_on = false; if (only_first) done_labeling = true; } return 0; }
// label this virtual address. might fail, so // returns true iff byte was labeled bool label_byte(CPUState *cpu, target_ulong virt_addr, uint32_t label_num) { hwaddr pa = panda_virt_to_phys(cpu, virt_addr); if (pa == (hwaddr) -1) { printf ("label_byte: virtual addr " TARGET_FMT_lx " not available\n", virt_addr); return false; } if (no_taint) { // don't print a message -- you'd have too many in this case return false; } if (positional_labels) { taint2_label_ram(pa, label_num); } else { taint2_label_ram(pa, 1); } if (pandalog) { Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.has_taint_label_virtual_addr = 1; ple.has_taint_label_physical_addr = 1; ple.has_taint_label_number = 1; ple.taint_label_virtual_addr = virt_addr; ple.taint_label_physical_addr = pa; if (positional_labels) { ple.taint_label_number = label_num; } else { ple.taint_label_number = 1; } pandalog_write_entry(&ple); } return true; }
// 3 long sys_read(unsigned int fd, char __user *buf, size_t count); // typedef void (*on_sys_read_return_t)(CPUState* env,target_ulong pc,uint32_t fd,target_ulong buf,uint32_t count); void read_return(CPUState* env,target_ulong pc,uint32_t fd,target_ulong buf,uint32_t count) { if (saw_read && panda_current_asid(env) == the_asid) { count = EAX; printf ("count=%d\n", count); printf ("returning from read of [%s] count=%d\n", taint_filename, count); printf ("*** applying %s taint labels %d..%d to buffer\n", positional_labels ? "positional" : "uniform", taint_label_number_start, taint_label_number_start + count - 1); for (uint32_t i=0; i<count; i++ ) { target_phys_addr_t pa = panda_virt_to_phys(env, the_buf+i); if (pandalog) { Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.has_taint_label_virtual_addr = 1; ple.has_taint_label_physical_addr = 1; ple.has_taint_label_number = 1; ple.taint_label_virtual_addr = the_buf + i; ple.taint_label_physical_addr = pa; if (positional_labels) { ple.taint_label_number = taint_label_number_start + i; } else { ple.taint_label_number = 1; } pandalog_write_entry(&ple); } if (!no_taint) { if (positional_labels) { if (use_taint2) taint2_label_ram(pa, taint_label_number_start + i); else taint_label_ram(pa, i); } else { if (use_taint2) taint2_label_ram(pa, 1); else taint_label_ram(pa, 1); } } } taint_label_number_start += count; printf (" ... done applying labels\n"); saw_read = false; } }
// Support all features of label and query program void i386_hypercall_callback(CPUState *env){ #if 0 if (EAX == 0xabcd) { printf ("\n hypercall pc=0x%x\n", (int) panda_current_pc(env)); for (uint32_t i=0; i<8; i++) { printf ("reg[%d] = 0x%x\n", i, (int) env->regs[i]); } } #endif //printf("taint2: Hypercall! B " TARGET_FMT_lx " C " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", // env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX]); #if 0 // Label op. // EBX contains addr of that data // ECX contains size of data // EDX contains the label; ~0UL for autoenc. if ((env->regs[R_EAX] == 7 || env->regs[R_EAX] == 8)) { printf ("hypercall -- EAX=0x%x\n", EAX); target_ulong addr = panda_virt_to_phys(env, env->regs[R_EBX]); target_ulong size = env->regs[R_ECX]; target_ulong label = env->regs[R_EDX]; if (!taintEnabled){ printf("taint2: Label operation detected @ %lu\n", rr_get_guest_instr_count()); printf("taint2: Labeling " TARGET_FMT_lx " to " TARGET_FMT_lx " with label " TARGET_FMT_lx ".\n", addr, addr + size, label); __taint2_enable_taint(); } LabelSetP ls = NULL; if (label != (target_ulong)~0UL) { ls = label_set_singleton(label); } // otherwise autoinc. qemu_log_mask(CPU_LOG_TAINT_OPS, "label: %lx[%lx+%lx] <- %lx (%lx)\n", (uint64_t)shadow->ram, (uint64_t)addr, (uint64_t)size, (uint64_t)label, (uint64_t)ls); for (unsigned i = 0; i < size; i++) { //printf("label %u\n", i); shadow->ram->set(addr + i, label_set_singleton(i)); } } #endif if (pandalog && env->regs[R_EAX] == 0xabcd) { // LAVA Hypercall target_ulong addr = panda_virt_to_phys(env, ECX); if ((int)addr == -1) { printf ("panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%x paddr=0x%x\n", (uint32_t) ECX, (uint32_t) addr); } else { PandaHypercallStruct phs; panda_virtual_memory_rw(env, ECX, (uint8_t *) &phs, sizeof(phs), false); if (phs.action == 11) { // it's a lava query lava_taint_query(phs); } if (phs.action == 12) { // it's an attack point sighting lava_attack_point(phs); } } } }
// hypercall-initiated taint query of some src-level extent void lava_taint_query (Panda__SrcInfoPri *si, target_ulong buf, target_ulong buf_len) { extern CPUState *cpu_single_env; CPUState *env = cpu_single_env; //if (pandalog && taintEnabled && (taint2_num_labels_applied() > 0)){ if (pandalog && taint2_enabled() && (taint2_num_labels_applied() > 0)){ // okay, taint is on and some labels have actually been applied // is there *any* taint on this extent uint32_t num_tainted = 0; bool is_strnlen = false; //bool is_strnlen = ((int) phs.len == -1); uint32_t offset=0; while (true) { // for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = buf + offset; //uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if (is_strnlen) { uint8_t c; panda_virtual_memory_rw(env, pa, &c, 1, false); // null terminator if (c==0) break; } if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { num_tainted ++; } } offset ++; // end of query by length or max string length if (!is_strnlen && offset == buf_len) break; //if (!is_strnlen && offset == phs.len) break; if (is_strnlen && (offset == LAVA_TAINT_QUERY_MAX_LEN)) break; } uint32_t len = offset; if (num_tainted) { printf("logging lava query\n"); // ok at least one byte in the extent is tainted // 1. write the pandalog entry that tells us something was tainted on this extent Panda__TaintQueryPri *tqh = (Panda__TaintQueryPri *) malloc (sizeof (Panda__TaintQueryPri)); *tqh = PANDA__TAINT_QUERY_PRI__INIT; tqh->buf = buf; //tqh->buf = phs.buf; tqh->len = len; tqh->num_tainted = num_tainted; // obtain the actual data out of memory // NOTE: first X bytes only! uint32_t data[LAVA_TAINT_QUERY_MAX_LEN]; uint32_t n = len; // grab at most X bytes from memory to pandalog // this is just a snippet. we dont want to write 1M buffer if (LAVA_TAINT_QUERY_MAX_LEN < len) n = LAVA_TAINT_QUERY_MAX_LEN; for (uint32_t i=0; i<n; i++) { data[i] = 0; uint8_t c; panda_virtual_memory_rw(env, buf+i, &c, 1, false); //panda_virtual_memory_rw(env, phs.buf+i, &c, 1, false); data[i] = c; } tqh->n_data = n; tqh->data = data; // 2. write out src-level info //Panda__SrcInfoPri *si = pandalog_src_info_create(phs); tqh->src_info = si; // 3. write out callstack info Panda__CallStack *cs = pandalog_callstack_create(); tqh->call_stack = cs; // 4. iterate over the bytes in the extent and pandalog detailed info about taint std::vector<Panda__TaintQuery *> tq; for (uint32_t offset=0; offset<len; offset++) { uint32_t va = buf + offset; //uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { tq.push_back(taint2_query_pandalog(a, offset)); } } } tqh->n_taint_query = tq.size(); tqh->taint_query = (Panda__TaintQuery **) malloc(sizeof(Panda__TaintQuery *) * tqh->n_taint_query); for (uint32_t i=0; i<tqh->n_taint_query; i++) { tqh->taint_query[i] = tq[i]; } Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.taint_query_pri = tqh; printf("about to write out taint query entry\n"); pandalog_write_entry(&ple); free(tqh->src_info); pandalog_callstack_free(tqh->call_stack); for (uint32_t i=0; i<tqh->n_taint_query; i++) { pandalog_taint_query_free(tqh->taint_query[i]); } free(tqh); } } }
void pfun(void *var_ty_void, const char *var_nm, LocType loc_t, target_ulong loc, void *in_args){ //void pfun(const char *var_ty, const char *var_nm, LocType loc_t, target_ulong loc, void *in_args){ // restore args const char *var_ty = (const char *) var_ty_void; struct args *args = (struct args *) in_args; CPUState *pfun_env = args->env; const char *src_filename = args->src_filename; uint64_t src_linenum = args->src_linenum; target_ulong guest_dword; std::string ty_string = std::string(var_ty); size_t num_derefs = std::count(ty_string.begin(), ty_string.end(), '*'); size_t i; //Panda__SrcInfoPri *si = pandalog_src_info_pri_create(const char *src_filename, uint64_t src_linenum, const char *src_ast_node_name); Panda__SrcInfoPri *si = pandalog_src_info_pri_create(src_filename, src_linenum, var_nm); switch (loc_t){ case LocReg: guest_dword = pfun_env->regs[loc]; if (num_derefs > 0) { for (i = 0; i < num_derefs; i++) { int rc = panda_virtual_memory_rw(pfun_env, guest_dword, (uint8_t *)&guest_dword, sizeof(guest_dword), 0); if (0 != rc) break; } if (0 != taint2_query_ram(panda_virt_to_phys(pfun_env, guest_dword))) { printf("VAR REG: %s %s in Reg %d\n", var_ty, var_nm, loc); printf(" => 0x%x, derefs: %ld\n", guest_dword, i); printf(" ==Location is tainted!==\n"); lava_taint_query(si, guest_dword, 1); } } else { // only query reg taint if the reg number is less than the number of registers if (loc < CPU_NB_REGS) { if (0 != taint2_query_reg(loc, 0)) { printf("VAR REG: %s %s in Reg %d\n", var_ty, var_nm, loc); printf(" => 0x%x, derefs: %d\n", guest_dword, 0); printf(" ==Reg is tainted!==\n"); } } } break; case LocMem: guest_dword = loc; for (i = 0; i < num_derefs; i++) { if (0 != panda_virtual_memory_rw(pfun_env, guest_dword, (uint8_t *)&guest_dword, sizeof(guest_dword), 0)){ break; } } if (0 != taint2_query_ram(panda_virt_to_phys(pfun_env, guest_dword))) { printf("VAR MEM: %s %s @ 0x%x\n", var_ty, var_nm, loc); printf(" => 0x%x, derefs: %ld\n", guest_dword, i); printf(" ==Location is tainted!==\n"); lava_taint_query(si, guest_dword, 1); } break; case LocConst: //printf("VAR CONST: %s %s as 0x%x\n", var_ty, var_nm, loc); break; case LocErr: //printf("VAR does not have a location we could determine. Most likely because the var is split among multiple locations\n"); break; // should not get here default: assert(1==0); } }
// Support all features of label and query program void i386_hypercall_callback(CPUState *env){ if (taintEnabled && pandalog) { // LAVA Hypercall #ifdef TAINT_LEGACY_HYPERCALL target_ulong buf_start = EBX; target_ulong buf_len = ECX; long label = EDI; // call to label data // EBX contains addr of that data // ECX contains size of data // EDI is the label integer // EDX = starting offset (for positional labels only) // -mostly not used, this is managed in pirate_utils if (EAX == 7 || EAX == 8){ if (!taintEnabled){ printf("Taint plugin: Label operation detected\n"); printf("Enabling taint processing\n"); __taint2_enable_taint(); } if (EAX == 7){ // Standard buffer label printf("taint2: single taint label\n"); taint2_add_taint_ram_single_label(env, (uint64_t)buf_start, (int)buf_len, label); } else if (EAX == 8){ // Positional buffer label printf("taint2: positional taint label\n"); taint2_add_taint_ram_pos(env, (uint64_t)buf_start, (int)buf_len); } } /* //mz Query taint on this buffer //mz EBX = start of buffer (VA) //mz ECX = size of buffer (bytes) // EDX = starting offset - for file queries // -mostly not used, this is managed in pirate_utils else if (env->regs[R_EAX] == 9){ //Query taint on label if (taintEnabled){ printf("Taint plugin: Query operation detected\n"); Addr a = make_maddr(buf_start); bufplot(env, shadow, &a, (int)buf_len); } //printf("Disabling taint processing\n"); //taintEnabled = false; //taintJustDisabled = true; //printf("Label occurrences on HD: %d\n", shad_dir_occ_64(shadow->hd)); } else if (env->regs[R_EAX] == 10){ // Guest util done - reset positional label counter taint_pos_count = 0; } */ #else target_ulong addr = panda_virt_to_phys(env, EAX); if ((int)addr == -1) { printf ("panda hypercall with ptr to invalid PandaHypercallStruct: vaddr=0x%x paddr=0x%x\n", (uint32_t) EAX, (uint32_t) addr); } else { PandaHypercallStruct phs; panda_virtual_memory_rw(env, EAX, (uint8_t *) &phs, sizeof(phs), false); if (phs.magic == 0xabcd) { if (phs.action == 11) { // it's a lava query lava_taint_query(phs); } else if (phs.action == 12) { // it's an attack point sighting lava_attack_point(phs); } else { printf("Unknown hypercall action %d\n", phs.action); } } else { printf ("Invalid magic value in PHS struct: %x != 0xabcd.\n", phs.magic); } } #endif // TAINT_LEGACY_HYPERCALL } }
// hypercall-initiated taint query of some src-level extent void lava_taint_query (PandaHypercallStruct phs) { extern CPUState *cpu_single_env; CPUState *env = cpu_single_env; if (pandalog && taintEnabled && (taint2_num_labels_applied() > 0)){ // okay, taint is on and some labels have actually been applied // is there *any* taint on this extent uint32_t num_tainted = 0; for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { num_tainted ++; } } } if (num_tainted) { // ok at least one byte in the extent is tainted // 1. write the pandalog entry that tells us something was tainted on this extent Panda__TaintQueryHypercall *tqh = (Panda__TaintQueryHypercall *) malloc (sizeof (Panda__TaintQueryHypercall)); *tqh = PANDA__TAINT_QUERY_HYPERCALL__INIT; tqh->buf = phs.buf; tqh->len = phs.len; tqh->num_tainted = num_tainted; // obtain the actual data out of memory // NOTE: first 32 bytes only! uint32_t data[32]; uint32_t n = phs.len; // grab at most 32 bytes from memory to pandalog // this is just a snippet. we dont want to write 1M buffer if (32 < phs.len) n = 32; for (uint32_t i=0; i<n; i++) { data[i] = 0; uint8_t c; panda_virtual_memory_rw(env, phs.buf+i, &c, 1, false); data[i] = c; } tqh->n_data = n; tqh->data = data; // 2. write out src-level info Panda__SrcInfo *si = pandalog_src_info_create(phs); tqh->src_info = si; // 3. write out callstack info Panda__CallStack *cs = pandalog_callstack_create(); tqh->call_stack = cs; // 4. iterate over the bytes in the extent and pandalog detailed info about taint std::vector<Panda__TaintQuery *> tq; for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { tq.push_back(__taint2_query_pandalog(a, offset)); } } } tqh->n_taint_query = tq.size(); tqh->taint_query = (Panda__TaintQuery **) malloc(sizeof(Panda__TaintQuery *) * tqh->n_taint_query); for (uint32_t i=0; i<tqh->n_taint_query; i++) { tqh->taint_query[i] = tq[i]; } Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.taint_query_hypercall = tqh; pandalog_write_entry(&ple); free(tqh->src_info); pandalog_callstack_free(tqh->call_stack); for (uint32_t i=0; i<tqh->n_taint_query; i++) { __pandalog_taint_query_free(tqh->taint_query[i]); } free(tqh); } } }
/** * @brief Hypercall-initiated taint query of some src-level extent. */ void taint_query_hypercall(PandaHypercallStruct phs) { CPUState *cpu = first_cpu; if (pandalog && taintEnabled && (taint2_num_labels_applied() > 0)) { // okay, taint is on and some labels have actually been applied // is there *any* taint on this extent uint32_t num_tainted = 0; bool is_strnlen = ((int) phs.len == -1); uint32_t offset=0; while (true) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(cpu, va); if (is_strnlen) { uint8_t c; panda_virtual_memory_rw(cpu, pa, &c, 1, false); // null terminator if (c==0) break; } if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { num_tainted ++; } } offset ++; // end of query by length or max string length if (!is_strnlen && offset == phs.len) break; if (is_strnlen && (offset == QUERY_HYPERCALL_MAX_LEN)) break; } uint32_t len = offset; if (num_tainted) { // ok at least one byte in the extent is tainted // 1. write the pandalog entry that tells us something was tainted on this extent Panda__TaintQueryHypercall *tqh = (Panda__TaintQueryHypercall *) malloc (sizeof (Panda__TaintQueryHypercall)); *tqh = PANDA__TAINT_QUERY_HYPERCALL__INIT; tqh->buf = phs.buf; tqh->len = len; tqh->num_tainted = num_tainted; // obtain the actual data out of memory // NOTE: first X bytes only! uint32_t data[QUERY_HYPERCALL_MAX_LEN]; uint32_t n = len; // grab at most X bytes from memory to pandalog // this is just a snippet. we dont want to write 1M buffer if (QUERY_HYPERCALL_MAX_LEN < len) n = QUERY_HYPERCALL_MAX_LEN; for (uint32_t i=0; i<n; i++) { data[i] = 0; uint8_t c; panda_virtual_memory_rw(cpu, phs.buf+i, &c, 1, false); data[i] = c; } tqh->n_data = n; tqh->data = data; // 2. write out src-level info Panda__SrcInfo *si = pandalog_src_info_create(phs); tqh->src_info = si; // 3. write out callstack info Panda__CallStack *cs = pandalog_callstack_create(); tqh->call_stack = cs; std::vector<Panda__TaintQuery *> tq; for (uint32_t offset=0; offset<len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(cpu, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { tq.push_back(taint2_query_pandalog(a, offset)); } } } tqh->n_taint_query = tq.size(); tqh->taint_query = (Panda__TaintQuery **) malloc(sizeof(Panda__TaintQuery *) * tqh->n_taint_query); for (uint32_t i=0; i<tqh->n_taint_query; i++) { tqh->taint_query[i] = tq[i]; } Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.taint_query_hypercall = tqh; pandalog_write_entry(&ple); free(tqh->src_info); pandalog_callstack_free(tqh->call_stack); for (uint32_t i=0; i<tqh->n_taint_query; i++) { pandalog_taint_query_free(tqh->taint_query[i]); } free(tqh); } } }
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 }