Пример #1
0
static bool parseJumpIndexTable(ExecutableContainer *c,
        InstPtr index_insn,
        const vector<VA> &jmptable_entries,
        raw_ostream &out)
{
    VA reloc_offset = index_insn->get_reloc_offset();
    if (reloc_offset == 0)  {
        out << "Unsupported jump index write; no relocation\n";
        // this jump index probably doesn't use a table
        return false;
    }

    VA  addrInInst = index_insn->get_loc() + reloc_offset;
    VA  indexTableEntry;
	VA  symbolSize;
    if(!c->relocate_addr(addrInInst, indexTableEntry, symbolSize)) {
        out << "Not a jump index table: can't relocate relocation in index insn\n";
        // can't relocate, something bad happened
        return false;
    }

    // assume we always index the start of the index table
    // ... might not be correct

    // this means we set initial entry to zero, the first element
    int initial_entry = 0;

    uint8_t b;
    int bindex = 0;
    // loop while all the bytes we read can be table indexes
    vector<uint8_t> index_entries;

    while( (indexTableEntry+bindex) < c->getExtent() ) {
        c->readByte(indexTableEntry+bindex, &b);
        if (b > jmptable_entries.size())
        {
            break;
        }
        out << "Read index table byte: " << to_string<uint32_t>((uint32_t)b, hex) << "\n";
        index_entries.push_back(b);
        bindex++;
    }

    JumpIndexTable *jit = new JumpIndexTable(index_entries, initial_entry);

    index_insn->set_jump_index_table(JumpIndexTablePtr(jit));


    return true;
}
Пример #2
0
//GENERIC_TRANSLATION_32MI(MOV32mi, 
//	doMIMov<32>(ip,   block, ADDR(0), OP(5)),
//	doMIMov<32>(ip,   block, STD_GLOBAL_OP(0), OP(5)),
//    doMIMovV<32>(ip,  block, ADDR_NOREF(0), GLOBAL_DATA_OFFSET(block, natM, ip))
//    )
//
static InstTransResult translate_MOV32mi(NativeModulePtr natM, BasicBlock *&block, InstPtr ip, MCInst &inst) {
    InstTransResult ret;
    Function *F = block->getParent();
    if( ip->has_call_tgt() ) {
        Value *callback_fn = makeCallbackForLocalFunction(
                block->getParent()->getParent(), 
                ip->get_call_tgt(0)
            );
        Value *addrInt = new PtrToIntInst(
            callback_fn, llvm::Type::getInt32Ty(block->getContext()), "", block);
        ret = doMIMovV<32>(ip, block, ADDR(0), addrInt);
    }
    else if( ip->is_data_offset() ) {
        if( ip->get_reloc_offset() < OP(5).getOffset() ) {
            doMIMov<32>(ip,   block, STD_GLOBAL_OP(0), OP(5));
        } else {
            doMIMovV<32>(ip,  block, ADDR_NOREF(0), GLOBAL_DATA_OFFSET(block, natM, ip));
        } 
        ret = ContinueBlock;
    } else { 
        ret = doMIMov<32>(ip,   block, ADDR(0), OP(5));
    }
    return ret;
}
Пример #3
0
static bool handlePossibleJumpTable(ExecutableContainer *c,
        NativeBlockPtr B,
        InstPtr jmpinst, 
        VA curAddr, 
        stack<VA> &funcs,
        stack<VA> &blockChildren,
        raw_ostream &out) {

    LASSERT(jmpinst->get_inst().getOpcode() == X86::JMP32m, 
            "handlePossibleJumpTable needs a JMP32m opcode"  );

    // is this a jump table, step 0
    // does this instruction have a relocation?
    VA reloc_offset = jmpinst->get_reloc_offset();
    if (reloc_offset == 0)  {
        out << "Not a jump table: no relocation in JMP32m\n";
        // bail, this is not a jump table
        return false;
    }

    // this relocation has to point to a relocation

    VA addrInInst = curAddr + reloc_offset;
    VA jmpTableEntry, someFunction;
    if(!c->relocate_addr(addrInInst, jmpTableEntry)) {
        out << "Not a jump table: can't relocate relocation in JMP32m\n";
        // can't relocate, something bad happened
       return false; 
    }

    if(!c->relocate_addr(jmpTableEntry, someFunction)) {
        // could not relocate the default jump table entry.
        // not good
        out << "Not a jump table: can't relocate first jump table entry\n";
        return false;
    }

    bool is_reloc_code = isAddrOfType(c, someFunction, ExecutableContainer::CodeSection);
    if(!is_reloc_code) {
        // jump table entry not point to code
        out << "Not a jump table: first entry doesn't point to code\n";
        return false;
    }
     

    // read jump table entries and add them as new function
    // entry points
    vector<VA> jmptable_entries; 
    int new_funs;
    int original_zero;

    // this reads negative jump table indexes, but vectors are not negative
    // indexed. the negative most, which should be the new index 0, is now
    // index N. Reverse the vector so it will be index 0, and save the current
    // size as the original zeroth element
    new_funs = addJmpTableEntries(c, jmptable_entries, jmpTableEntry,  -4, out);
    std::reverse(jmptable_entries.begin(), jmptable_entries.end());
    out << "Added: " << to_string<int>(new_funs, dec) << " functions to jmptable\n";

    original_zero = new_funs;

    // add original entry at the zero position
    jmptable_entries.push_back(someFunction);
    out << "Added JMPTABLE entry [" << to_string<uint32_t>(jmpTableEntry, hex) 
        << "] => " << to_string<uint32_t>(someFunction, hex)  << "\n";

    // add the positive table entries
    new_funs = addJmpTableEntries(c, jmptable_entries, jmpTableEntry,  4, out);
    out << "Added: " << to_string<int>(new_funs, dec) << " functions to jmptable\n";

    // associate instruction with jump table
    JumpTable *jt = new JumpTable(jmptable_entries, original_zero);
    jmpinst->set_jump_table(JumpTablePtr(jt));

    stack<VA> *toPush = NULL;

    // if this jump table is in the format
    // jmp [reg*4+imm32], then it is conformant
    // and we can turn it into an llvm switch();
    bool is_conformant = isConformantJumpInst(jmpinst);
    if(is_conformant) {
        toPush = &blockChildren;
        out << "GOT A CONFORMANT JUMP INST\n";
    } else {
        toPush = &funcs;
    }

    // add these jump table entries as new entry points
    for(std::vector<VA>::const_iterator itr = jmptable_entries.begin();
            itr != jmptable_entries.end();
            itr++) 
    {
        out << "Adding block via jmptable: " << to_string<VA>(*itr, hex) << "\n";
        toPush->push(*itr);
        if(is_conformant) {
            B->add_follow(*itr);
        }
    }

    processJumpIndexTable(c, B, jmpinst, jmptable_entries, out);

    return true;

}