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"); }
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