Factor out llvm disassembler
authorChristoph Egger <siccegge@cs.fau.de>
Tue, 20 May 2014 12:23:33 +0000 (14:23 +0200)
committerChristoph Egger <siccegge@cs.fau.de>
Tue, 20 May 2014 12:23:33 +0000 (14:23 +0200)
21 files changed:
CMakeLists.txt
src/disassembler.old/BasicBlock.hxx [new file with mode: 0644]
src/disassembler.old/Disassembler.cxx [new file with mode: 0644]
src/disassembler.old/Disassembler.hxx [new file with mode: 0644]
src/disassembler.old/Instruction.hxx [new file with mode: 0644]
src/disassembler.old/InstructionReader.cxx [new file with mode: 0644]
src/disassembler.old/InstructionReader.hxx [new file with mode: 0644]
src/disassembler.old/Target.cxx [new file with mode: 0644]
src/disassembler.old/Target.hxx [new file with mode: 0644]
src/disassembler/BasicBlock.hxx [deleted file]
src/disassembler/Disassembler.cxx
src/disassembler/Disassembler.hxx
src/disassembler/Instruction.hxx [deleted file]
src/disassembler/InstructionReader.cxx [deleted file]
src/disassembler/InstructionReader.hxx [deleted file]
src/disassembler/Target.cxx [deleted file]
src/disassembler/Target.hxx [deleted file]
src/disassembler/llvm/LLVMDisassembler.cxx [new file with mode: 0644]
src/disassembler/llvm/LLVMDisassembler.hxx [new file with mode: 0644]
src/gui/Mainwindow.cxx
src/gui/Mainwindow.hxx

index fe8e1a3e262e48a111d36e90652339a8a93d3769..2d9ccbf5a16d0d7a218c857913bacb9df1790591 100644 (file)
@@ -28,19 +28,20 @@ separate_arguments(LLVM_LIBS)
 set(CMAKE_CXX_COMPILER "clang++")
 
 SET(frida_SOURCES
-  src/Binary.cxx
   src/main.cxx
   src/gui/Mainwindow.cxx
   src/gui/widgets/BasicBlockWidget.cxx
-  src/disassembler/InstructionReader.cxx
-  src/disassembler/Target.cxx
-  src/disassembler/Disassembler.cxx)
+  src/disassembler/Disassembler.cxx
+  src/disassembler/llvm/LLVMDisassembler.cxx
+  )
 SET(frida_HEADERS
-  src/Binary.hxx
   src/include_llvm.hxx
-  src/Section.hxx
+  src/gui/qt.hxx
   src/gui/Mainwindow.hxx
-  src/gui/widgets/BasicBlockWidget.hxx)
+  src/gui/widgets/BasicBlockWidget.hxx
+  src/disassembler/llvm/LLVMDisassembler.hxx
+  src/disassembler/Disassembler.hxx
+  )
 
 ADD_EXECUTABLE(frida ${frida_SOURCES} ${frida_HEADERS_MOC})
 #ADD_LIBRARY(llvm SHARED )
