Пример #1
0
// R0 is command (label or query)
// R1 is buf_start
// R2 is length
// R3 is offset (not currently implemented, managed in pirate_utils)
// R4 is the label integer
void arm_hypercall_callback(CPUState *env){
    target_ulong buf_start = env->regs[1];
    target_ulong buf_len = env->regs[2];
    long label = env->regs[4];

    if (env->regs[0] == 7 || env->regs[0] == 8){
        if (!taintEnabled){
            printf("Taint plugin: Label operation detected\n");
            printf("Enabling taint processing\n");
            __taint_enable_taint();
        }
        TaintOpBuffer *tempBuf = tob_new( buf_len * sizeof(TaintOp));
        if (env->regs[0] == 7){
            // Standard buffer label
            add_taint_ram_single_label(env, shadow, tempBuf,
                (uint64_t)buf_start, (int)buf_len, label);
        }
        else if (env->regs[0] == 8){
            // Positional buffer label
            add_taint_ram_pos(env, shadow, tempBuf, (uint64_t)buf_start, (int)buf_len);
        }
        tob_delete(tempBuf);
    }

    else if (env->regs[0] == 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[0] == 10){
        // Guest util done - reset positional label counter
        taint_pos_count = 0;
    }
}
Пример #2
0
// Called whenever the taint state changes.
void taint_state_changed(FastShad *fast_shad, uint64_t shad_addr) {
    Addr addr;
    if (fast_shad == shadow->llv) {
        addr = make_laddr(shad_addr / MAXREGSIZE, shad_addr % MAXREGSIZE);
    } else if (fast_shad == shadow->ram) {
        addr = make_maddr(shad_addr);
    } else if (fast_shad == shadow->grv) {
        addr = make_greg(shad_addr / sizeof(target_ulong), shad_addr % sizeof(target_ulong));
    } else if (fast_shad == shadow->gsv) {
        addr.typ = GSPEC;
        addr.val.gs = shad_addr;
        addr.off = 0;
        addr.flag = (AddrFlag)0;
    } else if (fast_shad == shadow->ret) {
        addr.typ = RET;
        addr.val.ret = 0;
        addr.off = shad_addr;
        addr.flag = (AddrFlag)0;
    } else return;

    PPP_RUN_CB(on_taint_change, addr);
}
Пример #3
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);
        }
    }
}
Пример #4
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);
        }
    }
}
Пример #5
0
// this is for much of the hd taint transfers.
// this gets called from rr_log.c, rr_replay_skipped_calls, RR_CALL_HD_TRANSFER
// case.
int cb_replay_hd_transfer_taint(CPUState *env, uint32_t type, uint64_t src_addr,
        uint64_t dest_addr, uint32_t num_bytes) {
    // Replay hd transfer as taint transfer
    if (taintEnabled) {
        TaintOp top;
        top.typ = BULKCOPYOP;
        top.val.bulkcopy.l = num_bytes;
        switch (type) {
            case HD_TRANSFER_HD_TO_IOB:
#ifdef TAINTDEBUG
                printf("replay_hd_transfer HD_TRANSFER_HD_TO_IOB\n");
#endif
                top.val.bulkcopy.a = make_haddr(src_addr);
                top.val.bulkcopy.b = make_iaddr(dest_addr);
                break;
            case HD_TRANSFER_IOB_TO_HD:
#ifdef TAINTDEBUG
                printf("replay_hd_transfer HD_TRANSFER_IOB_TO_HD\n");
#endif
                top.val.bulkcopy.a = make_iaddr(src_addr);
                top.val.bulkcopy.b = make_haddr(dest_addr);
                break;
            case HD_TRANSFER_PORT_TO_IOB:
#ifdef TAINTDEBUG
                printf("replay_hd_transfer HD_TRANSFER_PORT_TO_IOB\n");
#endif
                top.val.bulkcopy.a = make_paddr(src_addr);
                top.val.bulkcopy.b = make_iaddr(dest_addr);
                break;
            case HD_TRANSFER_IOB_TO_PORT:
#ifdef TAINTDEBUG
                printf("replay_hd_transfer HD_TRANSFER_IOB_TO_PORT\n");
#endif
                top.val.bulkcopy.a = make_iaddr(src_addr);
                top.val.bulkcopy.b = make_paddr(dest_addr);
                break;
            case HD_TRANSFER_HD_TO_RAM:
#ifdef TAINTDEBUG
                printf("replay_hd_transfer HD_TRANSFER_HD_TO_RAM\n");
                printf("\tSource: 0x%lx, Dest: 0x%lx, Len: %d\n",
                    src_addr, dest_addr, num_bytes);
#endif
                top.val.bulkcopy.a = make_haddr(src_addr);
                top.val.bulkcopy.b = make_maddr(dest_addr);
                break;
            case HD_TRANSFER_RAM_TO_HD:
#ifdef TAINTDEBUG
                printf("replay_hd_transfer HD_TRANSFER_RAM_TO_HD\n");
                printf("\tSource: 0x%lx, Dest: 0x%lx, Len: %d\n",
                    src_addr, dest_addr, num_bytes);
#endif
                top.val.bulkcopy.a = make_maddr(src_addr);
                top.val.bulkcopy.b = make_haddr(dest_addr);
                break;
            default:
                printf ("Impossible hd transfer type: %d\n", type);
                assert (1==0);
        }
        // make the taint op buffer bigger if necessary
        tob_resize(&tob_io_thread);
        // add bulk copy corresponding to this hd transfer to buffer
        // of taint ops for io thread.
        tob_op_write(tob_io_thread, &top);
    }
    return 0;
}
Пример #6
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);
        }
    }
}