예제 #1
0
bool FPFilterFunc::filter(InstructionAPI::Instruction::Ptr inst, FPDecoder* decoder)
{
    unsigned char buffer[64];
    int size = inst->size();
    memcpy(buffer, inst->ptr(), size);
    return decoder->filter(buffer, size); 
}
예제 #2
0
bool IA_x86Details::isMovAPSTable(std::vector<std::pair< Address, EdgeTypeEnum > >& outEdges)
{
    /**
    * AMD-64 gcc emits a re-accuring idiom of:
     *         jmpq   *%r8
     *         movaps %xmm7,-0xf(%rax)
     *         movaps %xmm6,-0x1f(%rax)
     *         movaps %xmm5,-0x2f(%rax)
     *         movaps %xmm4,-0x3f(%rax)
     *         movaps %xmm3,-0x4f(%rax)
     *         movaps %xmm2,-0x5f(%rax)
     *         movaps %xmm1,-0x6f(%rax)
     *         movaps %xmm0,-0x7f(%rax)
     *         <other>
     *
     * The jump register is calculated in such a way that it'll be difficult
     * for our analysis to figure it out.  Instead we'll recognize the pattern
     * of the 'movaps'.  Note that the following instruction is also a valid jump
     * target
     **/
    parsing_printf("\tChecking for movaps table at 0x%lx...\n", currentBlock->current);
    std::set<Address> found;
    const unsigned char *bufferBegin =
            (const unsigned char *)currentBlock->_isrc->getPtrToInstruction(currentBlock->current);
    if( bufferBegin == NULL ) {
        parsing_printf("%s[%d]: failed to get pointer to instruction by offset\n",
                       FILE__, __LINE__);
        return false;
    }

    unsigned int size = (currentBlock->_cr->offset() + currentBlock->_cr->length()) - currentBlock->current;
    InstructionDecoder d(bufferBegin, size, currentBlock->_isrc->getArch());
    Address cur = currentBlock->current;
    unsigned last_insn_size = 0;
    InstructionAPI::Instruction::Ptr i = d.decode();
    cur += i->size();
    InstructionAPI::Instruction::Ptr insn;
    while (NULL != (insn = d.decode())) {
        //All insns in sequence are movaps
        parsing_printf("\t\tChecking instruction %s\n", insn->format().c_str());
        if (insn->getOperation().getID() != e_movapd &&
            insn->getOperation().getID() != e_movaps)
        {
            break;
        }
        //All insns are same size
        if (last_insn_size == 0)
            last_insn_size = insn->size();
        else if (last_insn_size != insn->size())
            break;

        found.insert(cur);

        cur += insn->size();
    }
    if (found.size() == 8) {
        found.insert(cur);
        //It's a match
        for (std::set<Address>::iterator i=found.begin(); i != found.end(); i++) {
            outEdges.push_back(std::make_pair(*i, INDIRECT));
        }
        parsing_printf("\tfound\n");
        return true;
    }
    parsing_printf("\tnot found (%d insns)\n", found.size());
    return false;
}