From 379a273ffec1fefe8b6f9af3a959ae85eba17857 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Sat, 3 Jan 2015 11:43:34 +0100 Subject: [PATCH 01/16] Add some simple samples for screenshots and similar stuff --- samples/crypt/main.c | 21 +++++++++++++++++++++ samples/simple/main.c | 10 ++++++++++ 2 files changed, 31 insertions(+) create mode 100644 samples/crypt/main.c create mode 100644 samples/simple/main.c diff --git a/samples/crypt/main.c b/samples/crypt/main.c new file mode 100644 index 0000000..773f0ea --- /dev/null +++ b/samples/crypt/main.c @@ -0,0 +1,21 @@ +#define _GNU_SOURCE +#include +#include +#include + +int check(char * str) { + /* Ich bin der größte! */ + static const char * correct = "TOgP5hrln1SAE"; + printf("%s\n", crypt(str, "TOPSECRET")); + return ! strcmp(correct, crypt(str, "TOPSECRET")); +} + +int main() { + char password[255]; + printf("Password: "); + scanf("%s", password); + if (check(password)) + printf("Success!\n"); + else + printf("Failure!\n"); +} diff --git a/samples/simple/main.c b/samples/simple/main.c new file mode 100644 index 0000000..0664bf0 --- /dev/null +++ b/samples/simple/main.c @@ -0,0 +1,10 @@ +#include +#include + +int main(int argc, char ** argv) { + int count = atoi(argv[1]); + + while (count --> 0) { + printf(argv[2]); + } +} -- 2.39.2 From 9254f26b4470c13bed9f6c18c86bde98d809b64c Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Sat, 3 Jan 2015 18:51:56 +0100 Subject: [PATCH 02/16] Consistently use include-guards --- src/gui/Mainwindow.hxx | 5 +++++ src/gui/qt.hxx | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/gui/Mainwindow.hxx b/src/gui/Mainwindow.hxx index 9ce1b6b..7f6d63e 100644 --- a/src/gui/Mainwindow.hxx +++ b/src/gui/Mainwindow.hxx @@ -1,3 +1,6 @@ +#ifndef INCLUDE__Mainwindow_hxx_ +#define INCLUDE__Mainwindow_hxx_ + #include #include #include @@ -38,3 +41,5 @@ private Q_SLOTS: void quit(); void open(); }; + +#endif /* INCLUDE__Mainwindow_hxx_ */ diff --git a/src/gui/qt.hxx b/src/gui/qt.hxx index 5ef2f3d..7397b23 100644 --- a/src/gui/qt.hxx +++ b/src/gui/qt.hxx @@ -1,3 +1,6 @@ +#ifndef INCLUDE__qt_hxx_ +#define INCLUDE__qt_hxx_ + #include #include #include @@ -19,3 +22,5 @@ #include #include #include + +#endif /* INCLUDE__qt_hxx_ */ -- 2.39.2 From c100e37a2dfbe6dd221e867559b473a4a5097570 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Mon, 5 Jan 2015 17:19:13 +0100 Subject: [PATCH 03/16] Cleanup sourcetree --- src/Binary.cxx | 473 ------------------- src/Binary.hxx | 50 -- src/{ => disassembler/llvm}/include_llvm.hxx | 0 src/main.cxx | 2 +- 4 files changed, 1 insertion(+), 524 deletions(-) delete mode 100644 src/Binary.cxx delete mode 100644 src/Binary.hxx rename src/{ => disassembler/llvm}/include_llvm.hxx (100%) diff --git a/src/Binary.cxx b/src/Binary.cxx deleted file mode 100644 index f877685..0000000 --- a/src/Binary.cxx +++ /dev/null @@ -1,473 +0,0 @@ -#include "Binary.hxx" - -#include "disassembler/Disassembler.hxx" - -#include -#include -#include - -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; -using namespace llvm::object; - -namespace { - bool error(error_code ec) { - if (!ec) return false; - - outs() << "error reading file: " << ec.message() << ".\n"; - outs().flush(); - return true; - } - - bool RelocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) return false; - if (error(b.getOffset(b_addr))) return false; - return a_addr < b_addr; - } - - void DumpBytes(StringRef bytes) { - static const char hex_rep[] = "0123456789abcdef"; - // FIXME: The real way to do this is to figure out the longest instruction - // and align to that size before printing. I'll fix this when I get - // around to outputting relocations. - // 15 is the longest x86 instruction - // 3 is for the hex rep of a byte + a space. - // 1 is for the null terminator. - enum { OutputSize = (15 * 3) + 1 }; - char output[OutputSize]; - - assert(bytes.size() <= 15 - && "DumpBytes only supports instructions of up to 15 bytes"); - memset(output, ' ', sizeof(output)); - unsigned index = 0; - for (StringRef::iterator i = bytes.begin(), - e = bytes.end(); i != e; ++i) { - output[index] = hex_rep[(*i & 0xF0) >> 4]; - output[index + 1] = hex_rep[*i & 0xF]; - index += 3; - } - - output[sizeof(output) - 1] = 0; - outs() << output; - } - - std::map readSections(const ObjectFile& o) { - error_code ec; - std::map result; - section_iterator i(o.section_begin()), e(o.section_end()); - for (; i != e; ++i) { - StringRef name; - if (error(i->getName(name))) break; - - result.insert(make_pair(name.str(), *i)); - } - return result; - } - - std::map readSymbols(const ObjectFile& o) { - error_code ec; - std::map result; - symbol_iterator si(o.symbol_begin()), se(o.symbol_end()); - for (; si != se; ++si) { - StringRef name; - if (error(si->getName(name))) break; - - result.insert(make_pair(name.str(), *si)); - } - return result; - } -} - -::Binary::Binary(const std::string& filename) - : triple(llvm::Twine("unkown-unknown-unknown")) -{ - ::Disassembler d(filename); - std::string error; - - binary = createBinary(filename).get(); - if (Archive *a = dyn_cast(binary)) { - std::cerr << "Got an archive!" << std::endl; - return; - } - - o = dyn_cast(binary); - - triple.setArch(Triple::ArchType(o->getArch())); - std::string tripleName(triple.getTriple()); - - outs() << tripleName << "\n"; - - target = TargetRegistry::lookupTarget("", triple, error); - if (!target) { - std::cerr << error; - return; - } - - outs() << target->getName() << "\n"; - - MRI.reset(target->createMCRegInfo(tripleName)); - if (!MRI) { - std::cerr << "error: no register info for target " << tripleName << "\n"; - return; - } - - // Set up disassembler. - AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName)); - if (!AsmInfo) { - std::cerr << "error: no assembly info for target " << tripleName << "\n"; - return; - } - - STI.reset(target->createMCSubtargetInfo(tripleName, "", "")); - if (!STI) { - errs() << "error: no subtarget info for target " << tripleName << "\n"; - return; - } - - MII.reset(target->createMCInstrInfo()); - if (!MII) { - std::cerr << "error: no instruction info for target " << tripleName << "\n"; - return; - } - - DisAsm.reset(target->createMCDisassembler(*STI)); - if (!DisAsm) { - std::cerr << "error: no disassembler for target " << tripleName << "\n"; - return; - } - - MOFI.reset(new MCObjectFileInfo); - Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get())); - RelInfo.reset( - target->createMCRelocationInfo(tripleName, *Ctx.get())); - if (RelInfo) { - Symzer.reset( - MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(), RelInfo, o)); - if (Symzer) - DisAsm->setSymbolizer(Symzer); - } - - MIA.reset(target->createMCInstrAnalysis(MII.get())); - - int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); - if (!IP) { - std::cerr << "error: no instruction printer for target " << tripleName - << '\n'; - return; - } - - OwningPtr OD( - new MCObjectDisassembler(*o, *DisAsm, *MIA)); - Mod.reset(OD->buildModule(/* withCFG */ false)); - - symbols = readSymbols(*o); - sections = readSections(*o); - - // for_each(sections.begin(), sections.end(), [](const std::pair& i){ - // std::cout << "Section: " << i.first << std::endl; - // }); -} - - - -std::vector -::Binary::getSymbols() { - error_code ec; - SectionRef r = sections[".text"]; - std::vector result; - for_each(symbols.begin(), symbols.end(), [&](const std::pair& i) { - bool contains; - SymbolRef::Type t; - if (!error(r.containsSymbol(i.second, contains)) && contains) { - i.second.getType(t); - if (SymbolRef::ST_Function == t) - result.push_back(i.first); - } - }); - return result; -} - -void ::Binary::for_each_instruction(const std::string& function, - std::function callback) { - StringRef bytes; - uint64_t base_address, address, ssize, size(0), index, end; - StringRefMemoryObject memoryObject(""); - - if (symbols.end() != symbols.find(function)) { - SymbolRef ref; - section_iterator sec(o->section_begin()); - - ref = symbols.at(function); - if (error(ref.getSection(sec))) return; - if (error(ref.getAddress(address))) return; - if (address == UnknownAddressOrSize) return; - if (error(ref.getSize(ssize))) return; - if (error(sec->getAddress(base_address))) return; - if (error(sec->getContents(bytes))) return; - memoryObject = bytes; - - } - else if (sections.end() != sections.find(function)) { - SectionRef sref = sections.at(function); - if (error(sref.getAddress(address))) return; - if (address == UnknownAddressOrSize) return; - if (error(sref.getSize(ssize))) return; - if (error(sref.getContents(bytes))) return; - base_address = address; - memoryObject = bytes; - } - - - // outs() << "Start for_each_instruction " << function << "\n"; - - - for (end = address + ssize - base_address, index = address - base_address; index < end; index += size) { - MCInst Inst; - - if (DisAsm->getInstruction(Inst, size, memoryObject, index, - nulls(), nulls())) { - std::string buf; - llvm::raw_string_ostream s(buf); - IP->printInst(&Inst, s, ""); - - if (index + size < bytes.str().length()) - callback(base_address + index, bytes.str().substr(index, size), s.str()); - - } else { - errs() << "warning: invalid instruction encoding\n"; - if (size == 0) - size = 1; // skip illegible bytes - } - } - // outs() << "End for_each_instruction\n"; - -} - -void ::Binary::disassemble() { - for (MCModule::const_atom_iterator AI = Mod->atom_begin(), - AE = Mod->atom_end(); - AI != AE; ++AI) { - - if ((*AI)->getKind() != llvm::MCAtom::TextAtom) - continue; - - outs() << "\n\nAtom " << (*AI)->getName() << ": \n"; - if (const MCTextAtom *TA = dyn_cast(*AI)) { - for (MCTextAtom::const_iterator II = TA->begin(), IE = TA->end(); - II != IE; - ++II) { -// II->Inst.dump(); - IP->printInst(&II->Inst, outs(), ""); - outs() << "\n"; - } - } - } - - outs() << "binary " << triple.getArchName() << "\n"; -} - -void ::Binary::disassemble_functions() { - error_code ec; - for (section_iterator i = o->section_begin(), - e = o->section_end(); - i != e; ++i) { - if (error(ec)) break; - bool text; - if (error(i->isText(text))) break; - if (!text) continue; - - uint64_t SectionAddr; - if (error(i->getAddress(SectionAddr))) break; - - // Make a list of all the symbols in this section. - std::vector > Symbols; - for (symbol_iterator si = o->symbol_begin(), - se = o->symbol_end(); - si != se; ++si) { - bool contains; - if (!error(i->containsSymbol(*si, contains)) && contains) { - uint64_t Address; - if (error(si->getAddress(Address))) break; - if (Address == UnknownAddressOrSize) continue; - Address -= SectionAddr; - - StringRef Name; - if (error(si->getName(Name))) break; - - outs() << "\nXXX " << Name << "\n"; - - Symbols.push_back(std::make_pair(Address, Name)); - } - } - - // Sort the symbols by address, just in case they didn't come in that way. - array_pod_sort(Symbols.begin(), Symbols.end()); - - // Make a list of all the relocations for this section. - std::vector Rels; - // if (InlineRelocs) { - // for (relocation_iterator ri = i->begin_relocations(), - // re = i->end_relocations(); - // ri != re; ri.increment(ec)) { - // if (error(ec)) break; - // Rels.push_back(*ri); - // } - // } - - // Sort relocations by address. - std::sort(Rels.begin(), Rels.end(), RelocAddressLess); - - StringRef SegmentName = ""; - // if (const MachOObjectFile *MachO = - // dyn_cast(o)) { - // DataRefImpl DR = i->getRawDataRefImpl(); - // SegmentName = MachO->getSectionFinalSegmentName(DR); - // } - StringRef name; - if (error(i->getName(name))) break; - outs() << "Disassembly of section "; - if (!SegmentName.empty()) - outs() << SegmentName << ","; - outs() << name << ':'; - - // If the section has no symbols just insert a dummy one and disassemble - // the whole section. - if (Symbols.empty()) - Symbols.push_back(std::make_pair(0, name)); - - - StringRef Bytes; - if (error(i->getContents(Bytes))) break; - StringRefMemoryObject memoryObject(Bytes); - uint64_t Size; - uint64_t Index; - uint64_t SectSize; - if (error(i->getSize(SectSize))) break; - - std::vector::const_iterator rel_cur = Rels.begin(); - std::vector::const_iterator rel_end = Rels.end(); - // Disassemble symbol by symbol. - for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { - uint64_t Start = Symbols[si].first; - uint64_t End; - // The end is either the size of the section or the beginning of the next - // symbol. - if (si == se - 1) - End = SectSize; - // Make sure this symbol takes up space. - else if (Symbols[si + 1].first != Start) - End = Symbols[si + 1].first - 1; - else - // This symbol has the same address as the next symbol. Skip it. - continue; - - outs() << '\n' << Symbols[si].second << ":\n"; - -#ifndef NDEBUG - raw_ostream &DebugOut = nulls(); //DebugFlag ? dbgs() : nulls(); -#else - raw_ostream &DebugOut = nulls(); -#endif - - for (Index = Start; Index < End; Index += Size) { - MCInst Inst; - - if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, - DebugOut, nulls())) { - outs() << format("%8" PRIx64 ":", SectionAddr + Index); - outs() << "\t"; - DumpBytes(StringRef(Bytes.data() + Index, Size)); - - IP->printInst(&Inst, outs(), ""); - outs() << "\n"; - } else { - errs() << "warning: invalid instruction encoding\n"; - if (Size == 0) - Size = 1; // skip illegible bytes - } - - // Print relocation for instruction. - while (rel_cur != rel_end) { - bool hidden = false; - uint64_t addr; - SmallString<16> name; - SmallString<32> val; - - // If this relocation is hidden, skip it. - if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; - if (hidden) goto skip_print_rel; - - if (error(rel_cur->getOffset(addr))) goto skip_print_rel; - // Stop when rel_cur's address is past the current instruction. - if (addr >= Index + Size) break; - if (error(rel_cur->getTypeName(name))) goto skip_print_rel; - if (error(rel_cur->getValueString(val))) goto skip_print_rel; - - outs() << format("\t\t\t%8" PRIx64 ": ", SectionAddr + addr) << name - << "\t" << val << "\n"; - - skip_print_rel: - ++rel_cur; - } - } - } - } -} - -void ::Binary::disassemble_cfg() { - for (MCModule::const_func_iterator FI = Mod->func_begin(), - FE = Mod->func_end(); - FI != FE; ++FI) { - static int filenum = 0; - std::string FileName = std::string("dot/") + (Twine((*FI)->getName()) + "_" + utostr(filenum) + ".dot").str(); - - std::cerr << FileName << std::endl; - - // Start a new dot file. - std::string Error; - raw_fd_ostream Out(FileName.c_str(), Error); - if (!Error.empty()) { - errs() << "llvm-objdump: warning: " << Error << '\n'; - return; - } - - Out << "digraph \"" << (*FI)->getName() << "\" {\n"; - Out << "graph [ rankdir = \"LR\" ];\n"; - for (MCFunction::const_iterator i = (*FI)->begin(), e = (*FI)->end(); i != e; ++i) { - // Only print blocks that have predecessors. - bool hasPreds = (*i)->pred_begin() != (*i)->pred_end(); - - if (!hasPreds && i != (*FI)->begin()) - continue; - - Out << '"' << (*i)->getInsts()->getBeginAddr() << "\" [ label=\""; - // Print instructions. - for (unsigned ii = 0, ie = (*i)->getInsts()->size(); ii != ie; - ++ii) { - if (ii != 0) // Not the first line, start a new row. - Out << '|'; - if (ii + 1 == ie) // Last line, add an end id. - Out << ""; - - // Escape special chars and print the instruction in mnemonic form. - std::string Str; - raw_string_ostream OS(Str); - IP->printInst(&(*i)->getInsts()->at(ii).Inst, OS, ""); - Out << DOT::EscapeString(OS.str()); - } - Out << "\" shape=\"record\" ];\n"; - - // Add edges. - for (MCBasicBlock::succ_const_iterator si = (*i)->succ_begin(), - se = (*i)->succ_end(); si != se; ++si) - Out << (*i)->getInsts()->getBeginAddr() << ":o -> " - << (*si)->getInsts()->getBeginAddr() << ":a\n"; - } - Out << "}\n"; - - ++filenum; - } -} diff --git a/src/Binary.hxx b/src/Binary.hxx deleted file mode 100644 index 1a86578..0000000 --- a/src/Binary.hxx +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef INCLUDE__Binary_hxx -#define INCLUDE__Binary_hxx - -#include "include_llvm.hxx" -#include "Section.hxx" - -#include -#include -#include - -using llvm::OwningPtr; - -class Binary { -public: - Binary(const std::string& filename); - - void disassemble(); - - void disassemble_functions(); - - void disassemble_cfg(); - - std::vector getSymbols(); - - std::vector getFunctions(); - void for_each_instruction(const std::string& function, std::function callback); - -private: - llvm::Triple triple; - const llvm::Target * target; - llvm::object::ObjectFile * o; - - llvm::object::Binary* binary; - OwningPtr MRI; - OwningPtr AsmInfo; - OwningPtr Mod; - OwningPtr IP; - OwningPtr DisAsm; - OwningPtr MOFI; - OwningPtr Ctx; - OwningPtr MIA; - OwningPtr STI; - OwningPtr MII; - OwningPtr RelInfo; - OwningPtr Symzer; - - std::map sections; - std::map symbols; -}; -#endif diff --git a/src/include_llvm.hxx b/src/disassembler/llvm/include_llvm.hxx similarity index 100% rename from src/include_llvm.hxx rename to src/disassembler/llvm/include_llvm.hxx diff --git a/src/main.cxx b/src/main.cxx index ebb85e8..c33d6c4 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -1,4 +1,4 @@ -#include "include_llvm.hxx" +#include "disassembler/llvm/include_llvm.hxx" #include #include -- 2.39.2 From 231dae075375e7d57982f5107b86294fbe726b33 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Tue, 6 Jan 2015 22:23:25 +0100 Subject: [PATCH 04/16] Add in an Information Manager Now individual functions are added to the GUI via signals. This is the way it was alwasys supposed to work. Now Information flow is cleaner, we can add support to save things and we can properly tag things as functions and rerun the disassembler. Also includes some whitespace cleanup for technical reasons --- CMakeLists.txt | 5 +- src/core/InformationManager.cxx | 9 ++ src/core/InformationManager.hxx | 43 ++++++ src/disassembler/Disassembler.hxx | 11 +- src/disassembler/llvm/LLVMDisassembler.cxx | 9 +- src/disassembler/llvm/LLVMDisassembler.hxx | 71 ++++----- src/gui/Mainwindow.cxx | 163 +++++++++++---------- src/gui/Mainwindow.hxx | 37 ++--- src/main.cxx | 8 +- 9 files changed, 215 insertions(+), 141 deletions(-) create mode 100644 src/core/InformationManager.cxx create mode 100644 src/core/InformationManager.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a6433f..ab55827 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,8 @@ execute_process(COMMAND ${LLVM_CONFIG} --ldflags OUTPUT_VARIABLE LLVM_LDFLAG execute_process(COMMAND ${LLVM_CONFIG} --libs OUTPUT_VARIABLE LLVM_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${LLVM_CONFIG} --system-libs OUTPUT_VARIABLE LLVM_SYSTEM_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE) -string(REPLACE -O2 '' LLVM_CFLAGS ${LLVM_CFLAGS}) +string(REPLACE -O2 "" LLVM_CFLAGS ${LLVM_CFLAGS}) +string(REPLACE -fno-exceptions "" LLVM_CFLAGS ${LLVM_CFLAGS}) separate_arguments(LLVM_CFLAGS) add_definitions(${LLVM_CFLAGS}) @@ -41,6 +42,7 @@ set(CMAKE_CXX_COMPILER "clang++") SET(frida_SOURCES src/main.cxx + src/core/InformationManager.cxx src/gui/Mainwindow.cxx src/gui/widgets/BasicBlockWidget.cxx src/gui/widgets/CFGScene.cxx @@ -50,6 +52,7 @@ SET(frida_SOURCES ) SET(frida_HEADERS src/include_llvm.hxx + src/core/InformationManager.hxx src/gui/qt.hxx src/gui/Mainwindow.hxx src/gui/widgets/BasicBlockWidget.hxx diff --git a/src/core/InformationManager.cxx b/src/core/InformationManager.cxx new file mode 100644 index 0000000..6e91572 --- /dev/null +++ b/src/core/InformationManager.cxx @@ -0,0 +1,9 @@ +#include "InformationManager.hxx" +#include "disassembler/llvm/LLVMDisassembler.hxx" + +#include + +void InformationManager::reset(const std::string& filename) { + disassembler.reset(new LLVMDisassembler(filename, this)); + disassembler.get()->start(); +} diff --git a/src/core/InformationManager.hxx b/src/core/InformationManager.hxx new file mode 100644 index 0000000..5d2ef64 --- /dev/null +++ b/src/core/InformationManager.hxx @@ -0,0 +1,43 @@ +#ifndef INCLUDE__InformationManager_hxx +#define INCLUDE__InformationManager_hxx + +#include +#include + +class Disassembler; +class Function; + +class InformationManager { +public: + boost::signals2::connection + connect_new_function_signal(std::function f) { + return new_function_signal.connect(f); + } + + void signal_new_function(Function* f) { + new_function_signal(f); + } + + boost::signals2::connection + connect_reset_signal(std::function f) { + return reset_signal.connect(f); + } + + // boost::signals2::connection + // connect_information_added_signal(uint64_t begin, uint64_t end, + // std::function) { + + // } + + Disassembler* getDisassembler() { + return disassembler.get(); + } + + void reset(const std::string& filename); +private: + boost::signals2::signal reset_signal; + boost::signals2::signal new_function_signal; + std::unique_ptr disassembler; +}; + +#endif /* INCLUDE__InformationManager_hxx */ diff --git a/src/disassembler/Disassembler.hxx b/src/disassembler/Disassembler.hxx index a618ae5..c88bfd5 100644 --- a/src/disassembler/Disassembler.hxx +++ b/src/disassembler/Disassembler.hxx @@ -1,4 +1,4 @@ -#ifndef INCLUDE__Disassembler_hxx + #ifndef INCLUDE__Disassembler_hxx #define INCLUDE__Disassembler_hxx #include @@ -6,15 +6,16 @@ #include "disassembler/BasicBlock.hxx" #include "disassembler/Function.hxx" - +#include "core/InformationManager.hxx" class Disassembler { public: - Disassembler(const std::string& filename) {} + Disassembler(const std::string& filename, InformationManager* manager) {} virtual ~Disassembler() {} - void getSymbols(); - uint64_t entryAddress(); + virtual void start() = 0; + virtual void getSymbols() = 0; + virtual uint64_t entryAddress() = 0; virtual BasicBlock * getBasicBlock(uint64_t address) = 0; virtual void forEachFunction(std::function callback) = 0; diff --git a/src/disassembler/llvm/LLVMDisassembler.cxx b/src/disassembler/llvm/LLVMDisassembler.cxx index 6b3402e..7f87b80 100644 --- a/src/disassembler/llvm/LLVMDisassembler.cxx +++ b/src/disassembler/llvm/LLVMDisassembler.cxx @@ -14,10 +14,12 @@ using std::error_code; * ist sondern z.B. einfach nur Instruktionen oder ein Bootsektor oder * foo */ -LLVMDisassembler::LLVMDisassembler(const std::string& filename) - : Disassembler(filename) +LLVMDisassembler::LLVMDisassembler(const std::string& filename, + InformationManager* manager) + : Disassembler(filename, manager) , logger(log4cxx::Logger::getLogger("LLVMDisassembler")) , triple("unknown-unknown-unknown") + , manager(manager) { LOG4CXX_DEBUG(logger, "Handling file" << filename); auto result = createBinary(filename); @@ -111,7 +113,9 @@ LLVMDisassembler::LLVMDisassembler(const std::string& filename) std::unique_ptr OD( new MCObjectDisassembler(*o, *DisAsm, *MIA)); Mod.reset(OD->buildModule(false)); +} +void LLVMDisassembler::start() { readSymbols(); readSections(); disassemble(); @@ -231,6 +235,7 @@ void LLVMDisassembler::disassembleFunction(LLVMFunction* function) { } } LOG4CXX_DEBUG(logger, "Finished function " << function->getName()); + manager->signal_new_function(function); } void LLVMDisassembler::disassemble() { diff --git a/src/disassembler/llvm/LLVMDisassembler.hxx b/src/disassembler/llvm/LLVMDisassembler.hxx index f2baecb..d26bb12 100644 --- a/src/disassembler/llvm/LLVMDisassembler.hxx +++ b/src/disassembler/llvm/LLVMDisassembler.hxx @@ -15,13 +15,14 @@ class LLVMDisassembler - : public Disassembler { + : public Disassembler { public: - LLVMDisassembler(const std::string& filename); - virtual ~LLVMDisassembler(); + LLVMDisassembler(const std::string& filename, InformationManager* manager); + virtual ~LLVMDisassembler(); - void getSymbols(); - uint64_t entryAddress(); + void start(); + void getSymbols() {} + uint64_t entryAddress() {} void forEachFunction(std::function callback); void printEachInstruction(uint64_t start, uint64_t end, @@ -31,47 +32,47 @@ public: return blocks[address]; } - Function * disassembleFunctionAt(uint64_t address, const std::string& name = ""); + Function * disassembleFunctionAt(uint64_t address, const std::string& name = ""); protected: - bool isFunctionCall(uint64_t address) {return false;} - bool isJump(uint64_t address) {return false;} + bool isFunctionCall(uint64_t address) {return false;} + bool isJump(uint64_t address) {return false;} private: - // http://llvm.org/docs/doxygen/html/MCObjectDisassembler_8cpp_source.html +197 - void disassembleFunction(LLVMFunction* function); - void splitBlocks(); - void disassemble(); + // http://llvm.org/docs/doxygen/html/MCObjectDisassembler_8cpp_source.html +197 + void disassembleFunction(LLVMFunction* function); + void splitBlocks(); + void disassemble(); void readSymbols(); void readSections(); - log4cxx::LoggerPtr logger; + log4cxx::LoggerPtr logger; std::map blocks; std::map functions; - llvm::Triple triple; - std::shared_ptr binary; - - - const llvm::Target * target; - llvm::object::ObjectFile * o; - - std::unique_ptr MRI; - std::unique_ptr AsmInfo; - std::unique_ptr Mod; - std::unique_ptr IP; - std::unique_ptr DisAsm; - std::unique_ptr MOFI; - std::unique_ptr Ctx; - std::unique_ptr MIA; - std::unique_ptr STI; - std::unique_ptr MII; - std::unique_ptr RelInfo; - std::unique_ptr Symzer; - - std::map sections; - std::map symbols; + llvm::Triple triple; + std::shared_ptr binary; + + const llvm::Target * target; + llvm::object::ObjectFile * o; + + std::unique_ptr MRI; + std::unique_ptr AsmInfo; + std::unique_ptr Mod; + std::unique_ptr IP; + std::unique_ptr DisAsm; + std::unique_ptr MOFI; + std::unique_ptr Ctx; + std::unique_ptr MIA; + std::unique_ptr STI; + std::unique_ptr MII; + std::unique_ptr RelInfo; + std::unique_ptr Symzer; + + std::map sections; + std::map symbols; + InformationManager * manager; }; #endif diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index f98cd60..7b207fa 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -1,6 +1,7 @@ #include "Mainwindow.hxx" #include "qt.hxx" #include "disassembler/llvm/LLVMDisassembler.hxx" + #include "widgets/CFGScene.hxx" #include @@ -9,75 +10,105 @@ #include -Mainwindow::Mainwindow(const std::string& filename) -{ - openAction = new QAction(tr("&Open"), this); - // saveAction = new QAction(tr("&Save"), this); - exitAction = new QAction(tr("E&xit"), this); - - connect(openAction, SIGNAL(triggered()), this, SLOT(open())); - // connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(openAction); - // fileMenu->addAction(saveAction); - fileMenu->addSeparator(); - fileMenu->addAction(exitAction); - - scripting = new ScriptingDock(tr("Scripting"), this); - scripting->setAllowedAreas(Qt::BottomDockWidgetArea); - addDockWidget(Qt::BottomDockWidgetArea, scripting); - - listWidget = new QListWidget(); - stackedWidget = new QStackedWidget(); - dockWidget = new QDockWidget(tr("Functions"), this); - dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | - Qt::RightDockWidgetArea); - dockWidget->setWidget(listWidget); - addDockWidget(Qt::LeftDockWidgetArea, dockWidget); - setCentralWidget(stackedWidget); - - connect(listWidget, SIGNAL(currentRowChanged(int)), - stackedWidget, SLOT(setCurrentIndex(int))); - - setWindowTitle(tr("FRIDA")); - - openBinary(filename); +namespace { + BasicBlockWidget * + local__add_basic_block(BasicBlock * block, Disassembler * dis, + std::map& known_blocks, + CFGScene * scene, uint64_t starty, uint64_t startx); +} + +Mainwindow::Mainwindow(InformationManager* mgr) + : manager(mgr) { + openAction = new QAction(tr("&Open"), this); + // saveAction = new QAction(tr("&Save"), this); + exitAction = new QAction(tr("E&xit"), this); + + connect(openAction, SIGNAL(triggered()), this, SLOT(open())); + // connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); + connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(openAction); + // fileMenu->addAction(saveAction); + fileMenu->addSeparator(); + fileMenu->addAction(exitAction); + + scripting = new ScriptingDock(tr("Scripting"), this); + scripting->setAllowedAreas(Qt::BottomDockWidgetArea); + addDockWidget(Qt::BottomDockWidgetArea, scripting); + + listWidget = new QListWidget(); + stackedWidget = new QStackedWidget(); + dockWidget = new QDockWidget(tr("Functions"), this); + dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | + Qt::RightDockWidgetArea); + dockWidget->setWidget(listWidget); + addDockWidget(Qt::LeftDockWidgetArea, dockWidget); + setCentralWidget(stackedWidget); + + connect(listWidget, SIGNAL(currentRowChanged(int)), + stackedWidget, SLOT(setCurrentIndex(int))); + + setWindowTitle(tr("FRIDA")); + + mgr->connect_new_function_signal([&] (Function* fun) {addFunction(fun);}); } void Mainwindow::quit() { - QMessageBox messageBox; - messageBox.setWindowTitle(tr("Notepad")); - messageBox.setText(tr("Do you really want to quit?")); - messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - messageBox.setDefaultButton(QMessageBox::No); - if (messageBox.exec() == QMessageBox::Yes) - qApp->quit(); + QMessageBox messageBox; + messageBox.setWindowTitle(tr("Notepad")); + messageBox.setText(tr("Do you really want to quit?")); + messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + messageBox.setDefaultButton(QMessageBox::No); + if (messageBox.exec() == QMessageBox::Yes) + qApp->quit(); } void Mainwindow::open() { - QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", - tr("Binaries (*)")); + QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", + tr("Binaries (*)")); - openBinary(fileName.toStdString()); + manager->reset(fileName.toStdString()); } -void Mainwindow::openBinary(const std::string& filename) { - if (filename != "") { - disassembler.reset(new LLVMDisassembler(filename)); - disassembler->forEachFunction([&](uint64_t address, Function* fun) { - populateSymbolInformation(fun); - }); - } +void Mainwindow::addFunction(Function* fun) { + if (functions.find(fun) != functions.end()) + return; + + functions.insert(fun); + + QTabWidget * w = new QTabWidget(); + + // CFG + CFGScene * scene = new CFGScene; + + Disassembler * dis = manager->getDisassembler(); + std::cerr << dis << std::endl; + + BasicBlock * block = dis->getBasicBlock(fun->getStartAddress()); + + local__add_basic_block(block, manager->getDisassembler(), blocks, scene, block->getStartAddress(), 100); + + QGraphicsView * view = new QGraphicsView(scene); + w->addTab(view, "CFG"); + + // Listing + QTableWidget * t = new QTableWidget(); + t->setColumnCount(3); + t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + w->addTab(t, "Listing"); + + listWidget->addItem(fun->getName().c_str()); + stackedWidget->addWidget(w); } namespace { BasicBlockWidget * local__add_basic_block(BasicBlock * block, Disassembler * dis, - std::map& known_blocks, - CFGScene * scene, uint64_t starty, uint64_t startx) { + std::map& known_blocks, + CFGScene * scene, uint64_t starty, uint64_t startx) { decltype(known_blocks.begin()) old; if ((old = known_blocks.find(block->getStartAddress())) != known_blocks.end()) @@ -124,27 +155,3 @@ namespace { return widget; } } - -void Mainwindow::populateSymbolInformation(Function* fun) { - QTabWidget * w = new QTabWidget(); - - // CFG - CFGScene * scene = new CFGScene; - - BasicBlock * block = disassembler->getBasicBlock(fun->getStartAddress()); - - local__add_basic_block(block, disassembler.get(), blocks, scene, block->getStartAddress(), 100); - - QGraphicsView * view = new QGraphicsView(scene); - w->addTab(view, "CFG"); - - // Listing - QTableWidget * t = new QTableWidget(); - t->setColumnCount(3); - t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - - w->addTab(t, "Listing"); - - listWidget->addItem(fun->getName().c_str()); - stackedWidget->addWidget(w); -} diff --git a/src/gui/Mainwindow.hxx b/src/gui/Mainwindow.hxx index 7f6d63e..40fa81d 100644 --- a/src/gui/Mainwindow.hxx +++ b/src/gui/Mainwindow.hxx @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -12,34 +13,34 @@ #include "disassembler/Disassembler.hxx" #include "widgets/BasicBlockWidget.hxx" #include "widgets/ScriptingDock.hxx" +#include "core/InformationManager.hxx" class Mainwindow : public QMainWindow { - Q_OBJECT + Q_OBJECT public: - Mainwindow(const std::string& filename = ""); + Mainwindow(InformationManager* mgr); private: - void openBinary(const std::string& filename); + void addFunction(Function* fun); - void populateSymbolInformation(Function * fun); + QTextEdit *textEdit; + QPushButton *quitButton; + QMenu *fileMenu; - QTextEdit *textEdit; - QPushButton *quitButton; - QMenu *fileMenu; + QTabWidget * tabwidget; + QListWidget * listWidget; + QStackedWidget * stackedWidget; + QDockWidget * dockWidget; + ScriptingDock * scripting; - QTabWidget * tabwidget; - QListWidget * listWidget; - QStackedWidget * stackedWidget; - QDockWidget * dockWidget; - ScriptingDock * scripting; + QAction *exitAction; + QAction *openAction; - QAction *exitAction; - QAction *openAction; - - std::shared_ptr disassembler; std::map blocks; + std::set functions; + InformationManager* manager; private Q_SLOTS: - void quit(); - void open(); + void quit(); + void open(); }; #endif /* INCLUDE__Mainwindow_hxx_ */ diff --git a/src/main.cxx b/src/main.cxx index c33d6c4..290657d 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -17,6 +17,8 @@ #include "log4cxx/basicconfigurator.h" #include "gui/Mainwindow.hxx" +#include "core/InformationManager.hxx" +#include "disassembler/llvm/LLVMDisassembler.hxx" using std::cout; using std::cin; @@ -39,10 +41,11 @@ int main(int argc, char** argv) parser.addVersionOption(); parser.addPositionalArgument("filename", QCoreApplication::translate("main", "File to disassemble.")); - parser.process(app); #endif + InformationManager iman; + LOG4CXX_DEBUG(_logger, "Initializing LLVM"); llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); @@ -58,7 +61,8 @@ int main(int argc, char** argv) } #endif - Mainwindow m(filename); + Mainwindow m(&iman); m.show(); + iman.reset(filename); return app.exec(); } -- 2.39.2 From 9e283567ac56a6433e832d0fa38cf534a0cb8f9f Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Tue, 6 Jan 2015 22:26:57 +0100 Subject: [PATCH 05/16] Whitespace cleanup --- src/disassembler/BasicBlock.hxx | 20 +- src/disassembler/Disassembler.hxx | 10 +- src/disassembler/llvm/LLVMDisassembler.cxx | 672 ++++++++++----------- src/disassembler/llvm/LLVMDisassembler.hxx | 2 +- src/gui/Mainwindow.cxx | 14 +- src/gui/widgets/BasicBlockWidget.cxx | 20 +- src/gui/widgets/BasicBlockWidget.hxx | 44 +- src/gui/widgets/CFGScene.cxx | 132 ++-- src/gui/widgets/CFGScene.hxx | 24 +- src/gui/widgets/ScriptingDock.cxx | 52 +- src/gui/widgets/ScriptingDock.hxx | 56 +- src/main.cxx | 16 +- 12 files changed, 531 insertions(+), 531 deletions(-) diff --git a/src/disassembler/BasicBlock.hxx b/src/disassembler/BasicBlock.hxx index 1952f2b..6d623d0 100644 --- a/src/disassembler/BasicBlock.hxx +++ b/src/disassembler/BasicBlock.hxx @@ -5,18 +5,18 @@ class BasicBlock { public: - BasicBlock() { + BasicBlock() { next_blocks[0] = 0; next_blocks[1] = 0; } - uint64_t getStartAddress() const { - return start_address; - } + uint64_t getStartAddress() const { + return start_address; + } - uint64_t getEndAddress() const { - return end_address; - } + uint64_t getEndAddress() const { + return end_address; + } uint64_t getNextBlock(size_t index) const { assert(index < 2); @@ -37,10 +37,10 @@ public: } private: - uint64_t start_address; - uint64_t end_address; + uint64_t start_address; + uint64_t end_address; - uint64_t next_blocks[2]; + uint64_t next_blocks[2]; }; #endif diff --git a/src/disassembler/Disassembler.hxx b/src/disassembler/Disassembler.hxx index c88bfd5..4636ed9 100644 --- a/src/disassembler/Disassembler.hxx +++ b/src/disassembler/Disassembler.hxx @@ -1,4 +1,4 @@ - #ifndef INCLUDE__Disassembler_hxx +#ifndef INCLUDE__Disassembler_hxx #define INCLUDE__Disassembler_hxx #include @@ -11,7 +11,7 @@ class Disassembler { public: Disassembler(const std::string& filename, InformationManager* manager) {} - virtual ~Disassembler() {} + virtual ~Disassembler() {} virtual void start() = 0; virtual void getSymbols() = 0; @@ -20,10 +20,10 @@ public: virtual void forEachFunction(std::function callback) = 0; virtual void printEachInstruction(uint64_t start, uint64_t end, - std::function fun) = 0; + std::function fun) = 0; protected: - virtual bool isFunctionCall(uint64_t address) = 0; - virtual bool isJump(uint64_t address) = 0; + virtual bool isFunctionCall(uint64_t address) = 0; + virtual bool isJump(uint64_t address) = 0; }; #endif diff --git a/src/disassembler/llvm/LLVMDisassembler.cxx b/src/disassembler/llvm/LLVMDisassembler.cxx index 7f87b80..79c7a54 100644 --- a/src/disassembler/llvm/LLVMDisassembler.cxx +++ b/src/disassembler/llvm/LLVMDisassembler.cxx @@ -17,387 +17,387 @@ using std::error_code; LLVMDisassembler::LLVMDisassembler(const std::string& filename, InformationManager* manager) : Disassembler(filename, manager) - , logger(log4cxx::Logger::getLogger("LLVMDisassembler")) - , triple("unknown-unknown-unknown") - , manager(manager) + , logger(log4cxx::Logger::getLogger("LLVMDisassembler")) + , triple("unknown-unknown-unknown") + , manager(manager) { - LOG4CXX_DEBUG(logger, "Handling file" << filename); - auto result = createBinary(filename); - - error_code ec; - if ((ec = result.getError())) { - LOG4CXX_ERROR(logger, "Failed to load Binary" << ec.message()); - binary = NULL; - return; - } - - binary.reset(result.get()); - - o = dyn_cast(binary.get()); - - triple.setArch(Triple::ArchType(o->getArch())); - std::string tripleName(triple.getTriple()); - - LOG4CXX_INFO(logger, "Architecture " << tripleName); - - - std::string es; - target = TargetRegistry::lookupTarget("", triple, es); - if (!target) { - LOG4CXX_ERROR(logger, es); - return; - } - - LOG4CXX_INFO(logger, "Target " << target->getName()); - - MRI.reset(target->createMCRegInfo(tripleName)); - if (!MRI) { - LOG4CXX_ERROR(logger, "no register info for target " << tripleName); - return; - } - - // Set up disassembler. - AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName)); - if (!AsmInfo) { - LOG4CXX_ERROR(logger, "no assembly info for target " << tripleName); - return; - } - - STI.reset(target->createMCSubtargetInfo(tripleName, "", "")); - if (!STI) { - LOG4CXX_ERROR(logger, "no subtarget info for target " << tripleName); - return; - } - - MII.reset(target->createMCInstrInfo()); - if (!MII) { - LOG4CXX_ERROR(logger, "no instruction info for target " << tripleName); - return; - } - - MOFI.reset(new MCObjectFileInfo); - MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get()); - - DisAsm.reset(target->createMCDisassembler(*STI, Ctx)); - if (!DisAsm) { - LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName); - return; - } - RelInfo.reset( - target->createMCRelocationInfo(tripleName, Ctx)); - if (RelInfo) { - Symzer.reset( - MCObjectSymbolizer::createObjectSymbolizer(Ctx, std::move(RelInfo), o)); - if (Symzer) - DisAsm->setSymbolizer(std::move(Symzer)); - } - RelInfo.release(); - Symzer.release(); - - MIA.reset(target->createMCInstrAnalysis(MII.get())); - if (!MIA) { - LOG4CXX_ERROR(logger, "no instruction analysis for target " << tripleName); - return; - } - - int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); - if (!IP) { - LOG4CXX_ERROR(logger, "no instruction printer for target " << tripleName); - return; - } - - IP->setPrintImmHex(llvm::HexStyle::C); - IP->setPrintImmHex(true); - - std::unique_ptr OD( - new MCObjectDisassembler(*o, *DisAsm, *MIA)); - Mod.reset(OD->buildModule(false)); + LOG4CXX_DEBUG(logger, "Handling file" << filename); + auto result = createBinary(filename); + + error_code ec; + if ((ec = result.getError())) { + LOG4CXX_ERROR(logger, "Failed to load Binary" << ec.message()); + binary = NULL; + return; + } + + binary.reset(result.get()); + + o = dyn_cast(binary.get()); + + triple.setArch(Triple::ArchType(o->getArch())); + std::string tripleName(triple.getTriple()); + + LOG4CXX_INFO(logger, "Architecture " << tripleName); + + + std::string es; + target = TargetRegistry::lookupTarget("", triple, es); + if (!target) { + LOG4CXX_ERROR(logger, es); + return; + } + + LOG4CXX_INFO(logger, "Target " << target->getName()); + + MRI.reset(target->createMCRegInfo(tripleName)); + if (!MRI) { + LOG4CXX_ERROR(logger, "no register info for target " << tripleName); + return; + } + + // Set up disassembler. + AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName)); + if (!AsmInfo) { + LOG4CXX_ERROR(logger, "no assembly info for target " << tripleName); + return; + } + + STI.reset(target->createMCSubtargetInfo(tripleName, "", "")); + if (!STI) { + LOG4CXX_ERROR(logger, "no subtarget info for target " << tripleName); + return; + } + + MII.reset(target->createMCInstrInfo()); + if (!MII) { + LOG4CXX_ERROR(logger, "no instruction info for target " << tripleName); + return; + } + + MOFI.reset(new MCObjectFileInfo); + MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get()); + + DisAsm.reset(target->createMCDisassembler(*STI, Ctx)); + if (!DisAsm) { + LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName); + return; + } + RelInfo.reset( + target->createMCRelocationInfo(tripleName, Ctx)); + if (RelInfo) { + Symzer.reset( + MCObjectSymbolizer::createObjectSymbolizer(Ctx, std::move(RelInfo), o)); + if (Symzer) + DisAsm->setSymbolizer(std::move(Symzer)); + } + RelInfo.release(); + Symzer.release(); + + MIA.reset(target->createMCInstrAnalysis(MII.get())); + if (!MIA) { + LOG4CXX_ERROR(logger, "no instruction analysis for target " << tripleName); + return; + } + + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); + IP.reset(target->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); + if (!IP) { + LOG4CXX_ERROR(logger, "no instruction printer for target " << tripleName); + return; + } + + IP->setPrintImmHex(llvm::HexStyle::C); + IP->setPrintImmHex(true); + + std::unique_ptr OD( + new MCObjectDisassembler(*o, *DisAsm, *MIA)); + Mod.reset(OD->buildModule(false)); } void LLVMDisassembler::start() { - readSymbols(); - readSections(); - disassemble(); + readSymbols(); + readSections(); + disassemble(); } LLVMDisassembler::~LLVMDisassembler() { - std::for_each(functions.begin(), functions.end(), - [](std::pair it) { - delete it.second; - }); - std::for_each(blocks.begin(), blocks.end(), - [](std::pair it) { - delete it.second; - }); + std::for_each(functions.begin(), functions.end(), + [](std::pair it) { + delete it.second; + }); + std::for_each(blocks.begin(), blocks.end(), + [](std::pair it) { + delete it.second; + }); } Function* LLVMDisassembler::disassembleFunctionAt(uint64_t address, const std::string& name) { - SectionRef text_section = sections[".text"]; + SectionRef text_section = sections[".text"]; uint64_t base_address, size; text_section.getAddress(base_address); text_section.getSize(size); if (address < base_address || - address >= base_address + size) { + address >= base_address + size) { return NULL; } - if (functions.find(address) != functions.end()) { - return functions[address]; - } + if (functions.find(address) != functions.end()) { + return functions[address]; + } - LLVMFunction * function; - if (name == "") { - std::stringstream s; - s << ""; - function = new LLVMFunction(s.str(), address); - } else { - function = new LLVMFunction(name, address); - } - functions.insert(std::make_pair(address, function)); + LLVMFunction * function; + if (name == "") { + std::stringstream s; + s << ""; + function = new LLVMFunction(s.str(), address); + } else { + function = new LLVMFunction(name, address); + } + functions.insert(std::make_pair(address, function)); - disassembleFunction(function); + disassembleFunction(function); - return function; + return function; } void LLVMDisassembler::disassembleFunction(LLVMFunction* function) { - std::stack remaining_blocks; - SectionRef text_section = sections[".text"]; - StringRef bytes; - text_section.getContents(bytes); - StringRefMemoryObject ref(bytes); - - LOG4CXX_DEBUG(logger, "Handling function " << function->getName()); - - LLVMBasicBlock * block = new LLVMBasicBlock(function->getStartAddress(), this); - remaining_blocks.push(block); - blocks.insert(std::make_pair(block->getStartAddress(), block)); - - while (remaining_blocks.size()) { - LLVMBasicBlock * current_block = remaining_blocks.top(); - remaining_blocks.pop(); - - LOG4CXX_DEBUG(logger, "Handling Block starting at " << std::hex << current_block->getStartAddress()); - - uint64_t inst_size; - uint64_t base_address; - text_section.getAddress(base_address); - uint64_t current_address = current_block->getStartAddress() - base_address; - while(true) { - MCInst inst; - std::string buf; - llvm::raw_string_ostream s(buf); - - if(llvm::MCDisassembler::Success == - DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { - uint64_t jmptarget; - - if (MIA->evaluateBranch(inst, current_address, inst_size, jmptarget)) { - jmptarget += base_address; - if (!MIA->isIndirectBranch(inst)) { - if (MIA->isCall(inst)) { - if (functions.find(jmptarget) == functions.end()) { - disassembleFunctionAt(jmptarget); - } - } else { - current_block->setNextBlock(0, jmptarget); - if (blocks.find(jmptarget) == blocks.end()) { - LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this); - blocks.insert(std::make_pair(block->getStartAddress(), block)); - remaining_blocks.push(block); - } - if (MIA->isConditionalBranch(inst)) { - jmptarget = base_address + current_address + inst_size; - current_block->setNextBlock(1, jmptarget); - if (blocks.find(jmptarget) == blocks.end()) { - LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this); - blocks.insert(std::make_pair(block->getStartAddress(), block)); - remaining_blocks.push(block); - } - } - } - } - } - } else { - inst_size = 0; - } - - - if (inst_size == 0 || MIA->isTerminator(inst) || MIA->isBranch(inst)) { - current_block->setEndAddress(current_address + base_address + inst_size); - LOG4CXX_DEBUG(logger, "Finished Block at " << std::hex << - current_block->getEndAddress()); - break; - } - current_address += inst_size; - } - } - LOG4CXX_DEBUG(logger, "Finished function " << function->getName()); - manager->signal_new_function(function); + std::stack remaining_blocks; + SectionRef text_section = sections[".text"]; + StringRef bytes; + text_section.getContents(bytes); + StringRefMemoryObject ref(bytes); + + LOG4CXX_DEBUG(logger, "Handling function " << function->getName()); + + LLVMBasicBlock * block = new LLVMBasicBlock(function->getStartAddress(), this); + remaining_blocks.push(block); + blocks.insert(std::make_pair(block->getStartAddress(), block)); + + while (remaining_blocks.size()) { + LLVMBasicBlock * current_block = remaining_blocks.top(); + remaining_blocks.pop(); + + LOG4CXX_DEBUG(logger, "Handling Block starting at " << std::hex << current_block->getStartAddress()); + + uint64_t inst_size; + uint64_t base_address; + text_section.getAddress(base_address); + uint64_t current_address = current_block->getStartAddress() - base_address; + while(true) { + MCInst inst; + std::string buf; + llvm::raw_string_ostream s(buf); + + if(llvm::MCDisassembler::Success == + DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { + uint64_t jmptarget; + + if (MIA->evaluateBranch(inst, current_address, inst_size, jmptarget)) { + jmptarget += base_address; + if (!MIA->isIndirectBranch(inst)) { + if (MIA->isCall(inst)) { + if (functions.find(jmptarget) == functions.end()) { + disassembleFunctionAt(jmptarget); + } + } else { + current_block->setNextBlock(0, jmptarget); + if (blocks.find(jmptarget) == blocks.end()) { + LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this); + blocks.insert(std::make_pair(block->getStartAddress(), block)); + remaining_blocks.push(block); + } + if (MIA->isConditionalBranch(inst)) { + jmptarget = base_address + current_address + inst_size; + current_block->setNextBlock(1, jmptarget); + if (blocks.find(jmptarget) == blocks.end()) { + LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this); + blocks.insert(std::make_pair(block->getStartAddress(), block)); + remaining_blocks.push(block); + } + } + } + } + } + } else { + inst_size = 0; + } + + + if (inst_size == 0 || MIA->isTerminator(inst) || MIA->isBranch(inst)) { + current_block->setEndAddress(current_address + base_address + inst_size); + LOG4CXX_DEBUG(logger, "Finished Block at " << std::hex << + current_block->getEndAddress()); + break; + } + current_address += inst_size; + } + } + LOG4CXX_DEBUG(logger, "Finished function " << function->getName()); + manager->signal_new_function(function); } void LLVMDisassembler::disassemble() { - SectionRef text_section = sections[".text"]; - std::vector remaining_functions; - - // Assume all function symbols actually start a real function - for (auto x = symbols.begin(); x != symbols.end(); ++x) { - uint64_t result; - bool contains; - SymbolRef::Type symbol_type; - - - if (text_section.containsSymbol(x->second, contains) || !contains) - continue; - - if (x->second.getType(symbol_type) - || SymbolRef::ST_Function != symbol_type) - continue; - - if (!x->second.getAddress(result)) { - LLVMFunction * fun = new LLVMFunction(x->first, result); - remaining_functions.push_back(fun); - functions.insert(std::make_pair(result, fun)); - LOG4CXX_DEBUG(logger, "Disasembling " << x->first); - } - } - - for (LLVMFunction* function : remaining_functions) { - disassembleFunction(function); - } - - if (binary->isELF()) { - bool is64bit = (binary->getData()[4] == 0x02); - - uint64_t entry(0); - for (int i(0); i < (is64bit? 8 : 4); ++i) { - if (binary->isLittleEndian()) { - entry |= (unsigned int)((unsigned char)binary->getData()[0x18 + i]) << 8*i; - } else { - entry = entry << 8; - entry |= (unsigned char)binary->getData()[0x18 + i]; - } - } - LOG4CXX_DEBUG(logger, "Adding entry at: " << std::hex << entry); - std::stringstream s; - s << "<_start 0x" << std::hex << entry << ">"; - - disassembleFunctionAt(entry, s.str()); - } - - if (functions.empty()) { - uint64_t text_entry; - text_section.getAddress(text_entry); - LOG4CXX_INFO(logger, "No Symbols found, starting at the beginning of the text segment"); - disassembleFunctionAt(text_entry); - } - - splitBlocks(); + SectionRef text_section = sections[".text"]; + std::vector remaining_functions; + + // Assume all function symbols actually start a real function + for (auto x = symbols.begin(); x != symbols.end(); ++x) { + uint64_t result; + bool contains; + SymbolRef::Type symbol_type; + + + if (text_section.containsSymbol(x->second, contains) || !contains) + continue; + + if (x->second.getType(symbol_type) + || SymbolRef::ST_Function != symbol_type) + continue; + + if (!x->second.getAddress(result)) { + LLVMFunction * fun = new LLVMFunction(x->first, result); + remaining_functions.push_back(fun); + functions.insert(std::make_pair(result, fun)); + LOG4CXX_DEBUG(logger, "Disasembling " << x->first); + } + } + + for (LLVMFunction* function : remaining_functions) { + disassembleFunction(function); + } + + if (binary->isELF()) { + bool is64bit = (binary->getData()[4] == 0x02); + + uint64_t entry(0); + for (int i(0); i < (is64bit? 8 : 4); ++i) { + if (binary->isLittleEndian()) { + entry |= (unsigned int)((unsigned char)binary->getData()[0x18 + i]) << 8*i; + } else { + entry = entry << 8; + entry |= (unsigned char)binary->getData()[0x18 + i]; + } + } + LOG4CXX_DEBUG(logger, "Adding entry at: " << std::hex << entry); + std::stringstream s; + s << "<_start 0x" << std::hex << entry << ">"; + + disassembleFunctionAt(entry, s.str()); + } + + if (functions.empty()) { + uint64_t text_entry; + text_section.getAddress(text_entry); + LOG4CXX_INFO(logger, "No Symbols found, starting at the beginning of the text segment"); + disassembleFunctionAt(text_entry); + } + + splitBlocks(); } void LLVMDisassembler::splitBlocks() { - SectionRef text_section = sections[".text"]; - StringRef bytes; - text_section.getContents(bytes); - StringRefMemoryObject ref(bytes); - - // Split blocks where jumps are going inside the block - for (auto it = blocks.begin(); it != blocks.end(); ++it) { - LLVMBasicBlock * current_block = it->second; - uint64_t inst_size; - uint64_t base_address; - text_section.getAddress(base_address); - uint64_t current_address = current_block->getStartAddress() - base_address; - while(current_block->getEndAddress() - base_address > current_address) { - MCInst inst; - std::string buf; - llvm::raw_string_ostream s(buf); - - if(llvm::MCDisassembler::Success == - DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { - auto other = blocks.find(current_address + inst_size + base_address); - - if (other != blocks.end()) { - uint64_t endaddress = current_address + inst_size + base_address; - if (endaddress != current_block->getEndAddress()) { - LOG4CXX_DEBUG(logger, "Shortening block starting at " - << std::hex - << current_block->getStartAddress() - << " now ending at " - << other->first); - current_block->setEndAddress(endaddress); - current_block->setNextBlock(0, other->first); - current_block->setNextBlock(1, 0); - } - } - } else { - inst_size = 1; - } - current_address += inst_size; - } - } + SectionRef text_section = sections[".text"]; + StringRef bytes; + text_section.getContents(bytes); + StringRefMemoryObject ref(bytes); + + // Split blocks where jumps are going inside the block + for (auto it = blocks.begin(); it != blocks.end(); ++it) { + LLVMBasicBlock * current_block = it->second; + uint64_t inst_size; + uint64_t base_address; + text_section.getAddress(base_address); + uint64_t current_address = current_block->getStartAddress() - base_address; + while(current_block->getEndAddress() - base_address > current_address) { + MCInst inst; + std::string buf; + llvm::raw_string_ostream s(buf); + + if(llvm::MCDisassembler::Success == + DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { + auto other = blocks.find(current_address + inst_size + base_address); + + if (other != blocks.end()) { + uint64_t endaddress = current_address + inst_size + base_address; + if (endaddress != current_block->getEndAddress()) { + LOG4CXX_DEBUG(logger, "Shortening block starting at " + << std::hex + << current_block->getStartAddress() + << " now ending at " + << other->first); + current_block->setEndAddress(endaddress); + current_block->setNextBlock(0, other->first); + current_block->setNextBlock(1, 0); + } + } + } else { + inst_size = 1; + } + current_address += inst_size; + } + } } void LLVMDisassembler::readSymbols() { - error_code ec; - symbol_iterator si(o->symbol_begin()), se(o->symbol_end()); - for (; si != se; ++si) { - StringRef name; - if ((ec = si->getName(name))) { - LOG4CXX_ERROR(logger, ec.message()); - break; - } - LOG4CXX_DEBUG(logger, "Added symbol " << name.str()); - symbols.insert(make_pair(name.str(), *si)); - } + error_code ec; + symbol_iterator si(o->symbol_begin()), se(o->symbol_end()); + for (; si != se; ++si) { + StringRef name; + if ((ec = si->getName(name))) { + LOG4CXX_ERROR(logger, ec.message()); + break; + } + LOG4CXX_DEBUG(logger, "Added symbol " << name.str()); + symbols.insert(make_pair(name.str(), *si)); + } } void LLVMDisassembler::readSections() { - error_code ec; - section_iterator i(o->section_begin()), e(o->section_end()); - for (; i != e; ++i) { - StringRef name; - if ((ec = i->getName(name))) { - LOG4CXX_ERROR(logger, ec.message()); - break; - } - LOG4CXX_DEBUG(logger, "Added section " << name.str()); - sections.insert(make_pair(name.str(), *i)); - } + error_code ec; + section_iterator i(o->section_begin()), e(o->section_end()); + for (; i != e; ++i) { + StringRef name; + if ((ec = i->getName(name))) { + LOG4CXX_ERROR(logger, ec.message()); + break; + } + LOG4CXX_DEBUG(logger, "Added section " << name.str()); + sections.insert(make_pair(name.str(), *i)); + } } void LLVMDisassembler::forEachFunction(std::function callback) { - std::for_each(functions.begin(), functions.end(), - [&](std::pair x) { - callback(x.first, x.second); - }); + std::for_each(functions.begin(), functions.end(), + [&](std::pair x) { + callback(x.first, x.second); + }); } void LLVMDisassembler::printEachInstruction(uint64_t start, uint64_t end, - std::function fun) { - SectionRef text_section = sections[".text"]; - uint64_t base_address; - text_section.getAddress(base_address); - uint64_t current_address = start - base_address; - - StringRef bytes; - text_section.getContents(bytes); - StringRefMemoryObject ref(bytes); - - while (current_address < end - base_address) { - uint64_t inst_size; - MCInst inst; + std::function fun) { + SectionRef text_section = sections[".text"]; + uint64_t base_address; + text_section.getAddress(base_address); + uint64_t current_address = start - base_address; + + StringRef bytes; + text_section.getContents(bytes); + StringRefMemoryObject ref(bytes); + + while (current_address < end - base_address) { + uint64_t inst_size; + MCInst inst; std::string buf; llvm::raw_string_ostream s(buf); - if(llvm::MCDisassembler::Success == - DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { + if(llvm::MCDisassembler::Success == + DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { - uint8_t bytes[inst_size+2]; - ref.readBytes(current_address, inst_size, bytes); + uint8_t bytes[inst_size+2]; + ref.readBytes(current_address, inst_size, bytes); uint64_t jmptarget; if (MIA->evaluateBranch(inst, current_address, inst_size, jmptarget)) { @@ -408,12 +408,12 @@ void LLVMDisassembler::printEachInstruction(uint64_t start, uint64_t end, IP->printInst(&inst, s, ""); fun(bytes, inst_size, s.str()); - } else { + } else { LOG4CXX_WARN(logger, "Invalid byte at" << std::hex << current_address + base_address); fun(NULL, 0, "Invalid Byte"); inst_size = 1; } current_address += inst_size; - } + } } diff --git a/src/disassembler/llvm/LLVMDisassembler.hxx b/src/disassembler/llvm/LLVMDisassembler.hxx index d26bb12..107767d 100644 --- a/src/disassembler/llvm/LLVMDisassembler.hxx +++ b/src/disassembler/llvm/LLVMDisassembler.hxx @@ -26,7 +26,7 @@ public: void forEachFunction(std::function callback); void printEachInstruction(uint64_t start, uint64_t end, - std::function fun); + std::function fun); BasicBlock * getBasicBlock(uint64_t address) { return blocks[address]; diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 7b207fa..5fd57aa 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -126,9 +126,9 @@ namespace { widget->moveBy(100*startx, block->getStartAddress() - starty); dis->printEachInstruction(block->getStartAddress(), block->getEndAddress(), - [&](uint8_t* bytes, size_t byte_count, const std::string& line) { - widget->addItem(bytes, byte_count, line.c_str() + 1); - }); + [&](uint8_t* bytes, size_t byte_count, const std::string& line) { + widget->addItem(bytes, byte_count, line.c_str() + 1); + }); BasicBlockWidget *tmp, *nextl(NULL), *nextr(NULL); BasicBlock * tmpblock; @@ -138,16 +138,16 @@ namespace { xshift = 1; tmpblock = dis->getBasicBlock(block->getNextBlock(0)); tmp = local__add_basic_block(tmpblock, dis, - known_blocks, - scene, starty, startx+xshift); + known_blocks, + scene, starty, startx+xshift); nextl = tmp; tmp->addPrevious(widget); } if (block->getNextBlock(1) != 0) { tmpblock = dis->getBasicBlock(block->getNextBlock(1)); tmp = local__add_basic_block(tmpblock, dis, - known_blocks, - scene, starty, startx-1); + known_blocks, + scene, starty, startx-1); nextr = tmp; tmp->addPrevious(widget); } diff --git a/src/gui/widgets/BasicBlockWidget.cxx b/src/gui/widgets/BasicBlockWidget.cxx index faaa2a6..ab06f88 100644 --- a/src/gui/widgets/BasicBlockWidget.cxx +++ b/src/gui/widgets/BasicBlockWidget.cxx @@ -4,21 +4,21 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block) : width(270), height(45) , name(name), block(block) { next[0] = NULL; next[1] = NULL; - _widget.move(5, 20); + _widget.move(5, 20); - if (width < 270) width = 270; + if (width < 270) width = 270; } void BasicBlockWidget::addItem(uint8_t* bytes, size_t num_bytes, const QString& line) { - QString bytestring; + QString bytestring; - for (size_t i(0); i < num_bytes; ++i) { - const char * hexdigits = "0123456789ABCDEF"; - bytestring += hexdigits[(bytes[i] >> 4) & 0xF]; - bytestring += hexdigits[bytes[i] & 0xF]; - bytestring += ' '; - } + for (size_t i(0); i < num_bytes; ++i) { + const char * hexdigits = "0123456789ABCDEF"; + bytestring += hexdigits[(bytes[i] >> 4) & 0xF]; + bytestring += hexdigits[bytes[i] & 0xF]; + bytestring += ' '; + } QString old_text = _widget.text(); if (old_text == "") { @@ -35,5 +35,5 @@ void BasicBlockWidget::addItem(uint8_t* bytes, size_t num_bytes, width = 12 + _widget.sizeHint().width(); height = 25 + _widget.sizeHint().height(); - if (width < 250) width = 250; + if (width < 250) width = 250; } diff --git a/src/gui/widgets/BasicBlockWidget.hxx b/src/gui/widgets/BasicBlockWidget.hxx index e40ed84..2dcc80c 100644 --- a/src/gui/widgets/BasicBlockWidget.hxx +++ b/src/gui/widgets/BasicBlockWidget.hxx @@ -11,41 +11,41 @@ class BasicBlockWidget : public QGraphicsItem { public: - BasicBlockWidget(const QString& name, BasicBlock * block); + BasicBlockWidget(const QString& name, BasicBlock * block); void addItem(uint8_t* bytes, size_t num_bytes, const QString& line); - QRectF boundingRect() const { - qreal penWidth = 1; + QRectF boundingRect() const { + qreal penWidth = 1; QRectF result(- penWidth / 2, - penWidth / 2, - width + penWidth, height + penWidth); - return result; - } + width + penWidth, height + penWidth); + return result; + } void mouseMoveEvent(QGraphicsSceneMouseEvent * event) { QGraphicsItem::mouseMoveEvent(event); - scene()->update(); + scene()->update(); } QPointF getEntry() const { return mapToScene(QPointF(width/2, 0)); } - std::array getExits() const { - return { { mapToScene(QPointF( width/3, height)), + std::array getExits() const { + return { { mapToScene(QPointF( width/3, height)), mapToScene(QPointF( width/2, height)), mapToScene(QPointF(2*width/3, height)) } }; - } + } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) { - painter->fillRect(0, 0, width, height, QColor(0xcc, 0xcc, 0xff, 0xff)); - painter->setPen(QColor(0x00, 0x00, 0xff, 0xff)); - painter->drawRect(0, 0, width, height); - painter->drawText(5, 15, name); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) { + painter->fillRect(0, 0, width, height, QColor(0xcc, 0xcc, 0xff, 0xff)); + painter->setPen(QColor(0x00, 0x00, 0xff, 0xff)); + painter->drawRect(0, 0, width, height); + painter->drawText(5, 15, name); if (_widget.text() != "") _widget.render(painter, QPoint(5, 20)); - } + } void addPrevious(BasicBlockWidget * widget) { previous.push_back(widget); @@ -56,13 +56,13 @@ public: next[1] = right; } - BasicBlockWidget ** getNext() { - return next; - } + BasicBlockWidget ** getNext() { + return next; + } private: - uint32_t width, height; - QLabel _widget; + uint32_t width, height; + QLabel _widget; QString name; BasicBlock * block; std::vector previous; diff --git a/src/gui/widgets/CFGScene.cxx b/src/gui/widgets/CFGScene.cxx index 75a39f0..ec33463 100644 --- a/src/gui/widgets/CFGScene.cxx +++ b/src/gui/widgets/CFGScene.cxx @@ -1,44 +1,44 @@ #include "CFGScene.hxx" void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) { - QGraphicsScene::drawBackground(painter, rect); + QGraphicsScene::drawBackground(painter, rect); - spaceWidgets(); + spaceWidgets(); - for (BasicBlockWidget * widget : widgets) { + for (BasicBlockWidget * widget : widgets) { QPointF kopf = widget->getEntry(); - painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); - painter->drawLine(kopf, kopf - QPointF(0, 20)); + painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); + painter->drawLine(kopf, kopf - QPointF(0, 20)); - auto tails = widget->getExits(); - auto next = widget->getNext(); - if (NULL != next[0]) { - if (NULL != next[1]) { - painter->setPen(QColor(0xff, 0x00, 0x00, 0xff)); - painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20)); - drawLine(painter, widget, next[1], -1); + auto tails = widget->getExits(); + auto next = widget->getNext(); + if (NULL != next[0]) { + if (NULL != next[1]) { + painter->setPen(QColor(0xff, 0x00, 0x00, 0xff)); + painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20)); + drawLine(painter, widget, next[1], -1); - painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); - painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20)); - drawLine(painter, widget, next[0], 1); - } else { - painter->setPen(QColor(0x00, 0x00, 0x00, 0xff)); - painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20)); - drawLine(painter, widget, next[0], 0); - } - } - } + painter->setPen(QColor(0x00, 0xff, 0x00, 0xff)); + painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20)); + drawLine(painter, widget, next[0], 1); + } else { + painter->setPen(QColor(0x00, 0x00, 0x00, 0xff)); + painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20)); + drawLine(painter, widget, next[0], 0); + } + } + } } void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to, int8_t side) { QPointF from_p = from->getExits()[side+1] + QPointF(0, 20); QPointF to_p = to->getEntry() - QPointF(0, 20); - if ((to_p - from_p).y() > 0) { + if ((to_p - from_p).y() > 0) { /* Forward Edge */ - QPointF angle1(from_p + QPointF(0, (to_p - from_p).y())); - painter->drawLine(from_p, angle1); - painter->drawLine(angle1, to_p); - } else { + QPointF angle1(from_p + QPointF(0, (to_p - from_p).y())); + painter->drawLine(from_p, angle1); + painter->drawLine(angle1, to_p); + } else { /* Backward Edge */ QRectF from_r(from->boundingRect()), to_r(to->boundingRect()); from_r.moveTo(from->scenePos()); @@ -65,45 +65,45 @@ void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWi } void CFGScene::spaceWidgets() { - bool changed = false; - do { - changed = false; - for (BasicBlockWidget * widget : widgets) { - QPointF out(std::get<0>(widget->getExits())); - BasicBlockWidget ** next = widget->getNext(); + bool changed = false; + do { + changed = false; + for (BasicBlockWidget * widget : widgets) { + QPointF out(std::get<0>(widget->getExits())); + BasicBlockWidget ** next = widget->getNext(); - if (NULL != next[0] - && (next[0]->getEntry() - widget->getEntry()).y() > 0 - && (next[0]->getEntry() - out).y() < 50) { - next[0]->moveBy(0, 1); - changed = true; - } - if (NULL != next[1] - && (next[1]->getEntry() - widget->getEntry()).y() > 0 - && (next[1]->getEntry() - out).y() < 50) { - next[1]->moveBy(0, 1); - changed = true; - } - } - } while (changed); + if (NULL != next[0] + && (next[0]->getEntry() - widget->getEntry()).y() > 0 + && (next[0]->getEntry() - out).y() < 50) { + next[0]->moveBy(0, 1); + changed = true; + } + if (NULL != next[1] + && (next[1]->getEntry() - widget->getEntry()).y() > 0 + && (next[1]->getEntry() - out).y() < 50) { + next[1]->moveBy(0, 1); + changed = true; + } + } + } while (changed); - for (BasicBlockWidget * widget : widgets) { - QRectF relevantRect = widget->boundingRect(); - relevantRect.moveTo(widget->scenePos()); - relevantRect.adjust(-20, -20, 20, 20); - for (QGraphicsItem * item : items(relevantRect)) { - if (item == widget) continue; - QRectF itemrect = item->boundingRect(); - itemrect.moveTo(item->scenePos()); - while (relevantRect.intersects(itemrect)) { - if (widget->scenePos().x() > item->scenePos().x()) { - widget->moveBy(1, 0); - relevantRect.moveTo(widget->scenePos()); - } else { - item->moveBy(1, 0); - itemrect.moveTo(item->scenePos()); - } - } - } - } + for (BasicBlockWidget * widget : widgets) { + QRectF relevantRect = widget->boundingRect(); + relevantRect.moveTo(widget->scenePos()); + relevantRect.adjust(-20, -20, 20, 20); + for (QGraphicsItem * item : items(relevantRect)) { + if (item == widget) continue; + QRectF itemrect = item->boundingRect(); + itemrect.moveTo(item->scenePos()); + while (relevantRect.intersects(itemrect)) { + if (widget->scenePos().x() > item->scenePos().x()) { + widget->moveBy(1, 0); + relevantRect.moveTo(widget->scenePos()); + } else { + item->moveBy(1, 0); + itemrect.moveTo(item->scenePos()); + } + } + } + } } diff --git a/src/gui/widgets/CFGScene.hxx b/src/gui/widgets/CFGScene.hxx index fb395f7..b343381 100644 --- a/src/gui/widgets/CFGScene.hxx +++ b/src/gui/widgets/CFGScene.hxx @@ -8,23 +8,23 @@ class CFGScene : public QGraphicsScene { public: - CFGScene(QWidget * parent = 0) - : QGraphicsScene(parent) {} + CFGScene(QWidget * parent = 0) + : QGraphicsScene(parent) {} - // Take special care when adding a BasicBlock to the scene as we - // need to draw arrows for it later on - void addItem(BasicBlockWidget* block) { - widgets.push_back(block); - QGraphicsScene::addItem(block); - } + // Take special care when adding a BasicBlock to the scene as we + // need to draw arrows for it later on + void addItem(BasicBlockWidget* block) { + widgets.push_back(block); + QGraphicsScene::addItem(block); + } - virtual void drawBackground(QPainter* painter, const QRectF & rect); + virtual void drawBackground(QPainter* painter, const QRectF & rect); private: - std::vector widgets; + std::vector widgets; - void drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to, int8_t side = 0); + void drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to, int8_t side = 0); - void spaceWidgets(); + void spaceWidgets(); }; #endif diff --git a/src/gui/widgets/ScriptingDock.cxx b/src/gui/widgets/ScriptingDock.cxx index 72ba9b0..86bc766 100644 --- a/src/gui/widgets/ScriptingDock.cxx +++ b/src/gui/widgets/ScriptingDock.cxx @@ -1,36 +1,36 @@ #include "ScriptingDock.hxx" namespace { - SCM handler (void *data, SCM tag, SCM throw_args) { - scm_handle_by_message_noexit ((void*)"foo", tag, throw_args); - return SCM_BOOL_F; - } + SCM handler (void *data, SCM tag, SCM throw_args) { + scm_handle_by_message_noexit ((void*)"foo", tag, throw_args); + return SCM_BOOL_F; + } } void ScriptingDock::doEvaluate() { - QString text = line->text(); - line->clear(); - LOG4CXX_INFO(logger, "Evaluating String \"" << text.toStdString() << "\""); - browser->append(QString("> ") + text); - - SCM result_obj = scm_internal_catch(SCM_BOOL_T, - (SCM (*)(void *))scm_c_eval_string, - (void*)text.toStdString().c_str(), - handler, NULL); - SCM result_str = scm_object_to_string(result_obj, SCM_UNDEFINED); + QString text = line->text(); + line->clear(); + LOG4CXX_INFO(logger, "Evaluating String \"" << text.toStdString() << "\""); + browser->append(QString("> ") + text); - SCM output = scm_get_output_string(guile_output_port); - QString output_q = scm_to_locale_string(output); - if (output_q.endsWith("\n")) output_q.chop(1); - if (output_q != "") browser->append(output_q); + SCM result_obj = scm_internal_catch(SCM_BOOL_T, + (SCM (*)(void *))scm_c_eval_string, + (void*)text.toStdString().c_str(), + handler, NULL); + SCM result_str = scm_object_to_string(result_obj, SCM_UNDEFINED); - output = scm_get_output_string(guile_error_port); - output_q = scm_to_locale_string(output); - if (output_q.endsWith("\n")) output_q.chop(1); - if (output_q != "") browser->append(output_q); + SCM output = scm_get_output_string(guile_output_port); + QString output_q = scm_to_locale_string(output); + if (output_q.endsWith("\n")) output_q.chop(1); + if (output_q != "") browser->append(output_q); - scm_truncate_file(guile_output_port, scm_from_uint16(0)); - scm_truncate_file(guile_error_port, scm_from_uint16(0)); - - browser->append(scm_to_locale_string(result_str)); + output = scm_get_output_string(guile_error_port); + output_q = scm_to_locale_string(output); + if (output_q.endsWith("\n")) output_q.chop(1); + if (output_q != "") browser->append(output_q); + + scm_truncate_file(guile_output_port, scm_from_uint16(0)); + scm_truncate_file(guile_error_port, scm_from_uint16(0)); + + browser->append(scm_to_locale_string(result_str)); } diff --git a/src/gui/widgets/ScriptingDock.hxx b/src/gui/widgets/ScriptingDock.hxx index ebbbc98..b6fc446 100644 --- a/src/gui/widgets/ScriptingDock.hxx +++ b/src/gui/widgets/ScriptingDock.hxx @@ -5,40 +5,40 @@ #include class ScriptingDock : public QDockWidget { - Q_OBJECT + Q_OBJECT public: - ScriptingDock(const QString& title, QWidget * parent = 0) - : QDockWidget(title, parent) - , logger(log4cxx::Logger::getLogger("ScriptingDock")) { - QTabWidget * tab = new QTabWidget; - QWidget * widget = new QWidget; - widget->setLayout(layout = new QGridLayout); - layout->addWidget(browser = new QTextBrowser, 0, 0, 1, 0); - layout->addWidget(line = new QLineEdit, 1, 0); - layout->addWidget(button = new QPushButton(tr("Evaluate")), 1, 1); - tab->addTab(widget, "GUILE"); - ((QDockWidget*)this)->setWidget(tab); - connect(button, SIGNAL(released()), this, SLOT(doEvaluate())); - connect(line, SIGNAL(returnPressed()), this, SLOT(doEvaluate())); - scm_init_guile(); - guile_output_port = scm_open_output_string(); - guile_error_port = scm_open_output_string(); - scm_set_current_output_port(guile_output_port); - scm_set_current_error_port(guile_error_port); - } + ScriptingDock(const QString& title, QWidget * parent = 0) + : QDockWidget(title, parent) + , logger(log4cxx::Logger::getLogger("ScriptingDock")) { + QTabWidget * tab = new QTabWidget; + QWidget * widget = new QWidget; + widget->setLayout(layout = new QGridLayout); + layout->addWidget(browser = new QTextBrowser, 0, 0, 1, 0); + layout->addWidget(line = new QLineEdit, 1, 0); + layout->addWidget(button = new QPushButton(tr("Evaluate")), 1, 1); + tab->addTab(widget, "GUILE"); + ((QDockWidget*)this)->setWidget(tab); + connect(button, SIGNAL(released()), this, SLOT(doEvaluate())); + connect(line, SIGNAL(returnPressed()), this, SLOT(doEvaluate())); + scm_init_guile(); + guile_output_port = scm_open_output_string(); + guile_error_port = scm_open_output_string(); + scm_set_current_output_port(guile_output_port); + scm_set_current_error_port(guile_error_port); + } private: - log4cxx::LoggerPtr logger; + log4cxx::LoggerPtr logger; - QTextBrowser * browser; - QGridLayout * layout; - QPushButton * button; - QLineEdit * line; + QTextBrowser * browser; + QGridLayout * layout; + QPushButton * button; + QLineEdit * line; - SCM guile_output_port; - SCM guile_error_port; + SCM guile_output_port; + SCM guile_error_port; private Q_SLOTS: - void doEvaluate(); + void doEvaluate(); }; #endif diff --git a/src/main.cxx b/src/main.cxx index 290657d..0c1ffe5 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -28,8 +28,8 @@ int main(int argc, char** argv) { QApplication app(argc, argv); - log4cxx::BasicConfigurator::configure(); - log4cxx::LoggerPtr _logger(log4cxx::Logger::getLogger("main")); + log4cxx::BasicConfigurator::configure(); + log4cxx::LoggerPtr _logger(log4cxx::Logger::getLogger("main")); #ifdef ARGPARSE QCommandLineParser parser; @@ -46,13 +46,13 @@ int main(int argc, char** argv) InformationManager iman; - LOG4CXX_DEBUG(_logger, "Initializing LLVM"); - llvm::InitializeAllTargetInfos(); - llvm::InitializeAllTargetMCs(); - llvm::InitializeAllAsmParsers(); - llvm::InitializeAllDisassemblers(); + LOG4CXX_DEBUG(_logger, "Initializing LLVM"); + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); - LOG4CXX_DEBUG(_logger, "Initializing Qt"); + LOG4CXX_DEBUG(_logger, "Initializing Qt"); std::string filename = ""; #ifdef ARGPARSE -- 2.39.2 From adfc94c02957100b20f4f7d1ce63ed463cc253a3 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Wed, 7 Jan 2015 21:38:37 +0100 Subject: [PATCH 06/16] Remove debug output left in unintentionally --- src/gui/Mainwindow.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 5fd57aa..34dcfb1 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -84,8 +84,6 @@ void Mainwindow::addFunction(Function* fun) { CFGScene * scene = new CFGScene; Disassembler * dis = manager->getDisassembler(); - std::cerr << dis << std::endl; - BasicBlock * block = dis->getBasicBlock(fun->getStartAddress()); local__add_basic_block(block, manager->getDisassembler(), blocks, scene, block->getStartAddress(), 100); -- 2.39.2 From 4bcd18ed3dc3450d014351f5b27d1c7d1596601c Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Wed, 7 Jan 2015 21:41:22 +0100 Subject: [PATCH 07/16] Use QGraphicsProxyWidget This way the qlabel widget can be accessed properly (clicking and stuff) --- src/gui/widgets/BasicBlockWidget.cxx | 11 ++++++++--- src/gui/widgets/BasicBlockWidget.hxx | 3 +-- src/gui/widgets/CFGScene.cxx | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/BasicBlockWidget.cxx b/src/gui/widgets/BasicBlockWidget.cxx index ab06f88..2003458 100644 --- a/src/gui/widgets/BasicBlockWidget.cxx +++ b/src/gui/widgets/BasicBlockWidget.cxx @@ -2,9 +2,13 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block) : width(270), height(45) - , name(name), block(block) { + , name(name), block(block) + , _proxy(this) { next[0] = NULL; next[1] = NULL; - _widget.move(5, 20); + _proxy.setWidget(&_widget); + _widget.setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::LinksAccessibleByMouse); + + _proxy.setPos(5, 20); if (width < 270) width = 270; } @@ -22,7 +26,7 @@ void BasicBlockWidget::addItem(uint8_t* bytes, size_t num_bytes, QString old_text = _widget.text(); if (old_text == "") { - old_text = ""; + old_text = "
"; } QString new_text = old_text.remove("
") + @@ -32,6 +36,7 @@ void BasicBlockWidget::addItem(uint8_t* bytes, size_t num_bytes, ""; _widget.setText(new_text); + _widget.resize(_widget.sizeHint().width(), _widget.sizeHint().height()); width = 12 + _widget.sizeHint().width(); height = 25 + _widget.sizeHint().height(); diff --git a/src/gui/widgets/BasicBlockWidget.hxx b/src/gui/widgets/BasicBlockWidget.hxx index 2dcc80c..8aa182f 100644 --- a/src/gui/widgets/BasicBlockWidget.hxx +++ b/src/gui/widgets/BasicBlockWidget.hxx @@ -43,8 +43,6 @@ public: painter->setPen(QColor(0x00, 0x00, 0xff, 0xff)); painter->drawRect(0, 0, width, height); painter->drawText(5, 15, name); - if (_widget.text() != "") - _widget.render(painter, QPoint(5, 20)); } void addPrevious(BasicBlockWidget * widget) { @@ -62,6 +60,7 @@ public: private: uint32_t width, height; + QGraphicsProxyWidget _proxy; QLabel _widget; QString name; BasicBlock * block; diff --git a/src/gui/widgets/CFGScene.cxx b/src/gui/widgets/CFGScene.cxx index ec33463..4e7428d 100644 --- a/src/gui/widgets/CFGScene.cxx +++ b/src/gui/widgets/CFGScene.cxx @@ -93,6 +93,7 @@ void CFGScene::spaceWidgets() { relevantRect.adjust(-20, -20, 20, 20); for (QGraphicsItem * item : items(relevantRect)) { if (item == widget) continue; + if (std::find(widgets.begin(), widgets.end(), item) == widgets.end()) continue; QRectF itemrect = item->boundingRect(); itemrect.moveTo(item->scenePos()); while (relevantRect.intersects(itemrect)) { -- 2.39.2 From 079cf5a082a42232de30be1dd88779aac085174c Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Wed, 7 Jan 2015 21:44:04 +0100 Subject: [PATCH 08/16] BUGS file --- BUGS.org | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 BUGS.org diff --git a/BUGS.org b/BUGS.org new file mode 100644 index 0000000..17c6a53 --- /dev/null +++ b/BUGS.org @@ -0,0 +1,10 @@ +* TODO BasicBlockWidget should get an unique type + + As a result, properly filter BasicBlockWidgets when spacing + without linearly searching through all BasicBlockWidgets all the + time + +* TODO Splitting BasicBlocks needs to happen sooner + + BasicBlocks are splittet too late these days. As a result we + sometimes get BasicBlocks that are suffixes of other BasicBlocks -- 2.39.2 From 9904a19c01453a1d86d0249424f2afe9e3263af0 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 8 Jan 2015 18:40:21 +0100 Subject: [PATCH 09/16] Properly color text part of basic block widgets If the text was smaller than the minimum, rendering was ugly --- src/gui/widgets/BasicBlockWidget.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/BasicBlockWidget.cxx b/src/gui/widgets/BasicBlockWidget.cxx index 2003458..e65b6e2 100644 --- a/src/gui/widgets/BasicBlockWidget.cxx +++ b/src/gui/widgets/BasicBlockWidget.cxx @@ -7,7 +7,7 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block) next[0] = NULL; next[1] = NULL; _proxy.setWidget(&_widget); _widget.setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::LinksAccessibleByMouse); - + _widget.setStyleSheet("QLabel { background-color : #ddddff; }"); _proxy.setPos(5, 20); if (width < 270) width = 270; @@ -26,19 +26,19 @@ void BasicBlockWidget::addItem(uint8_t* bytes, size_t num_bytes, QString old_text = _widget.text(); if (old_text == "") { - old_text = ""; + old_text = "
"; } QString new_text = old_text.remove("
") + "" + bytestring + - "" + line + + "" + line.toHtmlEscaped() + "" + "" + ""; _widget.setText(new_text); - _widget.resize(_widget.sizeHint().width(), _widget.sizeHint().height()); width = 12 + _widget.sizeHint().width(); height = 25 + _widget.sizeHint().height(); if (width < 250) width = 250; + _widget.resize(width - 12, height - 25); } -- 2.39.2 From 9252262693432b33dbe4ffc60d79bbdc6fbb5f66 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 8 Jan 2015 18:42:04 +0100 Subject: [PATCH 10/16] Split blocks before finishing function --- src/disassembler/Function.hxx | 10 ++++++++++ src/disassembler/llvm/LLVMDisassembler.cxx | 21 ++++++++++++++------- src/disassembler/llvm/LLVMDisassembler.hxx | 2 +- src/disassembler/llvm/LLVMFunction.hxx | 3 --- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/disassembler/Function.hxx b/src/disassembler/Function.hxx index ccca54c..57833ba 100644 --- a/src/disassembler/Function.hxx +++ b/src/disassembler/Function.hxx @@ -2,6 +2,7 @@ #define INCLUDE__Function_hxx #include "disassembler/BasicBlock.hxx" +#include class Function { public: @@ -17,9 +18,18 @@ public: std::string getName() const { return name; } + + void addBasicBlock(BasicBlock* block) { + _blocks.insert(std::make_pair(block->getStartAddress(), block)); + } + + std::map& blocks() { + return _blocks; + } private: std::string name; uint64_t start_address; + std::map _blocks; }; #endif diff --git a/src/disassembler/llvm/LLVMDisassembler.cxx b/src/disassembler/llvm/LLVMDisassembler.cxx index 79c7a54..c73e703 100644 --- a/src/disassembler/llvm/LLVMDisassembler.cxx +++ b/src/disassembler/llvm/LLVMDisassembler.cxx @@ -138,7 +138,7 @@ Function* LLVMDisassembler::disassembleFunctionAt(uint64_t address, const std::s text_section.getAddress(base_address); text_section.getSize(size); - if (address < base_address || + if (address < base_address || address >= base_address + size) { return NULL; } @@ -174,6 +174,7 @@ void LLVMDisassembler::disassembleFunction(LLVMFunction* function) { LLVMBasicBlock * block = new LLVMBasicBlock(function->getStartAddress(), this); remaining_blocks.push(block); blocks.insert(std::make_pair(block->getStartAddress(), block)); + function->addBasicBlock(block); while (remaining_blocks.size()) { LLVMBasicBlock * current_block = remaining_blocks.top(); @@ -206,6 +207,7 @@ void LLVMDisassembler::disassembleFunction(LLVMFunction* function) { if (blocks.find(jmptarget) == blocks.end()) { LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this); blocks.insert(std::make_pair(block->getStartAddress(), block)); + function->addBasicBlock(block); remaining_blocks.push(block); } if (MIA->isConditionalBranch(inst)) { @@ -214,6 +216,7 @@ void LLVMDisassembler::disassembleFunction(LLVMFunction* function) { if (blocks.find(jmptarget) == blocks.end()) { LLVMBasicBlock * block = new LLVMBasicBlock(jmptarget, this); blocks.insert(std::make_pair(block->getStartAddress(), block)); + function->addBasicBlock(block); remaining_blocks.push(block); } } @@ -234,6 +237,7 @@ void LLVMDisassembler::disassembleFunction(LLVMFunction* function) { current_address += inst_size; } } + splitBlocks(function); LOG4CXX_DEBUG(logger, "Finished function " << function->getName()); manager->signal_new_function(function); } @@ -293,19 +297,19 @@ void LLVMDisassembler::disassemble() { LOG4CXX_INFO(logger, "No Symbols found, starting at the beginning of the text segment"); disassembleFunctionAt(text_entry); } - - splitBlocks(); } -void LLVMDisassembler::splitBlocks() { +void LLVMDisassembler::splitBlocks(LLVMFunction* function) { SectionRef text_section = sections[".text"]; StringRef bytes; text_section.getContents(bytes); StringRefMemoryObject ref(bytes); // Split blocks where jumps are going inside the block - for (auto it = blocks.begin(); it != blocks.end(); ++it) { - LLVMBasicBlock * current_block = it->second; + for (auto it = function->blocks().begin(); + it != function->blocks().end(); + ++it) { + BasicBlock * current_block = it->second; uint64_t inst_size; uint64_t base_address; text_section.getAddress(base_address); @@ -317,8 +321,10 @@ void LLVMDisassembler::splitBlocks() { if(llvm::MCDisassembler::Success == DisAsm->getInstruction(inst, inst_size, ref, current_address, nulls(), nulls())) { + // See if some other block starts here auto other = blocks.find(current_address + inst_size + base_address); + // Special case, other block starts here but we are at the end anyway if (other != blocks.end()) { uint64_t endaddress = current_address + inst_size + base_address; if (endaddress != current_block->getEndAddress()) { @@ -377,7 +383,8 @@ void LLVMDisassembler::forEachFunction(std::function } void LLVMDisassembler::printEachInstruction(uint64_t start, uint64_t end, - std::function fun) { + std::function fun) { SectionRef text_section = sections[".text"]; uint64_t base_address; text_section.getAddress(base_address); diff --git a/src/disassembler/llvm/LLVMDisassembler.hxx b/src/disassembler/llvm/LLVMDisassembler.hxx index 107767d..b0ab082 100644 --- a/src/disassembler/llvm/LLVMDisassembler.hxx +++ b/src/disassembler/llvm/LLVMDisassembler.hxx @@ -41,7 +41,7 @@ protected: private: // http://llvm.org/docs/doxygen/html/MCObjectDisassembler_8cpp_source.html +197 void disassembleFunction(LLVMFunction* function); - void splitBlocks(); + void splitBlocks(LLVMFunction* fun); void disassemble(); void readSymbols(); diff --git a/src/disassembler/llvm/LLVMFunction.hxx b/src/disassembler/llvm/LLVMFunction.hxx index 3bc813a..0bdb1dc 100644 --- a/src/disassembler/llvm/LLVMFunction.hxx +++ b/src/disassembler/llvm/LLVMFunction.hxx @@ -11,6 +11,3 @@ private: }; #endif - - - -- 2.39.2 From affaaf627e18dfd671bdc6e8d77e4838ff93b444 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 8 Jan 2015 18:43:41 +0100 Subject: [PATCH 11/16] More bugs --- BUGS.org | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BUGS.org b/BUGS.org index 17c6a53..b43fa7c 100644 --- a/BUGS.org +++ b/BUGS.org @@ -8,3 +8,8 @@ BasicBlocks are splittet too late these days. As a result we sometimes get BasicBlocks that are suffixes of other BasicBlocks + +* TODO spread out enries + + Add some small gap between inbound edges the currently layout is + slightly confusing -- 2.39.2 From 4ce83d6b47b1410a5356a6bbb11346b857740ce6 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 8 Jan 2015 18:44:54 +0100 Subject: [PATCH 12/16] remove more madness from llvm-config flags --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab55827..3a14e98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ execute_process(COMMAND ${LLVM_CONFIG} --system-libs OUTPUT_VARIABLE LLVM_SYSTEM string(REPLACE -O2 "" LLVM_CFLAGS ${LLVM_CFLAGS}) string(REPLACE -fno-exceptions "" LLVM_CFLAGS ${LLVM_CFLAGS}) +string(REPLACE -fno-rtti "" LLVM_CFLAGS ${LLVM_CFLAGS}) separate_arguments(LLVM_CFLAGS) add_definitions(${LLVM_CFLAGS}) -- 2.39.2 From 119d1aff7df9c3235177c3bf55bd618feb3c1519 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 8 Jan 2015 18:45:43 +0100 Subject: [PATCH 13/16] formating improvements --- src/gui/Mainwindow.cxx | 16 +++++++++++----- src/gui/widgets/BasicBlockWidget.hxx | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 34dcfb1..5643beb 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -23,9 +23,11 @@ Mainwindow::Mainwindow(InformationManager* mgr) // saveAction = new QAction(tr("&Save"), this); exitAction = new QAction(tr("E&xit"), this); - connect(openAction, SIGNAL(triggered()), this, SLOT(open())); + connect(openAction, SIGNAL(triggered()), + this, SLOT(open())); // connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(exitAction, SIGNAL(triggered()), + qApp, SLOT(quit())); fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(openAction); @@ -86,7 +88,8 @@ void Mainwindow::addFunction(Function* fun) { Disassembler * dis = manager->getDisassembler(); BasicBlock * block = dis->getBasicBlock(fun->getStartAddress()); - local__add_basic_block(block, manager->getDisassembler(), blocks, scene, block->getStartAddress(), 100); + local__add_basic_block(block, manager->getDisassembler(), blocks, scene, + block->getStartAddress(), 100); QGraphicsView * view = new QGraphicsView(scene); w->addTab(view, "CFG"); @@ -123,8 +126,11 @@ namespace { widget->setFlag(QGraphicsItem::ItemIsMovable, true); widget->moveBy(100*startx, block->getStartAddress() - starty); - dis->printEachInstruction(block->getStartAddress(), block->getEndAddress(), - [&](uint8_t* bytes, size_t byte_count, const std::string& line) { + dis->printEachInstruction(block->getStartAddress(), + block->getEndAddress(), + [&](uint8_t* bytes, + size_t byte_count, + const std::string& line) { widget->addItem(bytes, byte_count, line.c_str() + 1); }); diff --git a/src/gui/widgets/BasicBlockWidget.hxx b/src/gui/widgets/BasicBlockWidget.hxx index 8aa182f..8c86667 100644 --- a/src/gui/widgets/BasicBlockWidget.hxx +++ b/src/gui/widgets/BasicBlockWidget.hxx @@ -32,9 +32,9 @@ public: } std::array getExits() const { - return { { mapToScene(QPointF( width/3, height)), - mapToScene(QPointF( width/2, height)), - mapToScene(QPointF(2*width/3, height)) } }; + return { { mapToScene(QPointF( width/3, height)), + mapToScene(QPointF( width/2, height)), + mapToScene(QPointF(2*width/3, height)) } }; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, -- 2.39.2 From f6f7e517e577a67f01256ca0b0edea83729849f4 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Sat, 10 Jan 2015 17:43:04 +0100 Subject: [PATCH 14/16] Fix layout if functions include blocks before entry If a function contained a block with a lower address than it's entry a integer overflow occured resulting in bad layout. Handled now correctly. --- src/gui/Mainwindow.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 5643beb..196db38 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -88,8 +88,14 @@ void Mainwindow::addFunction(Function* fun) { Disassembler * dis = manager->getDisassembler(); BasicBlock * block = dis->getBasicBlock(fun->getStartAddress()); + uint64_t start_address(std::numeric_limits::max()); + for (auto b : fun->blocks()) { + if (b.first < start_address) + start_address = b.first; + } + local__add_basic_block(block, manager->getDisassembler(), blocks, scene, - block->getStartAddress(), 100); + start_address, 100); QGraphicsView * view = new QGraphicsView(scene); w->addTab(view, "CFG"); -- 2.39.2 From 753a5d402674d4465c86f01ca7ff9ede53377964 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Sat, 10 Jan 2015 17:43:23 +0100 Subject: [PATCH 15/16] Make name accessible in BasicBlockWidgets --- src/gui/widgets/BasicBlockWidget.hxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/widgets/BasicBlockWidget.hxx b/src/gui/widgets/BasicBlockWidget.hxx index 8c86667..9b2df93 100644 --- a/src/gui/widgets/BasicBlockWidget.hxx +++ b/src/gui/widgets/BasicBlockWidget.hxx @@ -58,6 +58,9 @@ public: return next; } + QString getName() const { + return name; + } private: uint32_t width, height; QGraphicsProxyWidget _proxy; -- 2.39.2 From 74555b2a9a524c568772bcea1332019a911bf86f Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Sat, 10 Jan 2015 17:44:12 +0100 Subject: [PATCH 16/16] Add logging infrastructure for mainwindow --- src/gui/Mainwindow.cxx | 3 ++- src/gui/Mainwindow.hxx | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 196db38..9f1d353 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -18,7 +18,8 @@ namespace { } Mainwindow::Mainwindow(InformationManager* mgr) - : manager(mgr) { + : manager(mgr) + , logger(log4cxx::Logger::getLogger("Mainwindow")) { openAction = new QAction(tr("&Open"), this); // saveAction = new QAction(tr("&Save"), this); exitAction = new QAction(tr("E&xit"), this); diff --git a/src/gui/Mainwindow.hxx b/src/gui/Mainwindow.hxx index 40fa81d..bb2a90e 100644 --- a/src/gui/Mainwindow.hxx +++ b/src/gui/Mainwindow.hxx @@ -4,12 +4,15 @@ #include #include #include + #include #include #include #include #include +#include + #include "disassembler/Disassembler.hxx" #include "widgets/BasicBlockWidget.hxx" #include "widgets/ScriptingDock.hxx" @@ -38,6 +41,8 @@ private: std::map blocks; std::set functions; InformationManager* manager; + + log4cxx::LoggerPtr logger; private Q_SLOTS: void quit(); void open(); -- 2.39.2