* add llil cpp example * added image * fix string stream under linux * fix path under linux * Update build notes for linux * analysis sync | mac os path | lill* usage change * added path note and removed comment about mac path * use UpdateAnalysisAndWait()
Diffstat (limited to 'examples/llil_parser')
-rw-r--r--examples/llil_parser/CMakeLists.txt51
-rw-r--r--examples/llil_parser/README.md63
-rw-r--r--examples/llil_parser/inc/LowLevel_IL_Parser.h171
-rw-r--r--examples/llil_parser/src/LowLevel_IL_Parser.cpp442
4 files changed, 727 insertions, 0 deletions
diff --git a/examples/llil_parser/CMakeLists.txt b/examples/llil_parser/CMakeLists.txt
new file mode 100644
index 00000000..5a0676e0
--- /dev/null
+++ b/examples/llil_parser/CMakeLists.txt
@@ -0,0 +1,51 @@
+# Mostly copied from https://github.com/Vector35/binaryninja-api/blob/dev/examples/breakpoint/CMakeLists.txt
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+project(LLIL_Parser)
+
+#-----------------------------------------------------------------------------
+include_directories("inc/")
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)
+#-----------------------------------------------------------------------------
+file( GLOB_RECURSE SRCS *.cpp *.h)
+#-----------------------------------------------------------------------------
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+#-----------------------------------------------------------------------------
+if(WIN32)
+ set(BINJA_DIR "C:\\Program Files\\Vector35\\BinaryNinja"
+ CACHE PATH "Binary Ninja installation directory")
+ set(BINJA_BIN_DIR "${BINJA_DIR}")
+ set(BINJA_PLUGINS_DIR "$ENV{APPDATA}/Binary Ninja/plugins"
+ CACHE PATH "Binary Ninja user plugins directory")
+elseif(APPLE)
+ set(BINJA_DIR "/Applications/Binary Ninja.app"
+ CACHE PATH "Binary Ninja installation directory")
+ set(BINJA_BIN_DIR "${BINJA_DIR}/Contents/MacOS")
+ set(BINJA_PLUGINS_DIR "$ENV{HOME}/Library/Application Support/Binary Ninja/plugins"
+ CACHE PATH "Binary Ninja user plugins directory")
+else()
+ set(BINJA_DIR "$ENV{HOME}/binaryninja"
+ CACHE PATH "Binary Ninja installation directory")
+ set(BINJA_BIN_DIR "${BINJA_DIR}")
+ set(BINJA_PLUGINS_DIR "$ENV{HOME}/.binaryninja/plugins"
+ CACHE PATH "Binary Ninja user plugins directory")
+endif()
+#-----------------------------------------------------------------------------
+add_executable (${PROJECT_NAME} ${SRCS} )
+#-----------------------------------------------------------------------------
+find_library(BINJA_API_LIBRARY binaryninjaapi
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/../../bin ${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Release ${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Debug)
+find_library(BINJA_CORE_LIBRARY binaryninjacore
+ HINTS ${BINJA_BIN_DIR})
+#-----------------------------------------------------------------------------
+target_link_libraries(${PROJECT_NAME}
+ ${BINJA_API_LIBRARY}
+ ${BINJA_CORE_LIBRARY}
+ )
+#-----------------------------------------------------------------------------
+install (TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION Lib
+ ARCHIVE DESTINATION Lib)
+
diff --git a/examples/llil_parser/README.md b/examples/llil_parser/README.md
new file mode 100644
index 00000000..07532c79
--- /dev/null
+++ b/examples/llil_parser/README.md
@@ -0,0 +1,63 @@
+LLIL Parser - Binary Ninja C++ API Sample
+===
+
+> Robert Yates | 22nd June 2017
+
+LLIL Parser is a simple example for demonstrating how to use the BinaryNinja C++ API
+
+![ScreenShot](https://user-images.githubusercontent.com/1876966/27665067-58d34dd0-5c6b-11e7-9361-6efd01cfa0af.JPG)
+
+Example of building under windows from scratch
+===
+
+* https://cmake.org/ Required for this example
+* We will be using Visual Studio 2017 however if want to use a different version simply run the `cmake -G` command to find the alternative name to use in the cmake commands below, be sure to use the Win64 version.
+
+Note: if you havent installed binary ninja into a default location then you will need to edit the cmake file and also the `std::string get_plugins_directory()` function in the `.cpp` file
+
+# Building the BinaryNinja API
+```
+git clone https://github.com/Vector35/binaryninja-api.git
+cd binaryninja
+mkdir _build
+cd _build
+cmake .. -G "Visual Studio 15 2017 Win64"
+cmake --build . --config Release
+```
+
+The objective here is to build the `binaryninjaapi.lib` This will be placed in the `bin` folder
+
+# Building the C++ Example
+
+```
+cd ../examples
+mkdir _build
+cd _build
+cmake ../llil_parser -G "Visual Studio 15 2017 Win64"
+cmake --build . --config Release
+cd Release
+copy "c:\Program Files\Vector35\BinaryNinja\binaryninjacore.dll" .
+```
+
+If you get an error about `BINJA_API_LIBRARY` check the API has built properly and `binaryninjaapi.lib` is located in the `bin` folder in the root folder of the API
+
+If you get an error about `BINJA_CORE_LIBRARY` then the file C:\Program Files\Vector35\BinaryNinja\binaryninjacore.lib is missing see [Create .lib file from .dll](https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/) on details about how to create this lib file from the dll file located in that directory
+
+> Building under the linux is almost exactly the same however you need not use the `-G` parameter and you build with the `make` command instead of `cmake --build` another important note is that i had to execute `cp ~/binaryninja/libbinaryninjacore.so.1 ~/binaryninja/libbinaryninjacore.so` before linking would work
+
+Note i do not have access to a MAC so i havent tested this.
+
+Using the example
+===
+
+Simply run the compiled executable with a target binary as a parameter and it will parse the LLIL from the first detected function in the target binary.
+
+The `void LlilParser::analysisInstruction(const BNLowLevelILInstruction& insn)` function is probably the most
+function of interest for learning.
+
+This example is only intended for learning from the source code however if you wish to turn it into something more useful then you could add callbacks in the analysis function to keep track of when certain regs, values occur etc.
+
+# Disclaimer
+
+This was mostly figured out by myself and may not be the best way to achieve the intended desire, however i hope it serves as a starting point
+
diff --git a/examples/llil_parser/inc/LowLevel_IL_Parser.h b/examples/llil_parser/inc/LowLevel_IL_Parser.h
new file mode 100644
index 00000000..7b3b6baa
--- /dev/null
+++ b/examples/llil_parser/inc/LowLevel_IL_Parser.h
@@ -0,0 +1,171 @@
+#ifndef __LOWLEVEL_IL_PARSER_H_
+#define __LOWLEVEL_IL_PARSER_H_
+
+#include "binaryninjacore.h"
+#include "binaryninjaapi.h"
+#include <map>
+
+std::string get_plugins_directory();
+void ShowBanner();
+
+using namespace BinaryNinja;
+
+enum OperandPurpose
+{
+ kDest,
+ kSrc,
+ kConstant,
+ kLeft,
+ kRight,
+ kHi,
+ kLow,
+ kTargets,
+ kCondition,
+ kVector,
+ kOutput,
+ kStack,
+ kParam,
+ kDestMemory,
+ kSrcMemory,
+ kTrue,
+ kFalse,
+ kBit,
+ kCarry,
+ kFullReg,
+};
+
+enum OperandType
+{
+ kReg,
+ kExpr,
+ kFlag,
+ kIntList,
+ kInt,
+ kRegSsa,
+ kRegSsaList,
+ kFlagSsa,
+ kCond,
+ kFlagSsaList,
+};
+
+struct BNLowLevelILOperationSyntax
+{
+ OperandPurpose purpose;
+ OperandType type;
+};
+
+
+static std::map<BNLowLevelILOperation, std::vector<BNLowLevelILOperationSyntax>> g_llilSyntaxMap = { \
+{ LLIL_NOP,{} }, \
+{ LLIL_SET_REG,{ { kDest, kReg },{ kSrc,kExpr } } }, \
+{ LLIL_SET_REG_SPLIT,{ { kHi, kReg },{ kLow,kReg },{ kSrc,kExpr } } } , \
+{ LLIL_SET_FLAG,{ { kDest, kFlag },{ kSrc,kExpr } } }, \
+{ LLIL_LOAD,{ { kSrc, kExpr } } }, \
+{ LLIL_STORE,{ { kDest, kExpr },{ kSrc,kExpr } } }, \
+{ LLIL_PUSH,{ { kSrc, kExpr } } }, \
+{ LLIL_POP,{} }, \
+{ LLIL_REG,{ { kSrc, kReg } } }, \
+{ LLIL_CONST,{ { kConstant, kInt } } }, \
+{ LLIL_CONST_PTR,{ { kConstant, kInt } } }, \
+{ LLIL_FLAG,{ { kSrc, kFlag } } }, \
+{ LLIL_FLAG_BIT,{ { kSrc, kFlag },{ kBit,kInt } } }, \
+{ LLIL_ADD,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_ADC,{ { kLeft, kExpr },{ kRight,kExpr },{ kCarry,kExpr } } }, \
+{ LLIL_SUB,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_SBB,{ { kLeft, kExpr },{ kRight,kExpr },{ kCarry,kExpr } } }, \
+{ LLIL_AND,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_OR,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_XOR,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_LSL,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_LSR,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_ASR,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_ROL,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_RLC,{ { kLeft, kExpr },{ kRight,kExpr },{ kCarry,kExpr } } }, \
+{ LLIL_ROR,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_RRC,{ { kLeft, kExpr },{ kRight,kExpr },{ kCarry,kExpr } } }, \
+{ LLIL_MUL,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_MULU_DP,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_MULS_DP,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_DIVU,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_DIVU_DP,{ { kHi, kExpr },{ kLow,kExpr },{ kRight,kExpr } } }, \
+{ LLIL_DIVS,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_DIVS_DP,{ { kHi, kExpr },{ kLow,kExpr },{ kRight,kExpr } } }, \
+{ LLIL_MODU,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_MODU_DP,{ { kHi, kExpr },{ kLow,kExpr },{ kRight,kExpr } } }, \
+{ LLIL_MODS,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_MODS_DP,{ { kHi, kExpr },{ kLow,kExpr },{ kRight,kExpr } } }, \
+{ LLIL_NEG,{ { kSrc, kExpr } } }, \
+{ LLIL_NOT,{ { kSrc, kExpr } } }, \
+{ LLIL_SX,{ { kSrc, kExpr } } }, \
+{ LLIL_ZX,{ { kSrc, kExpr } } }, \
+{ LLIL_LOW_PART,{ { kSrc, kExpr } } }, \
+{ LLIL_JUMP,{ { kDest, kExpr } } }, \
+{ LLIL_JUMP_TO,{ { kDest, kExpr },{ kTargets,kIntList } } }, \
+{ LLIL_CALL,{ { kDest, kExpr } } }, \
+{ LLIL_RET,{ { kDest, kExpr } } }, \
+{ LLIL_NORET,{} }, \
+{ LLIL_IF,{ { kCondition, kExpr },{ kTrue,kInt },{ kFalse,kInt } } }, \
+{ LLIL_GOTO,{ { kDest, kInt } } }, \
+{ LLIL_FLAG_COND,{ { kCondition, kCond } } }, \
+{ LLIL_CMP_E,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_NE,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_SLT,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_ULT,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_SLE,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_ULE,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_SGE,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_UGE,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_SGT,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_CMP_UGT,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_TEST_BIT,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_BOOL_TO_INT,{ { kSrc, kExpr } } }, \
+{ LLIL_ADD_OVERFLOW,{ { kLeft, kExpr },{ kRight,kExpr } } }, \
+{ LLIL_SYSCALL,{} }, \
+{ LLIL_BP,{} }, \
+{ LLIL_TRAP,{ { kVector, kInt } } }, \
+{ LLIL_UNDEF,{} }, \
+{ LLIL_UNIMPL,{} }, \
+{ LLIL_UNIMPL_MEM,{ { kSrc, kExpr } } }, \
+{ LLIL_SET_REG_SSA,{ { kDest, kRegSsa },{ kSrc,kExpr } } }, \
+{ LLIL_IF,{ { kFullReg, kRegSsa },{ kDest,kReg },{ kSrc,kExpr } } }, \
+{ LLIL_SET_REG_SPLIT_SSA,{ { kHi, kExpr },{ kLow,kExpr },{ kSrc,kExpr } } }, \
+{ LLIL_REG_SPLIT_DEST_SSA,{ { kDest, kRegSsa } } }, \
+{ LLIL_REG_SSA,{ { kSrc, kRegSsa } } }, \
+{ LLIL_REG_SSA_PARTIAL,{ { kFullReg, kRegSsa },{ kSrc,kReg } } }, \
+{ LLIL_SET_FLAG_SSA,{ { kDest, kFlagSsa },{ kSrc,kExpr } } }, \
+{ LLIL_FLAG_SSA,{ { kSrc, kFlagSsa } } }, \
+{ LLIL_FLAG_BIT_SSA,{ { kSrc, kFlagSsa },{ kBit, kInt } } }, \
+{ LLIL_CALL_SSA,{ { kOutput, kExpr },{ kDest,kExpr },{ kStack,kExpr },{ kParam,kExpr } } }, \
+{ LLIL_SYSCALL_SSA,{ { kOutput, kExpr },{ kStack,kExpr },{ kParam,kExpr } } }, \
+{ LLIL_CALL_OUTPUT_SSA,{ { kDestMemory, kInt },{ kDest, kRegSsaList } } }, \
+{ LLIL_CALL_STACK_SSA,{ { kSrc, kRegSsa },{ kSrcMemory, kInt } } }, \
+{ LLIL_CALL_PARAM_SSA,{ { kSrc, kRegSsaList } } }, \
+{ LLIL_LOAD_SSA,{ { kSrc, kExpr },{ kSrcMemory, kInt } } }, \
+{ LLIL_STORE_SSA,{ { kDest, kExpr },{ kDestMemory,kInt },{ kSrcMemory,kInt },{ kSrc,kExpr } } }, \
+{ LLIL_REG_PHI,{ { kDest, kRegSsa },{ kSrc, kRegSsaList } } }, \
+{ LLIL_FLAG_PHI,{ { kDest, kFlagSsa },{ kSrc, kFlagSsaList } } }, \
+{ LLIL_MEM_PHI,{ { kDestMemory, kInt },{ kSrcMemory, kIntList } } }, \
+};
+
+
+class LlilParser
+{
+
+public:
+ LlilParser(BinaryView *bv);
+ const std::string getLowLevelILOperationName(const BNLowLevelILOperation id) const;
+ void decodeIndexInFunction(uint64_t functionAddress, int indexIl);
+ void decodeWholeFunction(uint64_t functionAddress);
+ void decodeWholeFunction(BinaryNinja::Function *function);
+private:
+ void showIndent() const;
+ void analysisInstruction(const BNLowLevelILInstruction& insn);
+
+ BinaryView *m_bv;
+ std::vector<BinaryNinja::Ref<BinaryNinja::Function>> m_currentFunction;
+ int m_tabs;
+ size_t m_currentInstructionId;
+};
+
+
+#endif /* __LOWLEVEL_IL_PARSER_H_ */ \ No newline at end of file
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