Exemplo n.º 1
0
void
cfi_call_instrumentation_snapahot(void *dcontext, instrlist_t *ilist, instr_t *where, void *callee)
{
    uint dstack_offs = 0, pad = 0;

    unsigned int eflags_offs;

    CFI_ASSERT(dcontext != NULL, "cfi_call_instrumentation_snapahot: dcontext cannot be NULL");

    instr_t *next_snapshot = INSTR_CREATE_label(dcontext);
    PRE(ilist, where, INSTR_CREATE_pushf(dcontext));
    dstack_offs += XSP_SZ;
    eflags_offs = dstack_offs;

    PRE(ilist, where, INSTR_CREATE_push(dcontext, opnd_create_reg(DR_REG_RDI)));
    dstack_offs += XSP_SZ;

    PRE(ilist, where, INSTR_CREATE_mov_imm(dcontext, opnd_create_reg(DR_REG_RDI), OPND_CREATE_INT64(&flag_memory_snapshot)));
    PRE(ilist, where, INSTR_CREATE_mov_ld(dcontext, opnd_create_reg(DR_REG_RDI), opnd_create_base_disp(DR_REG_RDI, DR_REG_NULL, 0, 0, OPSZ_PTR)));
    PRE(ilist, where, INSTR_CREATE_cmp(dcontext, opnd_create_reg(DR_REG_RDI), OPND_CREATE_INT8(0x0)));
    PRE(ilist, where, INSTR_CREATE_jcc(dcontext, OP_je, opnd_create_instr(next_snapshot)));

    PRE(ilist, where, INSTR_CREATE_push(dcontext,
                          opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0,
                          dstack_offs - eflags_offs, OPSZ_STACK)));

    PRE(ilist, where, INSTR_CREATE_and(dcontext,
                         opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0, 0,
                                               OPSZ_STACK),
                         OPND_CREATE_INT32(~(EFLAGS_NON_SYSTEM | EFLAGS_IF))));

    PRE(ilist, where, INSTR_CREATE_popf(dcontext));

    instrlist_set_our_mangling(ilist, true);
    cfi_insert_meta_native_call_vargs(dcontext, ilist, where, true/*clean*/, callee);
    instrlist_set_our_mangling(ilist, false);

    cfi_insert_native_call(dcontext, ilist, where, callee /*, opnd_create_reg(DR_REG_RAX)*/);

    PRE(ilist, where, next_snapshot);
    PRE(ilist, where, INSTR_CREATE_pop(dcontext, opnd_create_reg(DR_REG_RDI)));
    PRE(ilist, where, INSTR_CREATE_popf(dcontext));



   /* dstack_offs = cfi_prepare_for_native_call(dcontext, ilist, where);

     instrlist_set_our_mangling(ilist, true);
     cfi_insert_meta_native_call_vargs(dcontext, ilist, where, true*//*clean*//*, callee);
     instrlist_set_our_mangling(ilist, false);

     cfi_cleanup_after_native_call(dcontext, ilist, where);*/
}
Exemplo n.º 2
0
static void
test_instr_as_immed(void)
{
    void *drcontext = dr_get_current_drcontext();
    instrlist_t *ilist = instrlist_create(drcontext);
    byte *pc;
    instr_t *ins0, *ins1, *ins2;
    opnd_t opnd;
    byte *highmem = PREFERRED_ADDR;
    pc = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                               DR_MEMPROT_EXEC, highmem);
    ASSERT(pc == highmem);

    /* Test push_imm of instr */
    ins0 = INSTR_CREATE_nop(drcontext);
    instrlist_append(ilist, ins0);
    instrlist_insert_push_instr_addr(drcontext, ins0, highmem,
                                     ilist, NULL, &ins1, &ins2);
    ASSERT(ins2 != NULL);
    instrlist_append(ilist, INSTR_CREATE_pop
                     (drcontext, opnd_create_reg(DR_REG_RAX)));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, highmem, true);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < highmem + PAGE_SIZE);
    pc = ((byte* (*)(void))highmem)();
    ASSERT(pc == highmem);

    /* Test mov_imm of instr */
    ins0 = INSTR_CREATE_nop(drcontext);
    instrlist_append(ilist, ins0);
    /* Beyond TOS, but a convenient mem dest */
    opnd = opnd_create_base_disp(DR_REG_RSP, DR_REG_NULL, 0, -8, OPSZ_8);
    instrlist_insert_mov_instr_addr(drcontext, ins0, highmem, opnd,
                                    ilist, NULL, &ins1, &ins2);
    ASSERT(ins2 != NULL);
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_RAX), opnd));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, highmem, true);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < highmem + PAGE_SIZE);
    pc = ((byte* (*)(void))highmem)();
    ASSERT(pc == highmem);

    instrlist_clear_and_destroy(drcontext, ilist);
    dr_raw_mem_free(highmem, PAGE_SIZE);
}
Exemplo n.º 3
0
static void
test_indirect_cti(void *dc)
{
    /*
    0x004275f4   ff d1                call   %ecx %esp -> %esp (%esp) 
    0x004275f4   66 ff d1             data16 call   %cx %esp -> %esp (%esp) 
    0x004275f4   67 ff d1             addr16 call   %ecx %sp -> %sp (%sp) 
    0x00427794   ff 19                lcall  (%ecx) %esp -> %esp (%esp) 
    0x00427794   66 ff 19             data16 lcall  (%ecx) %esp -> %esp (%esp) 
    0x00427794   67 ff 1f             addr16 lcall  (%bx) %sp -> %sp (%sp) 
    */
    instr_t *instr;
    instr = INSTR_CREATE_call_ind(dc, opnd_create_reg(REG_XCX));
    test_instr_encode(dc, instr, 2);
#ifndef X64 /* only on AMD can we shorten, so we don't test it */
    instr = instr_create_2dst_2src(dc, OP_call_ind, opnd_create_reg(REG_XSP),
                                   opnd_create_base_disp(REG_XSP, REG_NULL, 0, -2, OPSZ_2),
                                   opnd_create_reg(REG_CX), opnd_create_reg(REG_XSP));
    test_instr_encode(dc, instr, 3);
#endif
    instr = instr_create_2dst_2src(dc, OP_call_ind,
                                   opnd_create_reg(IF_X64_ELSE(REG_ESP, REG_SP)),
                                   opnd_create_base_disp(IF_X64_ELSE(REG_ESP, REG_SP),
                                                         REG_NULL, 0, -(int)sizeof(void*),
                                                         OPSZ_ret),
                                   /* only on AMD can we shorten, so we don't test it */
                                   opnd_create_reg(REG_XCX),
                                   opnd_create_reg(IF_X64_ELSE(REG_ESP, REG_SP)));
    test_instr_encode(dc, instr, 3);

    /* invalid to have far call go through reg since needs 6 bytes */
    instr = INSTR_CREATE_call_far_ind(dc, opnd_create_base_disp(REG_XCX, REG_NULL, 0, 0,
                                                                OPSZ_6));
    test_instr_encode(dc, instr, 2);
    instr = instr_create_2dst_2src(dc, OP_call_far_ind, opnd_create_reg(REG_XSP),
                                   opnd_create_base_disp(REG_XSP, REG_NULL, 0, -4, OPSZ_4),
                                   opnd_create_base_disp(REG_XCX, REG_NULL, 0, 0,
                                                         OPSZ_4),
                                   opnd_create_reg(REG_XSP));
    test_instr_encode(dc, instr, 3);
    instr = instr_create_2dst_2src(dc, OP_call_far_ind,
                                   opnd_create_reg(IF_X64_ELSE(REG_ESP, REG_SP)),
                                   opnd_create_base_disp(IF_X64_ELSE(REG_ESP, REG_SP),
                                                         REG_NULL, 0, -8,
                                                         OPSZ_8_rex16_short4),
                                   opnd_create_base_disp(IF_X64_ELSE(REG_EBX, REG_BX),
                                                         REG_NULL, 0, 0, OPSZ_6),
                                   opnd_create_reg(IF_X64_ELSE(REG_ESP, REG_SP)));
    test_instr_encode(dc, instr, 3);

    /* case 10710: make sure we can encode these guys
         0x00428844   0e                   push   %cs %esp -> %esp (%esp) 
         0x00428844   1e                   push   %ds %esp -> %esp (%esp) 
         0x00428844   16                   push   %ss %esp -> %esp (%esp) 
         0x00428844   06                   push   %es %esp -> %esp (%esp) 
         0x00428844   0f a0                push   %fs %esp -> %esp (%esp) 
         0x00428844   0f a8                push   %gs %esp -> %esp (%esp) 
         0x00428844   1f                   pop    %esp (%esp) -> %ds %esp 
         0x00428844   17                   pop    %esp (%esp) -> %ss %esp 
         0x00428844   07                   pop    %esp (%esp) -> %es %esp 
         0x00428844   0f a1                pop    %esp (%esp) -> %fs %esp 
         0x00428844   0f a9                pop    %esp (%esp) -> %gs %esp 
     */
#ifndef X64
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_CS)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_DS)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_SS)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_ES)), 1);
#endif
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_FS)), 2);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_GS)), 2);
#ifndef X64
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_DS)), 1);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_SS)), 1);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_ES)), 1);
#endif
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_FS)), 2);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_GS)), 2);
}
Exemplo n.º 4
0
static void
test_indirect_cti(void *dc)
{
    /*
    0x004275f4   ff d1                call   %ecx %esp -> %esp (%esp) 
    0x004275f4   66 ff d1             data16 call   %cx %esp -> %esp (%esp) 
    0x004275f4   67 ff d1             addr16 call   %ecx %sp -> %sp (%sp) 
    0x00427794   ff 19                lcall  (%ecx) %esp -> %esp (%esp) 
    0x00427794   66 ff 19             data16 lcall  (%ecx) %esp -> %esp (%esp) 
    0x00427794   67 ff 1f             addr16 lcall  (%bx) %sp -> %sp (%sp) 
    */
    instr_t *instr;
    instr = INSTR_CREATE_call_ind(dc, opnd_create_reg(REG_ECX));
    test_instr_encode(dc, instr, 2);
    instr = instr_create_2dst_2src(dc, OP_call_ind, opnd_create_reg(REG_ESP),
                                   opnd_create_base_disp(REG_ESP, REG_NULL, 0, 0, OPSZ_2),
                                   opnd_create_reg(REG_CX), opnd_create_reg(REG_ESP));
    test_instr_encode(dc, instr, 3);
    instr = instr_create_2dst_2src(dc, OP_call_ind, opnd_create_reg(REG_SP),
                                   opnd_create_base_disp(REG_SP, REG_NULL, 0, 0, OPSZ_4_short2),
                                   opnd_create_reg(REG_ECX), opnd_create_reg(REG_SP));
    test_instr_encode(dc, instr, 3);

    /* invalid to have far call go through reg since needs 6 bytes */
    instr = INSTR_CREATE_call_far_ind(dc, opnd_create_base_disp(REG_ECX, REG_NULL, 0, 0,
                                                                OPSZ_6));
    test_instr_encode(dc, instr, 2);
    instr = instr_create_2dst_2src(dc, OP_call_far_ind, opnd_create_reg(REG_ESP),
                                   opnd_create_base_disp(REG_ESP, REG_NULL, 0, 0, OPSZ_2),
                                   opnd_create_base_disp(REG_ECX, REG_NULL, 0, 0,
                                                         OPSZ_4),
                                   opnd_create_reg(REG_ESP));
    test_instr_encode(dc, instr, 3);
    instr = instr_create_2dst_2src(dc, OP_call_far_ind, opnd_create_reg(REG_SP),
                                   opnd_create_base_disp(REG_SP, REG_NULL, 0, 0, OPSZ_4_short2),
                                   opnd_create_base_disp(REG_BX, REG_NULL, 0, 0,
                                                         OPSZ_6),
                                   opnd_create_reg(REG_SP));
    test_instr_encode(dc, instr, 3);

    /* case 10710: make sure we can encode these guys
         0x00428844   0e                   push   %cs %esp -> %esp (%esp) 
         0x00428844   1e                   push   %ds %esp -> %esp (%esp) 
         0x00428844   16                   push   %ss %esp -> %esp (%esp) 
         0x00428844   06                   push   %es %esp -> %esp (%esp) 
         0x00428844   0f a0                push   %fs %esp -> %esp (%esp) 
         0x00428844   0f a8                push   %gs %esp -> %esp (%esp) 
         0x00428844   1f                   pop    %esp (%esp) -> %ds %esp 
         0x00428844   17                   pop    %esp (%esp) -> %ss %esp 
         0x00428844   07                   pop    %esp (%esp) -> %es %esp 
         0x00428844   0f a1                pop    %esp (%esp) -> %fs %esp 
         0x00428844   0f a9                pop    %esp (%esp) -> %gs %esp 
     */
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_CS)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_DS)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_SS)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_ES)), 1);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_FS)), 2);
    test_instr_encode(dc, INSTR_CREATE_push(dc, opnd_create_reg(SEG_GS)), 2);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_DS)), 1);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_SS)), 1);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_ES)), 1);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_FS)), 2);
    test_instr_encode(dc, INSTR_CREATE_pop(dc, opnd_create_reg(SEG_GS)), 2);
}
Exemplo n.º 5
0
void
watchpoint_indirect_call_event(dcontext_t *drcontext, instrlist_t *ilist, instr_t *instr,
                     instr_t *next_instr, bool mangle_calls, uint flags)
{
    opnd_t instr_opnd;
    reg_id_t base_reg;
    unsigned long used_registers = 0;
    app_pc pc;
    struct memory_operand_modifier ops = {0};

    instr_t *begin_instrumenting = INSTR_CREATE_label(drcontext);
    instr_t *done_instrumenting = INSTR_CREATE_label(drcontext);
    instr_t *nop = INSTR_CREATE_nop(drcontext);
    instr_t *emulated;


    memset(&ops, 0, sizeof(struct memory_operand_modifier));

    if(instr_reads_memory(instr)) {
        instr_opnd = instr_get_src(instr, 0);
        if (opnd_is_rel_addr(instr_opnd) || opnd_is_abs_addr(instr_opnd)) {

        }else if (opnd_is_base_disp(instr_opnd)) {

            for_each_src_operand(instr, &ops, (opnd_callback_t *) memory_src_operand_finder);
           // base_reg = opnd_get_reg(instr_opnd);

            switch(ops.found_operand.value.base_disp.base_reg) {
                case DR_REG_RSP: case DR_REG_ESP: case DR_REG_SP:
                case DR_REG_RBP: case DR_REG_EBP: case DR_REG_BP:
                    return;
                default:
                  break;
            }

            collect_regs(&used_registers, instr, instr_num_srcs, instr_get_src );
            collect_regs(&used_registers, instr, instr_num_dsts, instr_get_dst );

            reg_id_t reg_watched_addr = get_next_free_reg(&used_registers);
            opnd_t opnd_watched_addr = opnd_create_reg(reg_watched_addr);

            reg_id_t reg_unwatched_addr = get_next_free_reg(&used_registers);
            opnd_t opnd_unwatched_addr = opnd_create_reg(reg_unwatched_addr);

            PRE(ilist, instr, begin_instrumenting);
            PRE(ilist, instr, INSTR_CREATE_push(drcontext, opnd_watched_addr));
            PRE(ilist, instr, INSTR_CREATE_push(drcontext, opnd_unwatched_addr));
            PRE(ilist, instr, INSTR_CREATE_pushf(drcontext));
            PRE(ilist, instr, INSTR_CREATE_lea(drcontext, opnd_watched_addr, opnd_create_base_disp(opnd_get_base(ops.found_operand),
                                                        opnd_get_index(ops.found_operand), opnd_get_scale(ops.found_operand),
                                                        opnd_get_disp(ops.found_operand), OPSZ_lea)));

            PRE(ilist, instr, INSTR_CREATE_mov_imm(drcontext, opnd_unwatched_addr,
                                            OPND_CREATE_INT64(WATCHPOINT_INDEX_MASK)));
            PRE(ilist, instr, INSTR_CREATE_or(drcontext, opnd_unwatched_addr, opnd_watched_addr));

            emulated = instr_clone(drcontext, instr);
            emulated->translation = 0;

            ops.replacement_operand = opnd_create_base_disp(
                    reg_unwatched_addr, DR_REG_NULL,1, 0 , ops.found_operand.size);

            for_each_operand(emulated, &ops, (opnd_callback_t *) memory_operand_replacer);

            PRE(ilist, instr, INSTR_CREATE_popf(drcontext));
            PRE(ilist, instr, emulated);
            PRE(ilist, instr, INSTR_CREATE_pop(drcontext, opnd_unwatched_addr));
            PRE(ilist, instr, INSTR_CREATE_pop(drcontext, opnd_watched_addr));

            PRE(ilist, instr, INSTR_CREATE_jmp_short(drcontext,
                    opnd_create_instr(done_instrumenting)));

            pc = instr->translation;
            instr->translation = 0; // hack!
            instr_being_modified(instr, false);
            instr_set_ok_to_mangle(instr, false);

            if(NULL != pc){
                nop->translation = pc + instr->length;
            }
            POST(ilist, instr, nop);
            POST(ilist, instr, done_instrumenting);

        }
    }
}