diff --git a/src/disassembler.old/BasicBlock.hxx b/src/disassembler.old/BasicBlock.hxx
new file mode 100644 (file)
index 0000000..22a31e0
--- /dev/null
@@ -0,0 +1,8 @@
+
+
+class BasicBlock {
+public:
+
+private:
+
+};
diff --git a/src/disassembler.old/Disassembler.cxx b/src/disassembler.old/Disassembler.cxx
new file mode 100644 (file)
index 0000000..7422df5
--- /dev/null
@@ -0,0 +1,12 @@
+#include "Disassembler.hxx"
+
+using namespace llvm;
+using namespace llvm::object;
+
+Disassembler::Disassembler(const std::string& filename) 
+       : _binary(createBinary(filename).get())
+       , _target(_binary)
+{
+    
+}
+
diff --git a/src/disassembler.old/Disassembler.hxx b/src/disassembler.old/Disassembler.hxx
new file mode 100644 (file)
index 0000000..3effa25
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef INCLUDE__Disassembler_hxx
+#define INCLUDE__Disassembler_hxx
+
+#include "Target.hxx"
+#include "include_llvm.hxx"
+
+class Disassembler {
+public:
+    Disassembler(const std::string& filename);
+private:
+    llvm::object::Binary* _binary;
+    Target _target;
+};
+
+#endif
diff --git a/src/disassembler.old/Instruction.hxx b/src/disassembler.old/Instruction.hxx
new file mode 100644 (file)
index 0000000..afb5193
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+class Instruction {
+public:
+private:
+};
diff --git a/src/disassembler.old/InstructionReader.cxx b/src/disassembler.old/InstructionReader.cxx
new file mode 100644 (file)
index 0000000..8f8df91
--- /dev/null
@@ -0,0 +1,27 @@
+#include "InstructionReader.hxx"
+
+InstructionReader::InstructionReader(const Target& target)
+    : _logger(log4cxx::Logger::getLogger("disassembler.Target"))
+    , _target(target)
+{
+    DisAsm.reset(_target.getTarget().createMCDisassembler(_target.getSubTargetInfo()));
+    if (!DisAsm) {
+        LOG4CXX_ERROR(_logger, "error: no disassembler for target " << _target.getTripleName())
+            return;
+    }
+}
+
+void InstructionReader::readInstruction(std::string& data, size_t& offset, Instruction& inst) {
+    llvm::MCInst instr;
+    llvm::StringRefMemoryObject memoryObject(data);
+    uint64_t size;
+    
+    if (DisAsm->getInstruction(instr, size, memoryObject, offset,
+                               llvm::nulls(), llvm::nulls())) {
+        
+    } else {
+        LOG4CXX_WARN(_logger, "warning: invalid instruction encoding");
+        if (size == 0)
+            size = 1; // skip illegible bytes
+    }
+}
diff --git a/src/disassembler.old/InstructionReader.hxx b/src/disassembler.old/InstructionReader.hxx
new file mode 100644 (file)
index 0000000..092e73c
--- /dev/null
@@ -0,0 +1,18 @@
+#include "include_llvm.hxx"
+#include "Instruction.hxx"
+#include "Target.hxx"
+
+#include <string>
+
+#include <log4cxx/logger.h>
+
+
+class InstructionReader {
+public:
+    InstructionReader(const Target& target);
+    void readInstruction(std::string& data, size_t& offset, Instruction& inst);
+private:
+    log4cxx::LoggerPtr _logger;
+    const Target& _target;
+    llvm::OwningPtr<llvm::MCDisassembler> DisAsm;
+};
diff --git a/src/disassembler.old/Target.cxx b/src/disassembler.old/Target.cxx
new file mode 100644 (file)
index 0000000..79d590a
--- /dev/null
@@ -0,0 +1,28 @@
+#include "Target.hxx"
+
+#include <string>
+
+Target::Target(llvm::object::Binary* binary)
+    : _logger(log4cxx::Logger::getLogger("disassembler.Target"))
+    , triple("unknown-unknown-unknown")
+{
+    std::string error;
+    llvm::object::ObjectFile * o = llvm::dyn_cast<llvm::object::ObjectFile>(binary);
+
+    triple.setArch(llvm::Triple::ArchType(o->getArch()));
+    std::string tripleName(triple.getTriple());
+    LOG4CXX_INFO(_logger, "Detected triple " << tripleName);
+
+    target = llvm::TargetRegistry::lookupTarget("", triple, error);
+    if (!target) {
+        LOG4CXX_ERROR(_logger, "Couldn't create Target: " << error);
+        return;
+    }
+    LOG4CXX_INFO(_logger, "Target: " << target->getName());
+
+    STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
+    if (!STI) {
+        LOG4CXX_ERROR(_logger, "No subtarget for target " << tripleName);
+        return;
+    }
+}
diff --git a/src/disassembler.old/Target.hxx b/src/disassembler.old/Target.hxx
new file mode 100644 (file)
index 0000000..f72af7c
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef INCLUDE__Target_hxx
+#define INCLUDE__Target_hxx
+
+#include <log4cxx/logger.h>
+
+#include "include_llvm.hxx"
+
+class Target {
+public:
+    Target(llvm::object::Binary* binary);
+
+    const llvm::Target& getTarget() const {
+        return *target;
+    }
+
+    const llvm::MCSubtargetInfo& getSubTargetInfo() const {
+        return *STI;
+    }
+
+    std::string getTripleName() const {
+        return triple.getTriple();
+    }
+private:
+    log4cxx::LoggerPtr _logger;
+    llvm::Triple triple;
+
+    const llvm::Target * target;
+    llvm::OwningPtr<const llvm::MCSubtargetInfo> STI;
+};
+
+#endif
diff --git a/src/disassembler/BasicBlock.hxx b/src/disassembler/BasicBlock.hxx
deleted file mode 100644 (file)
index 22a31e0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-class BasicBlock {
-public:
-
-private:
-
-};
index 7422df561784966652b8f7e69ebb276019f2e0ea..968ebe2522bb765d958dc55346dcb74ecde690c5 100644 (file)
@@ -1,12 +1,3 @@
-#include "Disassembler.hxx"
+#include "disassembler/Disassembler.hxx"
 
