summaryrefslogtreecommitdiff
path: root/examples/llil_parser/src/LowLevel_IL_Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/llil_parser/src/LowLevel_IL_Parser.cpp')
-rw-r--r--examples/llil_parser/src/LowLevel_IL_Parser.cpp442
1 files changed, 442 insertions, 0 deletions
diff --git a/examples/llil_parser/src/LowLevel_IL_Parser.cpp b/examples/llil_parser/src/LowLevel_IL_Parser.cpp
new file mode 100644
index 00000000..2f61b83a
--- /dev/null
+++ b/examples/llil_parser/src/LowLevel_IL_Parser.cpp
@@ -0,0 +1,442 @@
+/*
+LLIL Parser - Binary Ninja C++ API Sample
+ - Robert Yates - 22/JUN/17
+ */
+
+#include "LowLevel_IL_Parser.h"
+#include <iostream>
+#include <sstream>
+
+int main(int argc, char* argv[])
+{
+
+ try
+ {
+ ShowBanner();
+
+
+ if (argc != 2)
+ {
+ printf("Usage: %s <input file>\n", argv[0]);
+ exit(-1);
+ }
+
+ std::string inputName = argv[1];
+
+ SetBundledPluginDirectory(get_plugins_directory());
+ InitCorePlugins();
+ InitUserPlugins();
+
+ auto bd = BinaryData(new FileMetadata(), inputName.c_str());
+ BinaryView *bv;
+
+ for (auto type : BinaryViewType::GetViewTypes())
+ {
+ if (type->IsTypeValidForData(&bd) && type->GetName() != "Raw")
+ {
+ bv = type->Create(&bd);
+ break;
+ }
+ }
+
+ printf("[i] Starting analysis\n");
+ bv->UpdateAnalysisAndWait();
+
+ printf("[i] Analysis done - %zd Functions\n", bv->GetAnalysisFunctionList().size());
+
+ if (bv->GetAnalysisFunctionList().size() < 1)
+ throw std::runtime_error("Error no functions found\n");
+
+ LlilParser myParser(bv);
+ myParser.decodeWholeFunction(bv->GetAnalysisFunctionList()[0]);
+
+ /*
+ // Show Single LLIL in function x at index x
+ myParser.decodeIndexInFunction(0x407930, 0);
+
+ // Decode a whole function by address
+ myParser.decodeWholeFunction(0x407930);
+
+ // Decode all functions
+ for (const auto& f : bv->GetAnalysisFunctionList())
+ {
+ // Decode a whole function by BinaryNinja::Function object
+ myParser.decodeWholeFunction(f);
+ }
+ */
+
+ }
+ catch (const std::exception& e)
+ {
+ printf("An Exception Occured: %s\n", e.what());
+ }
+
+ printf("[i] Finished\n");
+}
+
+
+
+LlilParser::LlilParser(BinaryView *bv)
+ : m_bv(bv)
+{
+ m_currentFunction.clear();
+ m_tabs = 0;
+ m_currentInstructionId = 0;
+}
+
+void LlilParser::showIndent() const
+{
+ for (int i = 0; i < m_tabs; i++)
+ printf(" ");
+}
+
+void LlilParser::analysisInstruction(const BNLowLevelILInstruction& insn)
+{
+
+ auto instructionSynatx = g_llilSyntaxMap.find(insn.operation);
+ BinaryNinja::Ref<BinaryNinja::LowLevelILFunction> llil = m_currentFunction[0]->GetLowLevelIL();
+ if (instructionSynatx == g_llilSyntaxMap.end())
+ throw std::runtime_error("Error unknown LLIL\n");
+
+ showIndent();
+ printf("Instruction: %s\n", getLowLevelILOperationName(insn.operation).c_str());
+ m_tabs += 3;
+
+ int operandId = 0;
+ for (const auto& operand : instructionSynatx->second)
+ {
+ if (operand.type == OperandType::kExpr)
+ {
+ // In this case the value in the operands[x] field is a new instruction & expression index value
+ BNLowLevelILInstruction nextInstruction = (*llil)[insn.operands[operandId]];
+
+ analysisInstruction(nextInstruction); // recursion begins :)
+ }
+ else if (operand.type == OperandType::kReg)
+ {
+ // In this case the register id is in the first operands field and we use Arch to translate
+ showIndent();
+ printf("Reg: %s\n", m_bv->GetDefaultArchitecture()->GetRegisterName(static_cast<uint32_t>(insn.operands[0])).c_str());
+ m_tabs += 3;
+ }
+ else if (operand.type == OperandType::kInt)
+ {
+ // In this case the operand is simply a value
+ showIndent();
+ printf("Value: %zX\n", insn.operands[0]);
+ m_tabs += 3;
+ }
+ else if (operand.type == OperandType::kFlag)
+ {
+ // In this case the operand is a flag
+ printf("Flag: %s\n", m_bv->GetDefaultArchitecture()->GetFlagName(static_cast<uint32_t>(insn.operands[0])).c_str());
+ m_tabs += 3;
+ }
+ else if (operand.type == OperandType::kIntList)
+ {
+ // In this case we have an array of llil targets
+ std::vector<uint64_t> intList = llil->GetOperandList(llil->GetIndexForInstruction(m_currentInstructionId), operandId);
+ showIndent();
+ printf("Target LLIL Indices: ");
+ for (const auto i : intList)
+ {
+ printf("%zd ", i);
+ }
+ printf("\n");
+ }
+ else
+ {
+ printf("[e] LLIL Parser: Not Handled -> OperandPurpose: %d OperandType: %d\n", operand.purpose, operand.type);
+ }
+
+
+ operandId++;
+ }
+
+
+}
+
+void LlilParser::decodeIndexInFunction(uint64_t functionAddress, int indexIl)
+{
+
+ m_currentFunction = m_bv->GetAnalysisFunctionsForAddress(functionAddress);
+ if (m_currentFunction.size() < 1)
+ throw std::runtime_error("Error no functions at requested address\n");
+
+ BinaryNinja::Function *function = m_currentFunction[0];
+ BinaryNinja::Ref<BinaryNinja::LowLevelILFunction> llil = function->GetLowLevelIL();
+
+ m_currentInstructionId = indexIl;
+ BNLowLevelILInstruction currentInstruction = (*llil)[llil->GetIndexForInstruction(indexIl)];
+
+
+ analysisInstruction(currentInstruction);
+ m_tabs = 0;
+
+}
+
+void LlilParser::decodeWholeFunction(BinaryNinja::Function *function)
+{
+ m_currentFunction.clear();
+ m_currentFunction.push_back(function);
+
+ BinaryNinja::Ref<BinaryNinja::LowLevelILFunction> llil = function->GetLowLevelIL();
+
+ for (size_t i = 0; i < llil->GetInstructionCount(); i++)
+ {
+
+ m_currentInstructionId = i;
+ BNLowLevelILInstruction currentInstruction = (*llil)[llil->GetIndexForInstruction(i)];
+
+ printf("\n[%zx][%zd]---------------------------------------------------------------------------\n", currentInstruction.address, i);
+
+ analysisInstruction(currentInstruction);
+ m_tabs = 0;
+ }
+
+}
+
+void LlilParser::decodeWholeFunction(uint64_t functionAddress)
+{
+
+ m_currentFunction = m_bv->GetAnalysisFunctionsForAddress(functionAddress);
+ if (m_currentFunction.size() < 1)
+ throw std::runtime_error("Error no functions at requested address or possible invalid BundledPluginDirectory\n");
+
+ BinaryNinja::Function *function = m_currentFunction[0];
+ BinaryNinja::Ref<BinaryNinja::LowLevelILFunction> llil = function->GetLowLevelIL();
+
+
+
+ for (size_t i = 0; i < llil->GetInstructionCount(); i++)
+ {
+ m_currentInstructionId = i;
+ BNLowLevelILInstruction currentInstruction = (*llil)[llil->GetIndexForInstruction(i)];
+
+ printf("\n[%zx][%zd]---------------------------------------------------------------------------\n", currentInstruction.address, i);
+
+ analysisInstruction(currentInstruction);
+ m_tabs = 0;
+ }
+
+}
+
+void ShowBanner()
+{
+
+ printf (".____ .____ .___.____ __________ \n");
+ printf ("| | | | | | | \\______ \\_____ _______ ______ ___________ \n");
+ printf ("| | | | | | | | ___/\\__ \\\\_ __ \\/ ___// __ \\_ __ \\\n");
+ printf ("| |___| |___| | |___ | | / __ \\| | \\/\\___ \\\\ ___/| | \\/\n");
+ printf ("|_______ \\_______ \\___|_______ \\ |____| (____ /__| /____ >\\___ >__| \n");
+ printf (" \\/ \\/ \\/ \\/ \\/ \\/ \n");
+ printf("====================================================================================\n\n");
+
+}
+
+#ifdef _WIN32
+std::string get_plugins_directory()
+{
+ return "C:\\Program Files\\Vector35\\BinaryNinja\\plugins\\";
+}
+#elif __APPLE__
+std::string get_plugins_directory()
+{
+ return "/Applications/Binary Ninja.app/Contents/MacOS/plugins/";
+}
+#else
+std::string get_plugins_directory()
+{
+ return "~/binaryninja/plugins";
+}
+#endif
+
+const std::string LlilParser::getLowLevelILOperationName(BNLowLevelILOperation id) const
+{
+
+ switch (id)
+ {
+ case LLIL_NOP:
+ return "LLIL_NOP";
+ case LLIL_SET_REG:
+ return "LLIL_SET_REG";
+ case LLIL_SET_REG_SPLIT:
+ return "LLIL_SET_REG_SPLIT";
+ case LLIL_SET_FLAG:
+ return "LLIL_SET_FLAG";
+ case LLIL_LOAD:
+ return "LLIL_LOAD";
+ case LLIL_STORE:
+ return "LLIL_STORE";
+ case LLIL_PUSH:
+ return "LLIL_PUSH";
+ case LLIL_POP:
+ return "LLIL_POP";
+ case LLIL_REG:
+ return "LLIL_REG";
+ case LLIL_CONST:
+ return "LLIL_CONST";
+ case LLIL_CONST_PTR:
+ return "LLIL_CONST_PTR";
+ case LLIL_FLAG:
+ return "LLIL_FLAG";
+ case LLIL_FLAG_BIT:
+ return "LLIL_FLAG_BIT";
+ case LLIL_ADD:
+ return "LLIL_ADD";
+ case LLIL_ADC:
+ return "LLIL_ADC";
+ case LLIL_SUB:
+ return "LLIL_SUB";
+ case LLIL_SBB:
+ return "LLIL_SBB";
+ case LLIL_AND:
+ return "LLIL_AND";
+ case LLIL_OR:
+ return "LLIL_OR";
+ case LLIL_XOR:
+ return "LLIL_XOR";
+ case LLIL_LSL:
+ return "LLIL_LSL";
+ case LLIL_LSR:
+ return "LLIL_LSR";
+ case LLIL_ASR:
+ return "LLIL_ASR";
+ case LLIL_ROL:
+ return "LLIL_ROL";
+ case LLIL_RLC:
+ return "LLIL_RLC";
+ case LLIL_ROR:
+ return "LLIL_ROR";
+ case LLIL_RRC:
+ return "LLIL_RRC";
+ case LLIL_MUL:
+ return "LLIL_MUL";
+ case LLIL_MULU_DP:
+ return "LLIL_MULU_DP";
+ case LLIL_MULS_DP:
+ return "LLIL_MULS_DP";
+ case LLIL_DIVU:
+ return "LLIL_DIVU";
+ case LLIL_DIVU_DP:
+ return "LLIL_DIVU_DP";
+ case LLIL_DIVS:
+ return "LLIL_DIVS";
+ case LLIL_DIVS_DP:
+ return "LLIL_DIVS_DP";
+ case LLIL_MODU:
+ return "LLIL_MODU";
+ case LLIL_MODU_DP:
+ return "LLIL_MODU_DP";
+ case LLIL_MODS:
+ return "LLIL_MODS";
+ case LLIL_MODS_DP:
+ return "LLIL_MODS_DP";
+ case LLIL_NEG:
+ return "LLIL_NEG";
+ case LLIL_NOT:
+ return "LLIL_NOT";
+ case LLIL_SX:
+ return "LLIL_SX";
+ case LLIL_ZX:
+ return "LLIL_ZX";
+ case LLIL_LOW_PART:
+ return "LLIL_LOW_PART";
+ case LLIL_JUMP:
+ return "LLIL_JUMP";
+ case LLIL_JUMP_TO:
+ return "LLIL_JUMP_TO";
+ case LLIL_CALL:
+ return "LLIL_CALL";
+ case LLIL_RET:
+ return "LLIL_RET";
+ case LLIL_NORET:
+ return "LLIL_NORET";
+ case LLIL_IF:
+ return "LLIL_IF";
+ case LLIL_GOTO:
+ return "LLIL_GOTO";
+ case LLIL_FLAG_COND:
+ return "LLIL_FLAG_COND";
+ case LLIL_CMP_E:
+ return "LLIL_CMP_E";
+ case LLIL_CMP_NE:
+ return "LLIL_CMP_NE";
+ case LLIL_CMP_SLT:
+ return "LLIL_CMP_SLT";
+ case LLIL_CMP_ULT:
+ return "LLIL_CMP_ULT";
+ case LLIL_CMP_SLE:
+ return "LLIL_CMP_SLE";
+ case LLIL_CMP_ULE:
+ return "LLIL_CMP_ULE";
+ case LLIL_CMP_SGE:
+ return "LLIL_CMP_SGE";
+ case LLIL_CMP_UGE:
+ return "LLIL_CMP_UGE";
+ case LLIL_CMP_SGT:
+ return "LLIL_CMP_SGT";
+ case LLIL_CMP_UGT:
+ return "LLIL_CMP_UGT";
+ case LLIL_TEST_BIT:
+ return "LLIL_TEST_BIT";
+ case LLIL_BOOL_TO_INT:
+ return "LLIL_BOOL_TO_INT";
+ case LLIL_ADD_OVERFLOW:
+ return "LLIL_ADD_OVERFLOW";
+ case LLIL_SYSCALL:
+ return "LLIL_SYSCALL";
+ case LLIL_BP:
+ return "LLIL_BP";
+ case LLIL_TRAP:
+ return "LLIL_TRAP";
+ case LLIL_UNDEF:
+ return "LLIL_UNDEF";
+ case LLIL_UNIMPL:
+ return "LLIL_UNIMPL";
+ case LLIL_UNIMPL_MEM:
+ return "LLIL_UNIMPL_MEM";
+ case LLIL_SET_REG_SSA:
+ return "LLIL_SET_REG_SSA";
+ case LLIL_SET_REG_SSA_PARTIAL:
+ return "LLIL_SET_REG_SSA_PARTIAL";
+ case LLIL_SET_REG_SPLIT_SSA:
+ return "LLIL_SET_REG_SPLIT_SSA";
+ case LLIL_REG_SPLIT_DEST_SSA:
+ return "LLIL_REG_SPLIT_DEST_SSA";
+ case LLIL_REG_SSA:
+ return "LLIL_REG_SSA";
+ case LLIL_REG_SSA_PARTIAL:
+ return "LLIL_REG_SSA_PARTIAL";
+ case LLIL_SET_FLAG_SSA:
+ return "LLIL_SET_FLAG_SSA";
+ case LLIL_FLAG_SSA:
+ return "LLIL_FLAG_SSA";
+ case LLIL_FLAG_BIT_SSA:
+ return "LLIL_FLAG_BIT_SSA";
+ case LLIL_CALL_SSA:
+ return "LLIL_CALL_SSA";
+ case LLIL_SYSCALL_SSA:
+ return "LLIL_SYSCALL_SSA";
+ case LLIL_CALL_PARAM_SSA:
+ return "LLIL_CALL_PARAM_SSA";
+ case LLIL_CALL_STACK_SSA:
+ return "LLIL_CALL_STACK_SSA";
+ case LLIL_CALL_OUTPUT_SSA:
+ return "LLIL_CALL_OUTPUT_SSA";
+ case LLIL_LOAD_SSA:
+ return "LLIL_LOAD_SSA";
+ case LLIL_STORE_SSA:
+ return "LLIL_STORE_SSA";
+ case LLIL_REG_PHI:
+ return "LLIL_REG_PHI";
+ case LLIL_FLAG_PHI:
+ return "LLIL_FLAG_PHI";
+ case LLIL_MEM_PHI:
+ return "LLIL_MEM_PHI";
+ }
+
+ return "Unknown";
+ //throw std::runtime_error("GetLowLevelILOperationName Failure");
+
+} \ No newline at end of file