]>
git.siccegge.de Git - frida/frida.git/blob - src/disassembler/llvm/LLVMDisassembler.cxx
1 #include "disassembler/llvm/LLVMDisassembler.hxx"
2 #include "disassembler/llvm/LLVMBasicBlock.hxx"
3 #include "disassembler/llvm/LLVMFunction.hxx"
9 using namespace llvm::object
;
12 * TODO: fallback code falls die Datei kein ELF/PE/COFF/MacO/.. binary
13 * ist sondern z.B. einfach nur Instruktionen oder ein Bootsektor oder
17 LLVMDisassembler::LLVMDisassembler(const std::string
& filename
)
18 : Disassembler(filename
)
19 , logger(log4cxx::Logger::getLogger("LLVMDisassembler"))
20 , triple("unknown-unknown-unknown")
22 LOG4CXX_DEBUG(logger
, "Handling file" << filename
);
23 auto result
= createBinary(filename
);
26 if ((ec
= result
.getError())) {
27 LOG4CXX_ERROR(logger
, "Failed to load Binary" << ec
.message());
32 binary
.reset(result
.get());
34 o
= dyn_cast
<ObjectFile
>(binary
.get());
36 triple
.setArch(Triple::ArchType(o
->getArch()));
37 std::string
tripleName(triple
.getTriple());
39 LOG4CXX_INFO(logger
, "Architecture " << tripleName
);
43 target
= TargetRegistry::lookupTarget("", triple
, es
);
45 LOG4CXX_ERROR(logger
, es
);
49 LOG4CXX_INFO(logger
, "Target " << target
->getName());
51 MRI
.reset(target
->createMCRegInfo(tripleName
));
53 LOG4CXX_ERROR(logger
, "no register info for target " << tripleName
);
57 // Set up disassembler.
58 AsmInfo
.reset(target
->createMCAsmInfo(*MRI
, tripleName
));
60 LOG4CXX_ERROR(logger
, "no assembly info for target " << tripleName
);
64 STI
.reset(target
->createMCSubtargetInfo(tripleName
, "", ""));
66 LOG4CXX_ERROR(logger
, "no subtarget info for target " << tripleName
);
70 MII
.reset(target
->createMCInstrInfo());
72 LOG4CXX_ERROR(logger
, "no instruction info for target " << tripleName
);
76 DisAsm
.reset(target
->createMCDisassembler(*STI
));
78 LOG4CXX_ERROR(logger
, "no disassembler for target " << tripleName
);
82 MOFI
.reset(new MCObjectFileInfo
);
83 Ctx
.reset(new MCContext(AsmInfo
.get(), MRI
.get(), MOFI
.get()));
85 target
->createMCRelocationInfo(tripleName
, *Ctx
.get()));
88 MCObjectSymbolizer::createObjectSymbolizer(*Ctx
.get(), RelInfo
, o
));
90 DisAsm
->setSymbolizer(Symzer
);
93 MIA
.reset(target
->createMCInstrAnalysis(MII
.get()));
95 int AsmPrinterVariant
= AsmInfo
->getAssemblerDialect();
96 IP
.reset(target
->createMCInstPrinter(AsmPrinterVariant
, *AsmInfo
, *MII
, *MRI
, *STI
));
98 LOG4CXX_ERROR(logger
, "no instruction printer for target " << tripleName
);
102 IP
->setPrintImmHex(llvm::HexStyle::C
);
103 IP
->setPrintImmHex(true);
105 OwningPtr
<MCObjectDisassembler
> OD(
106 new MCObjectDisassembler(*o
, *DisAsm
, *MIA
));
107 Mod
.reset(OD
->buildModule(false));
115 void LLVMDisassembler::disassemble() {
116 std::stack
<LLVMFunction
*> remaining_functions
;
117 std::stack
<LLVMBasicBlock
*> remaining_blocks
;
118 SectionRef text_section
= sections
[".text"];
120 std::for_each(symbols
.begin(), symbols
.end(),
121 [&](std::pair
<const std::string
, SymbolRef
> x
) {
124 SymbolRef::Type symbol_type
;
126 if (text_section
.containsSymbol(x
.second
, contains
) || !contains
)
129 if (x
.second
.getType(symbol_type
)
130 || SymbolRef::ST_Function
!= symbol_type
)
133 if (!x
.second
.getAddress(result
)) {
134 remaining_functions
.push(new LLVMFunction(x
.first
, result
));
135 LOG4CXX_DEBUG(logger
, "Disasembling " << x
.first
);
140 text_section
.getContents(bytes
);
141 StringRefMemoryObject
ref(bytes
);
143 while (remaining_functions
.size()) {
144 LLVMFunction
* current_function
= remaining_functions
.top();
145 remaining_functions
.pop();
147 LOG4CXX_DEBUG(logger
, "Handling function " << current_function
->getName());
149 // if ("_start" != current_function->getName())
152 remaining_blocks
.push(new LLVMBasicBlock(current_function
->getStartAddress()));
154 while (remaining_blocks
.size()) {
155 LLVMBasicBlock
* current_block
= remaining_blocks
.top();
156 remaining_blocks
.pop();
158 LOG4CXX_DEBUG(logger
, "Handling Block starting at " << std::hex
<< current_block
->getStartAddress());
161 uint64_t base_address
;
162 text_section
.getAddress(base_address
);
163 uint64_t current_address
= current_block
->getStartAddress() - base_address
;
167 llvm::raw_string_ostream
s(buf
);
169 if(llvm::MCDisassembler::Success
==
170 DisAsm
->getInstruction(inst
, inst_size
, ref
, current_address
, nulls(), nulls())) {
172 uint8_t bytes
[inst_size
+2];
173 ref
.readBytes(current_address
, inst_size
, bytes
);
175 for(uint8_t* cur
= bytes
; cur
< bytes
+ inst_size
; ++cur
) {
181 IP
->printInst(&inst
, s
, "");
183 LOG4CXX_DEBUG(logger
, std::hex
<< current_address
+ base_address
<< s
.str());
186 if (MIA
->evaluateBranch(inst
, current_address
, inst_size
, jmptarget
)) {
187 jmptarget
+= base_address
;
188 if (!MIA
->isIndirectBranch(inst
)) {
189 if (MIA
->isCall(inst
)) {
190 if (blocks
.find(jmptarget
) == blocks
.end())
191 remaining_functions
.push(new LLVMFunction("<Unnamed>", jmptarget
));
193 if (blocks
.find(jmptarget
) == blocks
.end())
194 remaining_blocks
.push(new LLVMBasicBlock(jmptarget
));
195 if (MIA
->isConditionalBranch(inst
)) {
196 jmptarget
= base_address
+ current_address
+ inst_size
;
197 if (blocks
.find(jmptarget
) == blocks
.end())
198 remaining_blocks
.push(new LLVMBasicBlock(jmptarget
));
208 if (inst_size
== 0 || MIA
->isTerminator(inst
) || MIA
->isBranch(inst
)) {
209 current_block
->setEndAddress(current_address
+ base_address
);
210 blocks
.insert(std::make_pair(current_block
->getStartAddress(), current_block
));
211 LOG4CXX_DEBUG(logger
, "Finished Block at " << current_block
->getEndAddress());
214 current_address
+= inst_size
;
217 LOG4CXX_DEBUG(logger
, "Finished function " << current_function
->getName());
221 void LLVMDisassembler::readSymbols() {
223 symbol_iterator
si(o
->symbol_begin()), se(o
->symbol_end());
224 for (; si
!= se
; ++si
) {
226 if ((ec
= si
->getName(name
))) {
227 LOG4CXX_ERROR(logger
, ec
.message());
230 LOG4CXX_DEBUG(logger
, "Added symbol " << name
.str());
231 symbols
.insert(make_pair(name
.str(), *si
));
235 void LLVMDisassembler::readSections() {
237 section_iterator
i(o
->section_begin()), e(o
->section_end());
238 for (; i
!= e
; ++i
) {
240 if ((ec
= i
->getName(name
))) {
241 LOG4CXX_ERROR(logger
, ec
.message());
244 LOG4CXX_DEBUG(logger
, "Added section " << name
.str());
245 sections
.insert(make_pair(name
.str(), *i
));
250 BasicBlock
* LLVMDisassembler::generateControlFlowGraph(uint64_t address
) {