-using namespace llvm;
-using namespace llvm::object;
-
-Disassembler::Disassembler(const std::string& filename) 
-       : _binary(createBinary(filename).get())
-       , _target(_binary)
-{
-    
-}
 
index 3effa2586aa70a7505df5b497ac2acd1f666c5c7..9986ac8e3a0fd4f61f94c25b3da364b36d1a901b 100644 (file)
@@ -1,15 +1,28 @@
 #ifndef INCLUDE__Disassembler_hxx
 #define INCLUDE__Disassembler_hxx
 
-#include "Target.hxx"
-#include "include_llvm.hxx"
+#include <string>
+#include <functional>
+
+class BasicBlock {};
 
 class Disassembler {
 public:
-    Disassembler(const std::string& filename);
-private:
-    llvm::object::Binary* _binary;
-    Target _target;
+       Disassembler(const std::string& filename) {}
+    virtual ~Disassembler() {}
+
+       void getSymbols();
+       uint64_t entryAddress();
+
+    virtual void forEachInstruction(const std::string& name, std::function<void (long, std::string, std::string)> callback) = 0;
+
+    // http://llvm.org/docs/doxygen/html/MCObjectDisassembler_8cpp_source.html +197
+       BasicBlock * generateControlFlowGraph(const std::string& name);
+       BasicBlock * generateControlFlowGraph(uint64_t address);
+
+protected:
+    virtual bool isFunctionCall(uint64_t address) = 0;
+    virtual bool isJump(uint64_t address) = 0;
 };
 
 #endif
