Ejemplo n.º 1
0
// 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);
                    }
                }
            }
        }
    }
}
Ejemplo n.º 2
0
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);
        }
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
// 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;
    }
}
Ejemplo n.º 6
0
// 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);
            }
        }    
    }
}
Ejemplo n.º 7
0
// 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);
        }
    }
}
Ejemplo n.º 8
0
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);
    }
}
Ejemplo n.º 9
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
    }
}
Ejemplo n.º 10
0
// 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);
        }
    }
}
Ejemplo n.º 11
0
/**
 * @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);
        }
    }
}
Ejemplo n.º 12
0
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
}