Пример #1
0
void ControlFlowAnalysis::Analyse()
{
    dputs("Starting analysis...");
    DWORD ticks = GetTickCount();

    BasicBlockStarts();
    dprintf("Basic block starts in %ums!\n", GetTickCount() - ticks);
    ticks = GetTickCount();

    BasicBlocks();
    dprintf("Basic blocks in %ums!\n", GetTickCount() - ticks);
    ticks = GetTickCount();

    Functions();
    dprintf("Functions in %ums!\n", GetTickCount() - ticks);

    dprintf("Analysis finished!\n");
}
Пример #2
0
void CR_ModuleEx::CreateFlowGraph64(CR_Addr64 entrance) {
    auto cf = Info64()->CodeFuncFromAddr(entrance);
    assert(cf);

    CR_Addr64Set leaders;
    leaders.insert(entrance);

    // insert jumpees
    auto& jumpees = cf->Jumpees();
    leaders.insert(jumpees.begin(), jumpees.end());

    // insert exits' next
    auto& exits = cf->Exits();
    for (auto addr : exits) {
        auto op_code = Info64()->OpCodeFromAddr(addr);
        auto size = op_code->Codes().size();
        auto next_addr = static_cast<CR_Addr64>(addr + size);
        leaders.insert(next_addr);
    }

    // insert jumpers' next
    auto& jumpers = cf->Jumpers();
    for (auto addr : jumpers) {
        auto op_code = Info64()->OpCodeFromAddr(addr);
        auto size = op_code->Codes().size();
        auto next_addr = static_cast<CR_Addr64>(addr + size);
        leaders.insert(next_addr);
    }

    // sort
    std::vector<CR_Addr64> vecLeaders(leaders.begin(), leaders.end());
    std::sort(vecLeaders.begin(), vecLeaders.end());

    // store leaders
    cf->Leaders() = std::move(leaders);

    const size_t size = vecLeaders.size() - 1;
    for (size_t i = 0; i < size; ++i) {
        // for every pair of two adjacent leaders
        auto addr1 = vecLeaders[i], addr2 = vecLeaders[i + 1];
        // prepare a basic block
        CR_BasicBlock64 block;
        block.m_addr = addr1;
        CR_Addr64 next_addr = cr_invalid_addr64;
        for (auto addr = addr1; addr < addr2; ) {
            if (cf->Leaders().count(addr)) {
                // set label at each leader
                block.AddLeaderLabel(addr);
            }
            // op.code from addr
            auto op_code = Info64()->OpCodeFromAddr(addr);
            if (op_code == NULL) {
                break;
            }
            auto type = op_code->OpCodeType();
            if (type == cr_OCT_JMP) {
                // jump
                auto oper = op_code->Operand(0);
                if (oper->GetOperandType() == cr_DF_IMM) {
                    block.m_jump_to = oper->Value64();  // jump to
                }
                next_addr = cr_invalid_addr64;
            } else if (type == cr_OCT_RETURN) {
                next_addr = cr_invalid_addr64;
            } else if (type == cr_OCT_JCC || type == cr_OCT_LOOP) {
                // conditional jump or loop
                auto oper = op_code->Operand(0);
                if (oper->GetOperandType() == cr_DF_IMM) {
                    block.m_jump_to = oper->Value64();  // jump to
                }
                block.m_cond_code = op_code->CondCode();
                next_addr =
                    static_cast<CR_Addr64>(addr + op_code->Codes().size());
            } else {
                next_addr =
                    static_cast<CR_Addr64>(addr + op_code->Codes().size());
            }
            // add op.code
            block.m_stmts.emplace_back(*op_code);
            // go to next addr
            addr += static_cast<CR_Addr64>(op_code->Codes().size());
        }
        // add label at last
        block.AddLeaderLabel(addr2);
        // set next addr
        block.m_next_addr = next_addr;
        // add block
        cf->BasicBlocks().emplace_back(block);
    }
} // CR_ModuleEx::CreateFlowGraph64