void FunctionPass::FindFunctionWorkerPrepass(duint Start, duint End, std::vector<FunctionDef>* Blocks) { return; const duint minFunc = std::next(m_MainBlocks.begin(), Start)->VirtualStart; const duint maxFunc = std::next(m_MainBlocks.begin(), End - 1)->VirtualEnd; #ifdef _WIN64 // RUNTIME_FUNCTION exception information EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) { const duint funcAddr = m_ModuleStart + Function->BeginAddress; const duint funcEnd = m_ModuleStart + Function->EndAddress; // If within limits... if(funcAddr >= minFunc && funcAddr < maxFunc) { // Add the descriptor (virtual start/end) Blocks->push_back({ funcAddr, funcEnd, 0, 0, 0 }); } return true; }); #endif // _WIN64 // Module exports (return value ignored) apienumexports(m_ModuleStart, [&](duint Base, const char* Module, const char* Name, duint Address) { // If within limits... if(Address >= minFunc && Address < maxFunc) { // Add the descriptor (virtual start) Blocks->push_back({ Address, 0, 0, 0, 0 }); } }); }
void ControlFlowAnalysis::BasicBlocks() { for(auto i = _blockStarts.begin(); i != _blockStarts.end(); ++i) { uint start = *i; if(!IsValidAddress(start)) continue; uint nextStart = _base + _size; auto next = std::next(i); if(next != _blockStarts.end()) nextStart = *next; for(uint addr = start, prevaddr = 0; addr < _base + _size;) { prevaddr = addr; if(_cp.Disassemble(addr, TranslateAddress(addr), MAX_DISASM_BUFFER)) { if(_cp.InGroup(CS_GRP_RET) || _cp.GetId() == X86_INS_INT3) { insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block break; } else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) { uint dest1 = GetReferenceOperand(); uint dest2 = _cp.GetId() != X86_INS_JMP ? addr + _cp.Size() : 0; insertBlock(BasicBlock(start, addr, dest1, dest2)); insertParent(dest1, start); insertParent(dest2, start); break; } addr += _cp.Size(); } else addr++; if(addr == nextStart) //special case handling overlapping blocks { insertBlock(BasicBlock(start, prevaddr, 0, nextStart)); insertParent(nextStart, start); break; } } } _blockStarts.clear(); #ifdef _WIN64 int count = 0; EnumerateFunctionRuntimeEntries64([&](PRUNTIME_FUNCTION Function) { const uint funcAddr = _moduleBase + Function->BeginAddress; const uint funcEnd = _moduleBase + Function->EndAddress; // If within limits... if(funcAddr >= _base && funcAddr < _base + _size) _functionStarts.insert(funcAddr); count++; return true; }); dprintf("%u functions from the exception directory...\n", count); #endif // _WIN64 dprintf("%u basic blocks, %u function starts detected...\n", _blocks.size(), _functionStarts.size()); }