Пример #1
0
void Shade::detour(void *address, void *target, void *&trampoline)
{
    const size_t instr_max = 17;

    auto list = instrlist_create(dr);

    byte instr_data[instr_max];

    byte *current = (byte *)address;
    byte *min_pos = (byte *)address + 5;
    size_t size = 0;

    while(current < min_pos)
    {
        read(current, instr_data, instr_max);

        auto instr = instr_create(dr);

        byte *decoded = decode_from_copy(dr, instr_data, current, instr);

        if(!decoded)
            error("Unknown instruction");

        instrlist_append(list, instr);
        instr_make_persistent(dr, instr);

        current += (size_t)(decoded - instr_data);

        size += instr_length(dr, instr);
    }

    auto instr = INSTR_CREATE_jmp(dr, opnd_create_pc(current));
    size += instr_length(dr, instr);
    instrlist_append(list, instr);

    auto local_trampoline = alloca(size);

    if(!local_trampoline)
        error("Out of memory");

    void *remote = code_section.allocate(size, 4);

    if(!instrlist_encode_to_copy(dr, list, (byte *)local_trampoline, (byte *)remote, 0, true))
        error("Unable to encode instructions");

    instrlist_clear_and_destroy(dr, list);

    write(remote, local_trampoline, size);

    trampoline = remote;

    char code[5];

    DWORD offset = (size_t)target - (size_t)address - 5;

    code[0] = 0xE9;

    *(DWORD *)(code + 1) = offset;

    access(address, 5, [&] {
        write(address, code, 5);
    });
}
Пример #2
0
byte *
instrlist_encode(dcontext_t *dcontext, instrlist_t *ilist, byte *pc,
                 bool has_instr_jmp_targets)
{
    return instrlist_encode_to_copy(dcontext, ilist, pc, pc, NULL, has_instr_jmp_targets);
}