diff --git a/src/disassembler/Instruction.hxx b/src/disassembler/Instruction.hxx
deleted file mode 100644 (file)
index afb5193..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-class Instruction {
-public:
-private:
-};
diff --git a/src/disassembler/InstructionReader.cxx b/src/disassembler/InstructionReader.cxx
deleted file mode 100644 (file)
index 8f8df91..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "InstructionReader.hxx"
-
-InstructionReader::InstructionReader(const Target& target)
-    : _logger(log4cxx::Logger::getLogger("disassembler.Target"))
-    , _target(target)
-{
-    DisAsm.reset(_target.getTarget().createMCDisassembler(_target.getSubTargetInfo()));
-    if (!DisAsm) {
-        LOG4CXX_ERROR(_logger, "error: no disassembler for target " << _target.getTripleName())
-            return;
-    }
-}
-
-void InstructionReader::readInstruction(std::string& data, size_t& offset, Instruction& inst) {
-    llvm::MCInst instr;
-    llvm::StringRefMemoryObject memoryObject(data);
-    uint64_t size;
-    
-    if (DisAsm->getInstruction(instr, size, memoryObject, offset,
-                               llvm::nulls(), llvm::nulls())) {
-        
-    } else {
-        LOG4CXX_WARN(_logger, "warning: invalid instruction encoding");
-        if (size == 0)
-            size = 1; // skip illegible bytes
-    }
-}
diff --git a/src/disassembler/InstructionReader.hxx b/src/disassembler/InstructionReader.hxx
deleted file mode 100644 (file)
index 092e73c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "include_llvm.hxx"
-#include "Instruction.hxx"
-#include "Target.hxx"
-
-#include <string>
-
-#include <log4cxx/logger.h>
-
-
-class InstructionReader {
-public:
-    InstructionReader(const Target& target);
-    void readInstruction(std::string& data, size_t& offset, Instruction& inst);
-private:
-    log4cxx::LoggerPtr _logger;
-    const Target& _target;
-    llvm::OwningPtr<llvm::MCDisassembler> DisAsm;
-};
diff --git a/src/disassembler/Target.cxx b/src/disassembler/Target.cxx
deleted file mode 100644 (file)
index 79d590a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "Target.hxx"
-
-#include <string>
-
-Target::Target(llvm::object::Binary* binary)
-    : _logger(log4cxx::Logger::getLogger("disassembler.Target"))
-    , triple("unknown-unknown-unknown")
-{
-    std::string error;
-    llvm::object::ObjectFile * o = llvm::dyn_cast<llvm::object::ObjectFile>(binary);
-
-    triple.setArch(llvm::Triple::ArchType(o->getArch()));
-    std::string tripleName(triple.getTriple());
-    LOG4CXX_INFO(_logger, "Detected triple " << tripleName);
-
-    target = llvm::TargetRegistry::lookupTarget("", triple, error);
-    if (!target) {
-        LOG4CXX_ERROR(_logger, "Couldn't create Target: " << error);
-        return;
-    }
-    LOG4CXX_INFO(_logger, "Target: " << target->getName());
-
-    STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
-    if (!STI) {
-        LOG4CXX_ERROR(_logger, "No subtarget for target " << tripleName);
-        return;
-    }
-}
diff --git a/src/disassembler/Target.hxx b/src/disassembler/Target.hxx
deleted file mode 100644 (file)
index f72af7c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef INCLUDE__Target_hxx
-#define INCLUDE__Target_hxx
-
-#include <log4cxx/logger.h>
-
-#include "include_llvm.hxx"
-
-class Target {
-public:
-    Target(llvm::object::Binary* binary);
-
-    const llvm::Target& getTarget() const {
-        return *target;
-    }
-
-    const llvm::MCSubtargetInfo& getSubTargetInfo() const {
-        return *STI;
-    }
-
-    std::string getTripleName() const {
-        return triple.getTriple();
-    }
-private:
-    log4cxx::LoggerPtr _logger;
-    llvm::Triple triple;
-
-    const llvm::Target * target;
-    llvm::OwningPtr<const llvm::MCSubtargetInfo> STI;
-};
-
-#endif
diff --git a/src/disassembler/llvm/LLVMDisassembler.cxx b/src/disassembler/llvm/LLVMDisassembler.cxx
new file mode 100644 (file)
index 0000000..881c662
--- /dev/null
@@ -0,0 +1,100 @@
+#include "disassembler/llvm/LLVMDisassembler.hxx"
+
+using namespace llvm;
+using namespace llvm::object;
+
+/*
+ * TODO: fallback code falls die Datei kein ELF/PE/COFF/MacO/.. binary
+ * ist sondern z.B. einfach nur Instruktionen oder ein Bootsektor oder
+ * foo
+ */
+
+LLVMDisassembler::LLVMDisassembler(const std::string& filename)
+    : Disassembler(filename)
+    , logger(log4cxx::Logger::getLogger("LLVMDisassembler"))
+    , triple("unknown-unknown-unknown")
+{
+    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<ObjectFile>(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;
+    }
+
+    DisAsm.reset(target->createMCDisassembler(*STI));
+    if (!DisAsm) {
+        LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName);
+        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) {
+        LOG4CXX_ERROR(logger, "no instruction printer for target " << tripleName);
+        return;
+    }
+
+    OwningPtr<MCObjectDisassembler> OD(
+        new MCObjectDisassembler(*o, *DisAsm, *MIA));
+    Mod.reset(OD->buildModule(false));
+}
diff --git a/src/disassembler/llvm/LLVMDisassembler.hxx b/src/disassembler/llvm/LLVMDisassembler.hxx
new file mode 100644 (file)
index 0000000..ff81be5
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef INCLUDE__LLVMDisassembler_hxx
+#define INCLUDE__LLVMDisassembler_hxx
+
+#include <memory>
+#include <log4cxx/logger.h>
+
+#include "include_llvm.hxx"
+
+#include "disassembler/Disassembler.hxx"
+
+
+class LLVMDisassembler
+    : public Disassembler {
+public:
+    LLVMDisassembler(const std::string& filename);
+    virtual ~LLVMDisassembler() {};
+
+       void getSymbols();
+       uint64_t entryAddress();
+
+    void forEachInstruction(const std::string& name, std::function<void (long, std::string, std::string)> callback) {}
+
+       BasicBlock * generateControlFlowGraph(const std::string& name);
+       BasicBlock * generateControlFlowGraph(uint64_t address);
+
+protected:
+    bool isFunctionCall(uint64_t address) {return false;}
+    bool isJump(uint64_t address) {return false;}
+
+private:
+    log4cxx::LoggerPtr logger;
+
+    llvm::Triple triple;
+    std::shared_ptr<llvm::object::Binary> binary;
+
+
+    const llvm::Target * target;
+    llvm::object::ObjectFile * o;
+
+    std::unique_ptr<const llvm::MCRegisterInfo> MRI;
+    std::unique_ptr<const llvm::MCAsmInfo> AsmInfo;
+    std::unique_ptr<llvm::MCModule> Mod;
+    std::unique_ptr<llvm::MCInstPrinter> IP;
+    std::unique_ptr<llvm::MCDisassembler> DisAsm;
+    std::unique_ptr<const llvm::MCObjectFileInfo> MOFI;
+    std::unique_ptr<llvm::MCContext> Ctx;
+    std::unique_ptr<const llvm::MCInstrAnalysis> MIA;
+    std::unique_ptr<const llvm::MCSubtargetInfo> STI;
+    std::unique_ptr<const llvm::MCInstrInfo> MII;
+       llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo;
+       llvm::OwningPtr<llvm::MCSymbolizer> Symzer;
+
+    std::map<std::string, llvm::object::SectionRef> sections;
+    std::map<std::string, llvm::object::SymbolRef> symbols;
+};
+
+#endif
index be86cac4477c13db986082e9b78081207e7f23dc..061734a5bc946dde58082641543aed5ec24d6c0c 100644 (file)
@@ -1,6 +1,7 @@
-#include "Mainwindow.hxx"
+ #include "Mainwindow.hxx"
 #include "widgets/BasicBlockWidget.hxx"
 #include "qt.hxx"
