Esempio n. 1
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);
}
Esempio n. 2
0
static void
test_instr_opnds(void *dc)
{
    /* Verbose disasm looks like this:
     * 32-bit:
     *   0x080f1ae0  ff 25 e7 1a 0f 08    jmp    0x080f1ae7
     *   0x080f1ae6  b8 ef be ad de       mov    $0xdeadbeef -> %eax
     *   0x080f1ae0  a0 e6 1a 0f 08       mov    0x080f1ae6 -> %al
     *   0x080f1ae5  b8 ef be ad de       mov    $0xdeadbeef -> %eax
     * 64-bit:
     *   0x00000000006b8de0  ff 25 02 00 00 00    jmp    <rel> 0x00000000006b8de8
     *   0x00000000006b8de6  48 b8 ef be ad de 00 mov    $0x00000000deadbeef -> %rax
     *                       00 00 00
     *   0x00000000006b8de0  8a 05 02 00 00 00    mov    <rel> 0x00000000006b8de8 -> %al
     *   0x00000000006b8de6  48 b8 ef be ad de 00 mov    $0x00000000deadbeef -> %rax
     *                       00 00 00
     */
    instrlist_t *ilist;
    instr_t *tgt, *instr;
    byte *pc;
    short disp;

    ilist = instrlist_create(dc);

    /* test mem instr as ind jmp target */
    tgt = INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX),
                               opnd_create_immed_int(0xdeadbeef, OPSZ_PTR));
    /* skip rex+opcode */
    disp = IF_X64_ELSE(2,1);
    instrlist_append(ilist, INSTR_CREATE_jmp_ind
                     (dc, opnd_create_mem_instr(tgt, disp, OPSZ_PTR)));
    instrlist_append(ilist, tgt);
    pc = instrlist_encode(dc, ilist, buf, true/*instr targets*/);
    ASSERT(pc != NULL);
    instrlist_clear(dc, ilist);
#if VERBOSE
    pc = disassemble_with_info(dc, buf, STDOUT, true, true);
    pc = disassemble_with_info(dc, pc, STDOUT, true, true);
#endif
    pc = buf;
    instr = instr_create(dc);
    pc = decode(dc, pc, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_jmp_ind);
#ifdef X64
    ASSERT(opnd_is_rel_addr(instr_get_src(instr, 0)));
    ASSERT(opnd_get_addr(instr_get_src(instr, 0)) == pc + disp);
#else
    ASSERT(opnd_is_base_disp(instr_get_src(instr, 0)));
    ASSERT(opnd_get_base(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_index(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_disp(instr_get_src(instr, 0)) == (ptr_int_t)pc + disp);
#endif

    /* test mem instr as TYPE_O */
    tgt = INSTR_CREATE_mov_imm(dc, opnd_create_reg(DR_REG_XAX),
                               opnd_create_immed_int(0xdeadbeef, OPSZ_PTR));
    /* skip rex+opcode */
    disp = IF_X64_ELSE(2,1);
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (dc, opnd_create_reg(DR_REG_AL),
                      opnd_create_mem_instr(tgt, disp, OPSZ_1)));
    instrlist_append(ilist, tgt);
    pc = instrlist_encode(dc, ilist, buf, true/*instr targets*/);
    ASSERT(pc != NULL);
    instrlist_clear(dc, ilist);
#if VERBOSE
    pc = disassemble_with_info(dc, buf, STDOUT, true, true);
    pc = disassemble_with_info(dc, pc, STDOUT, true, true);
#endif
    pc = buf;
    instr_reset(dc, instr);
    pc = decode(dc, pc, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_mov_ld);
#ifdef X64
    ASSERT(opnd_is_rel_addr(instr_get_src(instr, 0)));
    ASSERT(opnd_get_addr(instr_get_src(instr, 0)) == pc + disp);
#else
    ASSERT(opnd_is_base_disp(instr_get_src(instr, 0)));
    ASSERT(opnd_get_base(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_index(instr_get_src(instr, 0)) == REG_NULL);
    ASSERT(opnd_get_disp(instr_get_src(instr, 0)) == (ptr_int_t)pc + disp);
#endif

    instr_free(dc, instr);
    instrlist_destroy(dc, ilist);
}
Esempio n. 3
0
static void
reachability_test(void)
{
    void *drcontext = dr_get_current_drcontext();
    instrlist_t *ilist = instrlist_create(drcontext);
    byte *gencode = (byte *)
        dr_nonheap_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC);
    byte *pc;
    int res;
    byte *highmem = PREFERRED_ADDR;
    pc = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                               DR_MEMPROT_EXEC, highmem);
    ASSERT(pc == highmem);

    dr_fprintf(STDERR, "  reachability test...");

    /* Test auto-magically turning rip-rel that won't reach but targets xax
     * into absmem.
     */
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_EAX),
                      opnd_create_rel_addr(highmem, OPSZ_4)));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, gencode, false);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < gencode + PAGE_SIZE);
    *(int*)highmem = 0x12345678;
    res = ((int (*)(void))gencode)();
    ASSERT(res == 0x12345678);

    /* Test auto-magically turning a reachable absmem into a rip-rel. */
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_ECX),
                      opnd_create_abs_addr(highmem + 0x800, OPSZ_4)));
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_EAX),
                      opnd_create_reg(DR_REG_ECX)));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, highmem, false);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < highmem + PAGE_SIZE);
    *(int*)(highmem + 0x800) = 0x12345678;
    res = ((int (*)(void))highmem)();
    ASSERT(res == 0x12345678);

    dr_raw_mem_free(highmem, PAGE_SIZE);

    /* Test targeting upper 2GB of low 4GB */
    highmem = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                               DR_MEMPROT_EXEC, (byte *)0xabcd0000);
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_ECX),
                      opnd_create_abs_addr(highmem, OPSZ_4)));
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_EAX),
                      opnd_create_reg(DR_REG_ECX)));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, gencode, false);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < gencode + PAGE_SIZE);
    *(int*)highmem = 0x12345678;
    res = ((int (*)(void))gencode)();
    ASSERT(res == 0x12345678);
    dr_raw_mem_free(highmem, PAGE_SIZE);

    /* Test targeting lower 2GB of low 4GB */
    highmem = dr_raw_mem_alloc(PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|
                               DR_MEMPROT_EXEC, (byte *)0x143d0000);
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_ECX),
                      opnd_create_abs_addr(highmem, OPSZ_4)));
    instrlist_append(ilist, INSTR_CREATE_mov_ld
                     (drcontext, opnd_create_reg(DR_REG_EAX),
                      opnd_create_reg(DR_REG_ECX)));
    instrlist_append(ilist, INSTR_CREATE_ret(drcontext));
    pc = instrlist_encode(drcontext, ilist, gencode, false);
    instrlist_clear(drcontext, ilist);
    ASSERT(pc < gencode + PAGE_SIZE);
    *(int*)highmem = 0x12345678;
    res = ((int (*)(void))gencode)();
    ASSERT(res == 0x12345678);
    dr_raw_mem_free(highmem, PAGE_SIZE);

    instrlist_clear_and_destroy(drcontext, ilist);
    dr_nonheap_free(gencode, PAGE_SIZE);

    test_instr_as_immed();

    dr_fprintf(STDERR, "success\n");
}
Esempio n. 4
0
/* frees the Instrs in the instrlist_t and the instrlist_t object itself */
void
instrlist_clear_and_destroy(dcontext_t *dcontext, instrlist_t *ilist)
{
    instrlist_clear(dcontext, ilist);
    instrlist_destroy(dcontext, ilist);
}