]> git.siccegge.de Git - frida/frida.git/blobdiff - src/disassembler/llvm/LLVMDisassembler.cxx
Disable buildModule
[frida/frida.git] / src / disassembler / llvm / LLVMDisassembler.cxx
index 58d122ab4d51472715c5288c99e7e846080f429a..45cd04e25566d97f830df05be7a00f42ffbe29a8 100644 (file)
@@ -1,7 +1,9 @@
+#include "disassembler/Instruction.hxx"
 #include "disassembler/llvm/LLVMDisassembler.hxx"
 #include "core/InformationManager.hxx"
 #include "core/Function.hxx"
 #include "core/BasicBlock.hxx"
+#include <boost/algorithm/string.hpp>
 
 #include <stack>
 #include <algorithm>
@@ -25,12 +27,22 @@ namespace {
  *
  */
 Disassembler * createLLVMDisassembler(const std::string& filename, InformationManager* manager) {
+       log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("disassembler.LLVMDisassembler"));
        if (filename == "")
                return NULL;
 
-       std::unique_ptr<Binary> o;
-       o.reset(createBinary(filename).get());
-       Binary * op = o.release();
+       auto retval = createBinary(filename);
+       if (error_code ec = retval.getError()) {
+               LOG4CXX_ERROR(logger, ec.message());
+               return NULL;
+       }
+
+       Binary * op = retval.get();
+
+       if (!op) {
+               LOG4CXX_ERROR(logger, "Could not open " << filename);
+               return NULL;
+       }
 
        // ELFType<endian, maxalign, 64bit>
        if (ELF32LEObjectFile * object = dyn_cast<ELF32LEObjectFile>(op)) {
@@ -166,7 +178,7 @@ LLVMDisassembler<ELFT>::LLVMDisassembler(const std::string& filename,
 
        std::unique_ptr<MCObjectDisassembler> OD(
                new MCObjectDisassembler(*o, *DisAsm, *MIA));
-       Mod.reset(OD->buildModule(false));
+       //Mod.reset(OD->buildModule(false));
 
        readSections();
 }
@@ -524,6 +536,60 @@ void LLVMDisassembler<ELFT>::readSections() {
 //     //               });
 // }
 
+template <typename ELFT>
+std::vector<Instruction> LLVMDisassembler<ELFT>::getInstructions(const BasicBlock *block) {
+       std::vector<Instruction> result;
+       SectionRef text_section = getTextSection();
+       uint64_t base_address;
+       text_section.getAddress(base_address);
+       uint64_t current_address = block->getStartAddress() - base_address;
+       uint64_t end_position = block->getEndAddress() - base_address;
+
+       StringRef bytes;
+       text_section.getContents(bytes);
+       StringRefMemoryObject ref(bytes);
+
+       while (current_address < end_position) {
+               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())) {
+
+                       uint8_t bytes[inst_size+2];
+                       ref.readBytes(current_address, inst_size, bytes);
+
+                       uint64_t jmptarget;
+                       std::string ref("");
+                       IP->printInst(&inst, s, "");
+                       if (MIA->evaluateBranch(inst, current_address, inst_size, jmptarget)) {
+                               std::stringstream stream;
+                               if (MIA->isCall(inst))
+                                       stream << "function:";
+                               else
+                                       stream << "block:";
+
+                               stream << std::hex << (base_address + jmptarget);
+                               ref = stream.str();
+                       }
+                       result.push_back(Instruction(current_address + base_address, boost::algorithm::trim_copy(s.str()),
+                                                    std::vector<uint8_t>(bytes, bytes+inst_size), ref));
+               } else {
+                       LOG4CXX_WARN(logger, "Invalid byte at" << std::hex << current_address + base_address);
+                       uint8_t bytes[1];
+                       ref.readBytes(current_address, 1, bytes);
+                       result.push_back(Instruction(current_address + base_address, "Invalid Instruction",
+                                                    std::vector<uint8_t>(bytes, bytes+1), ""));
+                       inst_size = 1;
+               }
+
+               current_address += inst_size;
+       }
+       return result;
+}
+
 template <typename ELFT>
 void LLVMDisassembler<ELFT>::printEachInstruction(uint64_t start, uint64_t end,
                                                   std::function<void (uint8_t*, size_t,