]> git.siccegge.de Git - frida/frida.git/commitdiff
Properly fail if no appropriate Disassembler can be constructed
authorChristoph Egger <Christoph.Egger@fau.de>
Thu, 26 Mar 2015 16:45:34 +0000 (17:45 +0100)
committerChristoph Egger <Christoph.Egger@fau.de>
Thu, 26 Mar 2015 16:45:34 +0000 (17:45 +0100)
Currently, for mipsel there is no InstructionAnalysis available for some
reason. frida gives now a errormessage and survives instead of just
segfaulting

src/core/Exception.hxx [new file with mode: 0644]
src/disassembler/llvm/LLVMDisassembler.cxx

diff --git a/src/core/Exception.hxx b/src/core/Exception.hxx
new file mode 100644 (file)
index 0000000..d1b0e67
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef INCLUDE__Exception_hxx_
+#define INCLUDE__Exception_hxx_
+
+#include <string>
+
+class Exception {
+public:
+       Exception () {}
+       // Exception (const Exception&) noexcept;
+       // exception& operator= (const exception&) noexcept;
+       virtual ~Exception() {}
+       virtual const char* what() const noexcept = 0;
+};
+
+class BinaryNotSupported {
+public:
+       BinaryNotSupported()
+               : message("This binary is not supported by this Disassembler") {}
+       BinaryNotSupported(const std::string& message)
+               : message("This binary is not supported by this Disassembler (" + message + ")") {}
+       const char* what() const {return message.c_str();}
+
+private:
+       std::string message;
+};             
+       
+#endif /* INCLUDE__Exception_hxx_ */
index e673c371650027021455b63f64b94e422dcc7a5d..66605d31bec388e64ef4ce97effeb8aa14feb089 100644 (file)
@@ -3,6 +3,7 @@
 #include "core/InformationManager.hxx"
 #include "core/Function.hxx"
 #include "core/BasicBlock.hxx"
+#include "core/Exception.hxx"
 #include <boost/algorithm/string.hpp>
 
 #include <stack>
@@ -47,26 +48,29 @@ Disassembler * createLLVMDisassembler(const std::string& filename, InformationMa
        foo.second.release();
 #endif
 
-       // ELFType<endian, maxalign, 64bit>
-       if (ELF32LEObjectFile * object = dyn_cast<ELF32LEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::little, 2, false>>(filename, manager, object);
-       }
-       if (ELF64LEObjectFile * object = dyn_cast<ELF64LEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::little, 2, true>>(filename, manager, object);
-       }
-       if (ELF32BEObjectFile * object = dyn_cast<ELF32BEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::big, 2, false>>(filename, manager, object);
-       }
-       if (ELF64BEObjectFile * object = dyn_cast<ELF64BEObjectFile>(op)) {
-               return new LLVMDisassembler<ELFType<support::big, 2, true>>(filename, manager, object);
-       }
-       if (COFFObjectFile * object = dyn_cast<COFFObjectFile>(op)) {
-               return new LLVMDisassembler<COFFT>(filename, manager, object);
-       }
-       if (MachOObjectFile * object = dyn_cast<MachOObjectFile>(op)) {
-               return new LLVMDisassembler<MACHOT>(filename, manager, object);
+       try {
+               // ELFType<endian, maxalign, 64bit>
+               if (ELF32LEObjectFile * object = dyn_cast<ELF32LEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::little, 2, false>>(filename, manager, object);
+               }
+               if (ELF64LEObjectFile * object = dyn_cast<ELF64LEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::little, 2, true>>(filename, manager, object);
+               }
+               if (ELF32BEObjectFile * object = dyn_cast<ELF32BEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::big, 2, false>>(filename, manager, object);
+               }
+               if (ELF64BEObjectFile * object = dyn_cast<ELF64BEObjectFile>(op)) {
+                       return new LLVMDisassembler<ELFType<support::big, 2, true>>(filename, manager, object);
+               }
+               if (COFFObjectFile * object = dyn_cast<COFFObjectFile>(op)) {
+                       return new LLVMDisassembler<COFFT>(filename, manager, object);
+               }
+               if (MachOObjectFile * object = dyn_cast<MachOObjectFile>(op)) {
+                       return new LLVMDisassembler<MACHOT>(filename, manager, object);
+               }
+       } catch (BinaryNotSupported& e) {
+               return NULL;
        }
-
        return NULL;
 }
 
@@ -122,7 +126,8 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        target = TargetRegistry::lookupTarget("", triple, es);
        if (!target) {
                LOG4CXX_ERROR(logger, es);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        LOG4CXX_INFO(logger, "Target " << target->getName());
@@ -130,26 +135,30 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        MRI.reset(target->createMCRegInfo(tripleName));
        if (!MRI) {
                LOG4CXX_ERROR(logger, "no register info for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        // Set up disassembler.
        AsmInfo.reset(target->createMCAsmInfo(*MRI, tripleName));
        if (!AsmInfo) {
                LOG4CXX_ERROR(logger, "no assembly info for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        STI.reset(target->createMCSubtargetInfo(tripleName, "", ""));
        if (!STI) {
                LOG4CXX_ERROR(logger, "no subtarget info for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        MII.reset(target->createMCInstrInfo());
        if (!MII) {
                LOG4CXX_ERROR(logger, "no instruction info for target " << tripleName);
-               return;
+                               BinaryNotSupported e;
+               throw e;
        }
 
        MOFI.reset(new MCObjectFileInfo);
@@ -158,7 +167,8 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        DisAsm.reset(target->createMCDisassembler(*STI, Ctx));
        if (!DisAsm) {
                LOG4CXX_ERROR(logger, "no disassembler for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
        RelInfo.reset(
                target->createMCRelocationInfo(tripleName, Ctx));
@@ -174,14 +184,16 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
        MIA.reset(target->createMCInstrAnalysis(MII.get()));
        if (!MIA) {
                LOG4CXX_ERROR(logger, "no instruction analysis for target " << tripleName);
-               return;
+               BinaryNotSupported e;
+               throw e;
        }
 
        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;
+               BinaryNotSupported e;
+               throw e;
        }
 
        IP->setPrintImmHex(llvm::HexStyle::C);