+#include "disassembler/llvm/LLVMDisassembler.hxx"
 
 #include <iostream>
 #include <sstream>
@@ -54,14 +55,15 @@ void Mainwindow::open() {
                                                     tr("Binaries (*)"));
 
     if (fileName != "") {
-        curBin = new qtlldb::Binary(fileName.toStdString());
-
-        std::vector<std::string> symbols = curBin->getSymbols();
-        if (0 == symbols.size())
-            populateSymbolInformation(".text");
-        for (auto it = symbols.begin(); it != symbols.end(); ++it) {
-            populateSymbolInformation(*it);
-        }
+        disassembler.reset(new LLVMDisassembler(fileName.toStdString()));
+        // curBin = new Binary(fileName.toStdString());
+
+        // std::vector<std::string> symbols = curBin->getSymbols();
+        // if (0 == symbols.size())
+        //     populateSymbolInformation(".text");
+        // for (auto it = symbols.begin(); it != symbols.end(); ++it) {
+        //     populateSymbolInformation(*it);
+        // }
     }
 }
 
@@ -72,18 +74,18 @@ void Mainwindow::populateSymbolInformation(const std::string& sym) {
     QTableWidget * t = new QTableWidget();
     t->setColumnCount(3);
     t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
-    curBin->for_each_instruction(sym, [&t](long add, std::string bytes, std::string mnemonic) {
-            int row = t->rowCount();
-            std::stringstream s;
-            t->setRowCount(t->rowCount() + 1);
-            s << std::hex << add;
-            t->setItem(row,0,new QTableWidgetItem(s.str().c_str()));
-            s.str("");
-            s << std::hex;
-            for_each(bytes.begin(), bytes.end(), [&s](char c){s << (unsigned int)((unsigned char)c) << ' ';});
-            t->setItem(row,1,new QTableWidgetItem(s.str().c_str()));
-            t->setItem(row,2,new QTableWidgetItem(mnemonic.c_str() + 1));
-        });
+    // curBin->for_each_instruction(sym, [&t](long add, std::string bytes, std::string mnemonic) {
+    //         int row = t->rowCount();
+    //         std::stringstream s;
+    //         t->setRowCount(t->rowCount() + 1);
+    //         s << std::hex << add;
+    //         t->setItem(row,0,new QTableWidgetItem(s.str().c_str()));
+    //         s.str("");
+    //         s << std::hex;
+    //         for_each(bytes.begin(), bytes.end(), [&s](char c){s << (unsigned int)((unsigned char)c) << ' ';});
+    //         t->setItem(row,1,new QTableWidgetItem(s.str().c_str()));
+    //         t->setItem(row,2,new QTableWidgetItem(mnemonic.c_str() + 1));
+    //     });
     w->addTab(t, "Listing");
 
     // CFG
index 34abc3a16a72e2f97da83a77871380f2fef7bd78..adfe71e47a3fc0803b23245bca3498e95dc8cc5b 100644 (file)
@@ -1,10 +1,11 @@
+#include <memory>
 #include <QTextEdit>
 #include <QPushButton>
 #include <QMainWindow>
 #include <QListWidget>
 #include <QStackedWidget>
 
-#include "Binary.hxx"
+#include "disassembler/Disassembler.hxx"
 
 class Mainwindow : public QMainWindow {
     Q_OBJECT
@@ -25,7 +26,7 @@ private:
     QAction *exitAction;
     QAction *openAction;
 
-    qtlldb::Binary * curBin;
+    std::shared_ptr<Disassembler> disassembler;
 private slots:
     void quit();
     void open();