summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basicblock.cpp37
-rw-r--r--binaryninjaapi.h101
-rw-r--r--binaryninjacore.h69
-rw-r--r--binaryview.cpp2
-rw-r--r--function.cpp1
-rw-r--r--functiongraph.cpp36
-rw-r--r--functiongraphblock.cpp1
-rw-r--r--plugin.cpp218
-rw-r--r--python/basicblock.py21
-rw-r--r--python/function.py71
-rw-r--r--python/plugin.py219
11 files changed, 736 insertions, 40 deletions
diff --git a/basicblock.cpp b/basicblock.cpp
index d42a1038..33f57d40 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -276,6 +276,7 @@ vector<DisassemblyTextLine> BasicBlock::GetDisassemblyText(DisassemblySettings*
{
DisassemblyTextLine line;
line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
line.tokens.reserve(lines[i].count);
for (size_t j = 0; j < lines[i].count; j++)
{
@@ -417,3 +418,39 @@ bool BasicBlock::IsBackEdge(BasicBlock* source, BasicBlock* target)
}
return false;
}
+
+
+bool BasicBlock::IsILBlock() const
+{
+ return BNIsILBasicBlock(m_object);
+}
+
+
+bool BasicBlock::IsLowLevelILBlock() const
+{
+ return BNIsLowLevelILBasicBlock(m_object);
+}
+
+
+bool BasicBlock::IsMediumLevelILBlock() const
+{
+ return BNIsMediumLevelILBasicBlock(m_object);
+}
+
+
+Ref<LowLevelILFunction> BasicBlock::GetLowLevelILFunction() const
+{
+ BNLowLevelILFunction* func = BNGetBasicBlockLowLevelILFunction(m_object);
+ if (!func)
+ return nullptr;
+ return new LowLevelILFunction(func);
+}
+
+
+Ref<MediumLevelILFunction> BasicBlock::GetMediumLevelILFunction() const
+{
+ BNMediumLevelILFunction* func = BNGetBasicBlockMediumLevelILFunction(m_object);
+ if (!func)
+ return nullptr;
+ return new MediumLevelILFunction(func);
+}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index d0c19e7a..81b5105d 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -986,6 +986,7 @@ namespace BinaryNinja
struct DisassemblyTextLine
{
uint64_t addr;
+ size_t instrIndex;
std::vector<InstructionTextToken> tokens;
};
@@ -1590,6 +1591,7 @@ namespace BinaryNinja
};
class LowLevelILFunction;
+ class MediumLevelILFunction;
class FunctionRecognizer;
class CallingConvention;
@@ -2254,6 +2256,12 @@ namespace BinaryNinja
void SetUserBasicBlockHighlight(uint8_t r, uint8_t g, uint8_t b, uint8_t alpha = 255);
static bool IsBackEdge(BasicBlock* source, BasicBlock* target);
+
+ bool IsILBlock() const;
+ bool IsLowLevelILBlock() const;
+ bool IsMediumLevelILBlock() const;
+ Ref<LowLevelILFunction> GetLowLevelILFunction() const;
+ Ref<MediumLevelILFunction> GetMediumLevelILFunction() const;
};
struct VariableNameAndType
@@ -2570,6 +2578,12 @@ namespace BinaryNinja
bool IsOptionSet(BNDisassemblyOption option) const;
void SetOption(BNDisassemblyOption option, bool state = true);
+
+ bool IsILGraph() const;
+ bool IsLowLevelILGraph() const;
+ bool IsMediumLevelILGraph() const;
+ Ref<LowLevelILFunction> GetLowLevelILFunction() const;
+ Ref<MediumLevelILFunction> GetMediumLevelILFunction() const;
};
struct LowLevelILLabel: public BNLowLevelILLabel
@@ -3312,7 +3326,10 @@ namespace BinaryNinja
{
Ref<BinaryView> view;
uint64_t address, length;
+ size_t instrIndex;
Ref<Function> function;
+ Ref<LowLevelILFunction> lowLevelILFunction;
+ Ref<MediumLevelILFunction> mediumLevelILFunction;
PluginCommandContext();
};
@@ -3345,15 +3362,55 @@ namespace BinaryNinja
std::function<bool(BinaryView*, Function*)> isValid;
};
+ struct RegisteredLowLevelILFunctionCommand
+ {
+ std::function<void(BinaryView*, LowLevelILFunction*)> action;
+ std::function<bool(BinaryView*, LowLevelILFunction*)> isValid;
+ };
+
+ struct RegisteredLowLevelILInstructionCommand
+ {
+ std::function<void(BinaryView*, const LowLevelILInstruction&)> action;
+ std::function<bool(BinaryView*, const LowLevelILInstruction&)> isValid;
+ };
+
+ struct RegisteredMediumLevelILFunctionCommand
+ {
+ std::function<void(BinaryView*, MediumLevelILFunction*)> action;
+ std::function<bool(BinaryView*, MediumLevelILFunction*)> isValid;
+ };
+
+ struct RegisteredMediumLevelILInstructionCommand
+ {
+ std::function<void(BinaryView*, const MediumLevelILInstruction&)> action;
+ std::function<bool(BinaryView*, const MediumLevelILInstruction&)> isValid;
+ };
+
static void DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view);
static void AddressPluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
static void RangePluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
static void FunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view, BNFunction* func);
+ static void LowLevelILFunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func);
+ static void LowLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func, size_t instr);
+ static void MediumLevelILFunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func);
+ static void MediumLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func, size_t instr);
static bool DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view);
static bool AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
static bool RangePluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
static bool FunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, BNFunction* func);
+ static bool LowLevelILFunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func);
+ static bool LowLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func, size_t instr);
+ static bool MediumLevelILFunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func);
+ static bool MediumLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func, size_t instr);
public:
PluginCommand(const BNPluginCommand& cmd);
@@ -3363,25 +3420,45 @@ namespace BinaryNinja
PluginCommand& operator=(const PluginCommand& cmd);
static void Register(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view)>& action);
+ const std::function<void(BinaryView* view)>& action);
static void Register(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view)>& action,
- const std::function<bool(BinaryView* view)>& isValid);
+ const std::function<void(BinaryView* view)>& action,
+ const std::function<bool(BinaryView* view)>& isValid);
static void RegisterForAddress(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view, uint64_t addr)>& action);
+ const std::function<void(BinaryView* view, uint64_t addr)>& action);
static void RegisterForAddress(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view, uint64_t addr)>& action,
- const std::function<bool(BinaryView* view, uint64_t addr)>& isValid);
+ const std::function<void(BinaryView* view, uint64_t addr)>& action,
+ const std::function<bool(BinaryView* view, uint64_t addr)>& isValid);
static void RegisterForRange(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view, uint64_t addr, uint64_t len)>& action);
+ const std::function<void(BinaryView* view, uint64_t addr, uint64_t len)>& action);
static void RegisterForRange(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view, uint64_t addr, uint64_t len)>& action,
- const std::function<bool(BinaryView* view, uint64_t addr, uint64_t len)>& isValid);
+ const std::function<void(BinaryView* view, uint64_t addr, uint64_t len)>& action,
+ const std::function<bool(BinaryView* view, uint64_t addr, uint64_t len)>& isValid);
static void RegisterForFunction(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view, Function* func)>& action);
+ const std::function<void(BinaryView* view, Function* func)>& action);
static void RegisterForFunction(const std::string& name, const std::string& description,
- const std::function<void(BinaryView* view, Function* func)>& action,
- const std::function<bool(BinaryView* view, Function* func)>& isValid);
+ const std::function<void(BinaryView* view, Function* func)>& action,
+ const std::function<bool(BinaryView* view, Function* func)>& isValid);
+ static void RegisterForLowLevelILFunction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, LowLevelILFunction* func)>& action);
+ static void RegisterForLowLevelILFunction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, LowLevelILFunction* func)>& action,
+ const std::function<bool(BinaryView* view, LowLevelILFunction* func)>& isValid);
+ static void RegisterForLowLevelILInstruction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, const LowLevelILInstruction& instr)>& action);
+ static void RegisterForLowLevelILInstruction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, const LowLevelILInstruction& instr)>& action,
+ const std::function<bool(BinaryView* view, const LowLevelILInstruction& instr)>& isValid);
+ static void RegisterForMediumLevelILFunction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, MediumLevelILFunction* func)>& action);
+ static void RegisterForMediumLevelILFunction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, MediumLevelILFunction* func)>& action,
+ const std::function<bool(BinaryView* view, MediumLevelILFunction* func)>& isValid);
+ static void RegisterForMediumLevelILInstruction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, const MediumLevelILInstruction& instr)>& action);
+ static void RegisterForMediumLevelILInstruction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, const MediumLevelILInstruction& instr)>& action,
+ const std::function<bool(BinaryView* view, const MediumLevelILInstruction& instr)>& isValid);
static std::vector<PluginCommand> GetList();
static std::vector<PluginCommand> GetValidList(const PluginCommandContext& ctxt);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index cb4b9eb9..69c5e61b 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1205,6 +1205,7 @@ extern "C"
struct BNDisassemblyTextLine
{
uint64_t addr;
+ size_t instrIndex;
BNInstructionTextToken* tokens;
size_t count;
};
@@ -1365,7 +1366,11 @@ extern "C"
DefaultPluginCommand,
AddressPluginCommand,
RangePluginCommand,
- FunctionPluginCommand
+ FunctionPluginCommand,
+ LowLevelILFunctionPluginCommand,
+ LowLevelILInstructionPluginCommand,
+ MediumLevelILFunctionPluginCommand,
+ MediumLevelILInstructionPluginCommand
};
struct BNPluginCommand
@@ -1379,11 +1384,19 @@ extern "C"
void (*addressCommand)(void* ctxt, BNBinaryView* view, uint64_t addr);
void (*rangeCommand)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
void (*functionCommand)(void* ctxt, BNBinaryView* view, BNFunction* func);
+ void (*lowLevelILFunctionCommand)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func);
+ void (*lowLevelILInstructionCommand)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func, size_t instr);
+ void (*mediumLevelILFunctionCommand)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func);
+ void (*mediumLevelILInstructionCommand)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func, size_t instr);
bool (*defaultIsValid)(void* ctxt, BNBinaryView* view);
bool (*addressIsValid)(void* ctxt, BNBinaryView* view, uint64_t addr);
bool (*rangeIsValid)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len);
bool (*functionIsValid)(void* ctxt, BNBinaryView* view, BNFunction* func);
+ bool (*lowLevelILFunctionIsValid)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func);
+ bool (*lowLevelILInstructionIsValid)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func, size_t instr);
+ bool (*mediumLevelILFunctionIsValid)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func);
+ bool (*mediumLevelILInstructionIsValid)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func, size_t instr);
};
struct BNCustomCallingConvention
@@ -2347,6 +2360,11 @@ extern "C"
BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlockDominanceFrontier(BNBasicBlock* block, size_t* count);
BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlockIteratedDominanceFrontier(BNBasicBlock** blocks,
size_t incomingCount, size_t* outputCount);
+ BINARYNINJACOREAPI bool BNIsILBasicBlock(BNBasicBlock* block);
+ BINARYNINJACOREAPI bool BNIsLowLevelILBasicBlock(BNBasicBlock* block);
+ BINARYNINJACOREAPI bool BNIsMediumLevelILBasicBlock(BNBasicBlock* block);
+ BINARYNINJACOREAPI BNLowLevelILFunction* BNGetBasicBlockLowLevelILFunction(BNBasicBlock* block);
+ BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetBasicBlockMediumLevelILFunction(BNBasicBlock* block);
BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetBasicBlockDisassemblyText(BNBasicBlock* block,
BNDisassemblySettings* settings, size_t* count);
@@ -2547,6 +2565,11 @@ extern "C"
BINARYNINJACOREAPI void BNSetFunctionGraphCompleteCallback(BNFunctionGraph* graph, void* ctxt, void (*func)(void* ctxt));
BINARYNINJACOREAPI void BNAbortFunctionGraph(BNFunctionGraph* graph);
BINARYNINJACOREAPI BNFunctionGraphType BNGetFunctionGraphType(BNFunctionGraph* graph);
+ BINARYNINJACOREAPI bool BNIsILFunctionGraph(BNFunctionGraph* graph);
+ BINARYNINJACOREAPI bool BNIsLowLevelILFunctionGraph(BNFunctionGraph* graph);
+ BINARYNINJACOREAPI bool BNIsMediumLevelILFunctionGraph(BNFunctionGraph* graph);
+ BINARYNINJACOREAPI BNLowLevelILFunction* BNGetFunctionGraphLowLevelILFunction(BNFunctionGraph* graph);
+ BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetFunctionGraphMediumLevelILFunction(BNFunctionGraph* graph);
BINARYNINJACOREAPI BNFunctionGraphBlock** BNGetFunctionGraphBlocks(BNFunctionGraph* graph, size_t* count);
BINARYNINJACOREAPI BNFunctionGraphBlock** BNGetFunctionGraphBlocksInRegion(
@@ -3017,29 +3040,45 @@ extern "C"
// Plugin commands
BINARYNINJACOREAPI void BNRegisterPluginCommand(const char* name, const char* description,
- void (*action)(void* ctxt, BNBinaryView* view),
- bool (*isValid)(void* ctxt, BNBinaryView* view), void* context);
+ void (*action)(void* ctxt, BNBinaryView* view), bool (*isValid)(void* ctxt, BNBinaryView* view), void* context);
BINARYNINJACOREAPI void BNRegisterPluginCommandForAddress(const char* name, const char* description,
- void (*action)(void* ctxt, BNBinaryView* view, uint64_t addr),
- bool (*isValid)(void* ctxt, BNBinaryView* view, uint64_t addr),
- void* context);
+ void (*action)(void* ctxt, BNBinaryView* view, uint64_t addr),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, uint64_t addr), void* context);
BINARYNINJACOREAPI void BNRegisterPluginCommandForRange(const char* name, const char* description,
- void (*action)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len),
- bool (*isValid)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len),
- void* context);
+ void (*action)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len), void* context);
BINARYNINJACOREAPI void BNRegisterPluginCommandForFunction(const char* name, const char* description,
- void (*action)(void* ctxt, BNBinaryView* view, BNFunction* func),
- bool (*isValid)(void* ctxt, BNBinaryView* view, BNFunction* func),
- void* context);
+ void (*action)(void* ctxt, BNBinaryView* view, BNFunction* func),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNFunction* func), void* context);
+ BINARYNINJACOREAPI void BNRegisterPluginCommandForLowLevelILFunction(const char* name, const char* description,
+ void (*action)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func), void* context);
+ BINARYNINJACOREAPI void BNRegisterPluginCommandForLowLevelILInstruction(const char* name, const char* description,
+ void (*action)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func, size_t instr),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNLowLevelILFunction* func, size_t instr), void* context);
+ BINARYNINJACOREAPI void BNRegisterPluginCommandForMediumLevelILFunction(const char* name, const char* description,
+ void (*action)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func), void* context);
+ BINARYNINJACOREAPI void BNRegisterPluginCommandForMediumLevelILInstruction(const char* name, const char* description,
+ void (*action)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func, size_t instr),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNMediumLevelILFunction* func, size_t instr), void* context);
BINARYNINJACOREAPI BNPluginCommand* BNGetAllPluginCommands(size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommands(BNBinaryView* view, size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForAddress(BNBinaryView* view, uint64_t addr,
- size_t* count);
+ size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForRange(BNBinaryView* view, uint64_t addr,
- uint64_t len, size_t* count);
+ uint64_t len, size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForFunction(BNBinaryView* view, BNFunction* func,
- size_t* count);
+ size_t* count);
+ BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForLowLevelILFunction(BNBinaryView* view,
+ BNLowLevelILFunction* func, size_t* count);
+ BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForLowLevelILInstruction(BNBinaryView* view,
+ BNLowLevelILFunction* func, size_t instr, size_t* count);
+ BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForMediumLevelILFunction(BNBinaryView* view,
+ BNMediumLevelILFunction* func, size_t* count);
+ BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForMediumLevelILInstruction(BNBinaryView* view,
+ BNMediumLevelILFunction* func, size_t instr, size_t* count);
BINARYNINJACOREAPI void BNFreePluginCommandList(BNPluginCommand* commands);
// Calling conventions
diff --git a/binaryview.cpp b/binaryview.cpp
index 8dcae40f..0a9a7118 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -1459,6 +1459,7 @@ vector<LinearDisassemblyLine> BinaryView::GetPreviousLinearDisassemblyLines(Line
line.block = lines[i].block ? new BasicBlock(BNNewBasicBlockReference(lines[i].block)) : nullptr;
line.lineOffset = lines[i].lineOffset;
line.contents.addr = lines[i].contents.addr;
+ line.contents.instrIndex = lines[i].contents.instrIndex;
line.contents.tokens.reserve(lines[i].contents.count);
for (size_t j = 0; j < lines[i].contents.count; j++)
{
@@ -1507,6 +1508,7 @@ vector<LinearDisassemblyLine> BinaryView::GetNextLinearDisassemblyLines(LinearDi
line.block = lines[i].block ? new BasicBlock(BNNewBasicBlockReference(lines[i].block)) : nullptr;
line.lineOffset = lines[i].lineOffset;
line.contents.addr = lines[i].contents.addr;
+ line.contents.instrIndex = lines[i].contents.instrIndex;
line.contents.tokens.reserve(lines[i].contents.count);
for (size_t j = 0; j < lines[i].contents.count; j++)
{
diff --git a/function.cpp b/function.cpp
index 1e91f8f3..835ab144 100644
--- a/function.cpp
+++ b/function.cpp
@@ -1337,6 +1337,7 @@ vector<DisassemblyTextLine> Function::GetTypeTokens(DisassemblySettings* setting
{
DisassemblyTextLine line;
line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
line.tokens.reserve(lines[i].count);
for (size_t j = 0; j < lines[i].count; j++)
{
diff --git a/functiongraph.cpp b/functiongraph.cpp
index a743254e..9948d70e 100644
--- a/functiongraph.cpp
+++ b/functiongraph.cpp
@@ -186,3 +186,39 @@ void FunctionGraph::SetOption(BNDisassemblyOption option, bool state)
{
BNSetFunctionGraphOption(m_graph, option, state);
}
+
+
+bool FunctionGraph::IsILGraph() const
+{
+ return BNIsILFunctionGraph(m_graph);
+}
+
+
+bool FunctionGraph::IsLowLevelILGraph() const
+{
+ return BNIsLowLevelILFunctionGraph(m_graph);
+}
+
+
+bool FunctionGraph::IsMediumLevelILGraph() const
+{
+ return BNIsMediumLevelILFunctionGraph(m_graph);
+}
+
+
+Ref<LowLevelILFunction> FunctionGraph::GetLowLevelILFunction() const
+{
+ BNLowLevelILFunction* func = BNGetFunctionGraphLowLevelILFunction(m_graph);
+ if (!func)
+ return nullptr;
+ return new LowLevelILFunction(func);
+}
+
+
+Ref<MediumLevelILFunction> FunctionGraph::GetMediumLevelILFunction() const
+{
+ BNMediumLevelILFunction* func = BNGetFunctionGraphMediumLevelILFunction(m_graph);
+ if (!func)
+ return nullptr;
+ return new MediumLevelILFunction(func);
+}
diff --git a/functiongraphblock.cpp b/functiongraphblock.cpp
index 06a35eee..469fb175 100644
--- a/functiongraphblock.cpp
+++ b/functiongraphblock.cpp
@@ -94,6 +94,7 @@ const vector<DisassemblyTextLine>& FunctionGraphBlock::GetLines()
{
DisassemblyTextLine line;
line.addr = lines[i].addr;
+ line.instrIndex = lines[i].instrIndex;
line.tokens.reserve(lines[i].count);
for (size_t j = 0; j < lines[i].count; j++)
{
diff --git a/plugin.cpp b/plugin.cpp
index 972ce28b..22befd65 100644
--- a/plugin.cpp
+++ b/plugin.cpp
@@ -19,6 +19,8 @@
// IN THE SOFTWARE.
#include "binaryninjaapi.h"
+#include "lowlevelilinstruction.h"
+#include "mediumlevelilinstruction.h"
using namespace BinaryNinja;
using namespace std;
@@ -27,6 +29,7 @@ using namespace std;
PluginCommandContext::PluginCommandContext()
{
address = length = 0;
+ instrIndex = BN_INVALID_EXPR;
}
@@ -97,6 +100,48 @@ void PluginCommand::FunctionPluginCommandActionCallback(void* ctxt, BNBinaryView
}
+void PluginCommand::LowLevelILFunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func)
+{
+ RegisteredLowLevelILFunctionCommand* cmd = (RegisteredLowLevelILFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<LowLevelILFunction> funcObject = new LowLevelILFunction(BNNewLowLevelILFunctionReference(func));
+ cmd->action(viewObject, funcObject);
+}
+
+
+void PluginCommand::LowLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func, size_t instr)
+{
+ RegisteredLowLevelILInstructionCommand* cmd = (RegisteredLowLevelILInstructionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<LowLevelILFunction> funcObject = new LowLevelILFunction(BNNewLowLevelILFunctionReference(func));
+ LowLevelILInstruction instrObject = funcObject->GetInstruction(instr);
+ cmd->action(viewObject, instrObject);
+}
+
+
+void PluginCommand::MediumLevelILFunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func)
+{
+ RegisteredMediumLevelILFunctionCommand* cmd = (RegisteredMediumLevelILFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<MediumLevelILFunction> funcObject = new MediumLevelILFunction(BNNewMediumLevelILFunctionReference(func));
+ cmd->action(viewObject, funcObject);
+}
+
+
+void PluginCommand::MediumLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func, size_t instr)
+{
+ RegisteredMediumLevelILInstructionCommand* cmd = (RegisteredMediumLevelILInstructionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<MediumLevelILFunction> funcObject = new MediumLevelILFunction(BNNewMediumLevelILFunctionReference(func));
+ MediumLevelILInstruction instrObject = funcObject->GetInstruction(instr);
+ cmd->action(viewObject, instrObject);
+}
+
+
bool PluginCommand::DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view)
{
RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
@@ -130,6 +175,48 @@ bool PluginCommand::FunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryVie
}
+bool PluginCommand::LowLevelILFunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func)
+{
+ RegisteredLowLevelILFunctionCommand* cmd = (RegisteredLowLevelILFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<LowLevelILFunction> funcObject = new LowLevelILFunction(BNNewLowLevelILFunctionReference(func));
+ return cmd->isValid(viewObject, funcObject);
+}
+
+
+bool PluginCommand::LowLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNLowLevelILFunction* func, size_t instr)
+{
+ RegisteredLowLevelILInstructionCommand* cmd = (RegisteredLowLevelILInstructionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<LowLevelILFunction> funcObject = new LowLevelILFunction(BNNewLowLevelILFunctionReference(func));
+ LowLevelILInstruction instrObject = funcObject->GetInstruction(instr);
+ return cmd->isValid(viewObject, instrObject);
+}
+
+
+bool PluginCommand::MediumLevelILFunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func)
+{
+ RegisteredMediumLevelILFunctionCommand* cmd = (RegisteredMediumLevelILFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<MediumLevelILFunction> funcObject = new MediumLevelILFunction(BNNewMediumLevelILFunctionReference(func));
+ return cmd->isValid(viewObject, funcObject);
+}
+
+
+bool PluginCommand::MediumLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNMediumLevelILFunction* func, size_t instr)
+{
+ RegisteredMediumLevelILInstructionCommand* cmd = (RegisteredMediumLevelILInstructionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<MediumLevelILFunction> funcObject = new MediumLevelILFunction(BNNewMediumLevelILFunctionReference(func));
+ MediumLevelILInstruction instrObject = funcObject->GetInstruction(instr);
+ return cmd->isValid(viewObject, instrObject);
+}
+
+
void PluginCommand::Register(const string& name, const string& description,
const function<void(BinaryView* view)>& action)
{
@@ -206,6 +293,89 @@ void PluginCommand::RegisterForFunction(const string& name, const string& descri
}
+void PluginCommand::RegisterForLowLevelILFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, LowLevelILFunction* func)>& action)
+{
+ RegisterForLowLevelILFunction(name, description, action, [](BinaryView*, LowLevelILFunction*) { return true; });
+}
+
+
+void PluginCommand::RegisterForLowLevelILFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, LowLevelILFunction* func)>& action,
+ const function<bool(BinaryView* view, LowLevelILFunction* func)>& isValid)
+{
+ RegisteredLowLevelILFunctionCommand* cmd = new RegisteredLowLevelILFunctionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForLowLevelILFunction(name.c_str(), description.c_str(),
+ LowLevelILFunctionPluginCommandActionCallback,
+ LowLevelILFunctionPluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForLowLevelILInstruction(const string& name, const string& description,
+ const function<void(BinaryView* view, const LowLevelILInstruction& instr)>& action)
+{
+ RegisterForLowLevelILInstruction(name, description, action,
+ [](BinaryView*, const LowLevelILInstruction&) { return true; });
+}
+
+
+void PluginCommand::RegisterForLowLevelILInstruction(const string& name, const string& description,
+ const function<void(BinaryView* view, const LowLevelILInstruction& instr)>& action,
+ const function<bool(BinaryView* view, const LowLevelILInstruction& instr)>& isValid)
+{
+ RegisteredLowLevelILInstructionCommand* cmd = new RegisteredLowLevelILInstructionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForLowLevelILInstruction(name.c_str(), description.c_str(),
+ LowLevelILInstructionPluginCommandActionCallback,
+ LowLevelILInstructionPluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForMediumLevelILFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, MediumLevelILFunction* func)>& action)
+{
+ RegisterForMediumLevelILFunction(name, description, action,
+ [](BinaryView*, MediumLevelILFunction*) { return true; });
+}
+
+
+void PluginCommand::RegisterForMediumLevelILFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, MediumLevelILFunction* func)>& action,
+ const function<bool(BinaryView* view, MediumLevelILFunction* func)>& isValid)
+{
+ RegisteredMediumLevelILFunctionCommand* cmd = new RegisteredMediumLevelILFunctionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForMediumLevelILFunction(name.c_str(), description.c_str(),
+ MediumLevelILFunctionPluginCommandActionCallback,
+ MediumLevelILFunctionPluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForMediumLevelILInstruction(const string& name, const string& description,
+ const function<void(BinaryView* view, const MediumLevelILInstruction& instr)>& action)
+{
+ RegisterForMediumLevelILInstruction(name, description, action,
+ [](BinaryView*, const MediumLevelILInstruction&) { return true; });
+}
+
+
+void PluginCommand::RegisterForMediumLevelILInstruction(const string& name, const string& description,
+ const function<void(BinaryView* view, const MediumLevelILInstruction& instr)>& action,
+ const function<bool(BinaryView* view, const MediumLevelILInstruction& instr)>& isValid)
+{
+ RegisteredMediumLevelILInstructionCommand* cmd = new RegisteredMediumLevelILInstructionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForMediumLevelILInstruction(name.c_str(), description.c_str(),
+ MediumLevelILInstructionPluginCommandActionCallback,
+ MediumLevelILInstructionPluginCommandIsValidCallback, cmd);
+}
+
+
vector<PluginCommand> PluginCommand::GetList()
{
vector<PluginCommand> result;
@@ -259,6 +429,38 @@ bool PluginCommand::IsValid(const PluginCommandContext& ctxt) const
if (!m_command.functionIsValid)
return true;
return m_command.functionIsValid(m_command.context, ctxt.view->GetObject(), ctxt.function->GetObject());
+ case LowLevelILFunctionPluginCommand:
+ if (!ctxt.lowLevelILFunction)
+ return false;
+ if (!m_command.lowLevelILFunctionIsValid)
+ return true;
+ return m_command.lowLevelILFunctionIsValid(m_command.context, ctxt.view->GetObject(),
+ ctxt.lowLevelILFunction->GetObject());
+ case LowLevelILInstructionPluginCommand:
+ if (!ctxt.lowLevelILFunction)
+ return false;
+ if (ctxt.instrIndex == BN_INVALID_EXPR)
+ return false;
+ if (!m_command.lowLevelILInstructionIsValid)
+ return true;
+ return m_command.lowLevelILInstructionIsValid(m_command.context, ctxt.view->GetObject(),
+ ctxt.lowLevelILFunction->GetObject(), ctxt.instrIndex);
+ case MediumLevelILFunctionPluginCommand:
+ if (!ctxt.mediumLevelILFunction)
+ return false;
+ if (!m_command.mediumLevelILFunctionIsValid)
+ return true;
+ return m_command.mediumLevelILFunctionIsValid(m_command.context, ctxt.view->GetObject(),
+ ctxt.mediumLevelILFunction->GetObject());
+ case MediumLevelILInstructionPluginCommand:
+ if (!ctxt.mediumLevelILFunction)
+ return false;
+ if (ctxt.instrIndex == BN_INVALID_EXPR)
+ return false;
+ if (!m_command.mediumLevelILInstructionIsValid)
+ return true;
+ return m_command.mediumLevelILInstructionIsValid(m_command.context, ctxt.view->GetObject(),
+ ctxt.mediumLevelILFunction->GetObject(), ctxt.instrIndex);
default:
return false;
}
@@ -284,6 +486,22 @@ void PluginCommand::Execute(const PluginCommandContext& ctxt) const
case FunctionPluginCommand:
m_command.functionCommand(m_command.context, ctxt.view->GetObject(), ctxt.function->GetObject());
break;
+ case LowLevelILFunctionPluginCommand:
+ m_command.lowLevelILFunctionCommand(m_command.context, ctxt.view->GetObject(),
+ ctxt.lowLevelILFunction->GetObject());
+ break;
+ case LowLevelILInstructionPluginCommand:
+ m_command.lowLevelILInstructionCommand(m_command.context, ctxt.view->GetObject(),
+ ctxt.lowLevelILFunction->GetObject(), ctxt.instrIndex);
+ break;
+ case MediumLevelILFunctionPluginCommand:
+ m_command.mediumLevelILFunctionCommand(m_command.context, ctxt.view->GetObject(),
+ ctxt.mediumLevelILFunction->GetObject());
+ break;
+ case MediumLevelILInstructionPluginCommand:
+ m_command.mediumLevelILInstructionCommand(m_command.context, ctxt.view->GetObject(),
+ ctxt.mediumLevelILFunction->GetObject(), ctxt.instrIndex);
+ break;
default:
break;
}
diff --git a/python/basicblock.py b/python/basicblock.py
index 1d932c5e..4dc783c3 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -256,6 +256,21 @@ class BasicBlock(object):
def highlight(self, value):
self.set_user_highlight(value)
+ @property
+ def is_il(self):
+ """Whether the basic block contains IL"""
+ return core.BNIsILBasicBlock(self.handle)
+
+ @property
+ def is_low_level_il(self):
+ """Whether the basic block contains Low Level IL"""
+ return core.BNIsLowLevelILBasicBlock(self.handle)
+
+ @property
+ def is_medium_level_il(self):
+ """Whether the basic block contains Medium Level IL"""
+ return core.BNIsMediumLevelILBasicBlock(self.handle)
+
@classmethod
def get_iterated_dominance_frontier(self, blocks):
if len(blocks) == 0:
@@ -322,6 +337,10 @@ class BasicBlock(object):
result = []
for i in xrange(0, count.value):
addr = lines[i].addr
+ if (lines[i].instrIndex != 0xffffffffffffffff) and hasattr(self, 'il_function'):
+ il_instr = self.il_function[lines[i].instrIndex]
+ else:
+ il_instr = None
tokens = []
for j in xrange(0, lines[i].count):
token_type = InstructionTextTokenType(lines[i].tokens[j].type)
@@ -333,7 +352,7 @@ class BasicBlock(object):
confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
tokens.append(function.InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
- result.append(function.DisassemblyTextLine(addr, tokens))
+ result.append(function.DisassemblyTextLine(addr, tokens, il_instr))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
diff --git a/python/function.py b/python/function.py
index 1cc4dcac..6db44e6d 100644
--- a/python/function.py
+++ b/python/function.py
@@ -1598,9 +1598,10 @@ class AdvancedFunctionAnalysisDataRequestor(object):
class DisassemblyTextLine(object):
- def __init__(self, addr, tokens):
+ def __init__(self, addr, tokens, il_instr = None):
self.address = addr
self.tokens = tokens
+ self.il_instruction = il_instr
def __str__(self):
result = ""
@@ -1625,8 +1626,9 @@ class FunctionGraphEdge(object):
class FunctionGraphBlock(object):
- def __init__(self, handle):
+ def __init__(self, handle, graph):
self.handle = handle
+ self.graph = graph
def __del__(self):
core.BNFreeFunctionGraphBlock(self.handle)
@@ -1645,13 +1647,22 @@ class FunctionGraphBlock(object):
def basic_block(self):
"""Basic block associated with this part of the function graph (read-only)"""
block = core.BNGetFunctionGraphBasicBlock(self.handle)
- func = core.BNGetBasicBlockFunction(block)
- if func is None:
+ func_handle = core.BNGetBasicBlockFunction(block)
+ if func_handle is None:
core.BNFreeBasicBlock(block)
- block = None
+ return None
+
+ view = binaryview.BinaryView(handle = core.BNGetFunctionData(func_handle))
+ func = Function(view, func_handle)
+
+ if core.BNIsLowLevelILBasicBlock(block):
+ block = lowlevelil.LowLevelILBasicBlock(view, block,
+ lowlevelil.LowLevelILFunction(func.arch, core.BNGetBasicBlockLowLevelILFunction(block), func))
+ elif core.BNIsMediumLevelILBasicBlock(block):
+ block = mediumlevelil.MediumLevelILBasicBlock(view, block,
+ mediumlevelil.MediumLevelILFunction(func.arch, core.BNGetBasicBlockMediumLevelILFunction(block), func))
else:
- block = basicblock.BasicBlock(binaryview.BinaryView(handle = core.BNGetFunctionData(func)), block)
- core.BNFreeFunction(func)
+ block = basicblock.BasicBlock(view, block)
return block
@property
@@ -1697,9 +1708,14 @@ class FunctionGraphBlock(object):
"""Function graph block list of lines (read-only)"""
count = ctypes.c_ulonglong()
lines = core.BNGetFunctionGraphBlockLines(self.handle, count)
+ block = self.basic_block
result = []
for i in xrange(0, count.value):
addr = lines[i].addr
+ if (lines[i].instrIndex != 0xffffffffffffffff) and hasattr(block, 'il_function'):
+ il_instr = block.il_function[lines[i].instrIndex]
+ else:
+ il_instr = None
tokens = []
for j in xrange(0, lines[i].count):
token_type = InstructionTextTokenType(lines[i].tokens[j].type)
@@ -1711,7 +1727,7 @@ class FunctionGraphBlock(object):
confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
- result.append(DisassemblyTextLine(addr, tokens))
+ result.append(DisassemblyTextLine(addr, tokens, il_instr))
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
@@ -1756,9 +1772,14 @@ class FunctionGraphBlock(object):
def __iter__(self):
count = ctypes.c_ulonglong()
lines = core.BNGetFunctionGraphBlockLines(self.handle, count)
+ block = self.basic_block
try:
for i in xrange(0, count.value):
addr = lines[i].addr
+ if (lines[i].instrIndex != 0xffffffffffffffff) and hasattr(block, 'il_function'):
+ il_instr = block.il_function[lines[i].instrIndex]
+ else:
+ il_instr = None
tokens = []
for j in xrange(0, lines[i].count):
token_type = InstructionTextTokenType(lines[i].tokens[j].type)
@@ -1770,7 +1791,7 @@ class FunctionGraphBlock(object):
confidence = lines[i].tokens[j].confidence
address = lines[i].tokens[j].address
tokens.append(InstructionTextToken(token_type, text, value, size, operand, context, address, confidence))
- yield DisassemblyTextLine(addr, tokens)
+ yield DisassemblyTextLine(addr, tokens, il_instr)
finally:
core.BNFreeDisassemblyTextLines(lines, count.value)
@@ -1858,7 +1879,7 @@ class FunctionGraph(object):
blocks = core.BNGetFunctionGraphBlocks(self.handle, count)
result = []
for i in xrange(0, count.value):
- result.append(FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i])))
+ result.append(FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i]), self))
core.BNFreeFunctionGraphBlockList(blocks, count.value)
return result
@@ -1897,6 +1918,32 @@ class FunctionGraph(object):
def settings(self):
return DisassemblySettings(core.BNGetFunctionGraphSettings(self.handle))
+ @property
+ def is_il(self):
+ return core.BNIsILFunctionGraph(self.handle)
+
+ @property
+ def is_low_level_il(self):
+ return core.BNIsLowLevelILFunctionGraph(self.handle)
+
+ @property
+ def is_medium_level_il(self):
+ return core.BNIsMediumLevelILFunctionGraph(self.handle)
+
+ @property
+ def il_function(self):
+ if self.is_low_level_il:
+ il_func = core.BNGetFunctionGraphLowLevelILFunction(self.handle)
+ if not il_func:
+ return None
+ return lowlevelil.LowLevelILFunction(self.function.arch, il_func, self.function)
+ if self.is_medium_level_il:
+ il_func = core.BNGetFunctionGraphMediumLevelILFunction(self.handle)
+ if not il_func:
+ return None
+ return mediumlevelil.MediumLevelILFunction(self.function.arch, il_func, self.function)
+ return None
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
@@ -1911,7 +1958,7 @@ class FunctionGraph(object):
blocks = core.BNGetFunctionGraphBlocks(self.handle, count)
try:
for i in xrange(0, count.value):
- yield FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i]))
+ yield FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i]), self)
finally:
core.BNFreeFunctionGraphBlockList(blocks, count.value)
@@ -1954,7 +2001,7 @@ class FunctionGraph(object):
blocks = core.BNGetFunctionGraphBlocksInRegion(self.handle, left, top, right, bottom, count)
result = []
for i in xrange(0, count.value):
- result.append(FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i])))
+ result.append(FunctionGraphBlock(core.BNNewFunctionGraphBlockReference(blocks[i]), self))
core.BNFreeFunctionGraphBlockList(blocks, count.value)
return result
diff --git a/python/plugin.py b/python/plugin.py
index e0054d86..c6cd9fc0 100644
--- a/python/plugin.py
+++ b/python/plugin.py
@@ -30,6 +30,8 @@ import filemetadata
import binaryview
import function
import log
+import lowlevelil
+import mediumlevelil
class PluginCommandContext(object):
@@ -38,6 +40,7 @@ class PluginCommandContext(object):
self.address = 0
self.length = 0
self.function = None
+ self.instruction = None
class _PluginCommandMetaClass(type):
@@ -118,6 +121,50 @@ class PluginCommand(object):
log.log_error(traceback.format_exc())
@classmethod
+ def _low_level_il_function_action(cls, view, func, action):
+ try:
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetLowLevelILOwnerFunction(func))
+ func_obj = lowlevelil.LowLevelILFunction(owner.arch, core.BNNewLowLevelILFunctionReference(func), owner)
+ action(view_obj, func_obj)
+ except:
+ log.log_error(traceback.format_exc())
+
+ @classmethod
+ def _low_level_il_instruction_action(cls, view, func, instr, action):
+ try:
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetLowLevelILOwnerFunction(func))
+ func_obj = lowlevelil.LowLevelILFunction(owner.arch, core.BNNewLowLevelILFunctionReference(func), owner)
+ action(view_obj, func_obj[instr])
+ except:
+ log.log_error(traceback.format_exc())
+
+ @classmethod
+ def _medium_level_il_function_action(cls, view, func, action):
+ try:
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetMediumLevelILOwnerFunction(func))
+ func_obj = mediumlevelil.MediumLevelILFunction(owner.arch, core.BNNewMediumLevelILFunctionReference(func), owner)
+ action(view_obj, func_obj)
+ except:
+ log.log_error(traceback.format_exc())
+
+ @classmethod
+ def _medium_level_il_instruction_action(cls, view, func, instr, action):
+ try:
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetMediumLevelILOwnerFunction(func))
+ func_obj = mediumlevelil.MediumLevelILFunction(owner.arch, core.BNNewMediumLevelILFunctionReference(func), owner)
+ action(view_obj, func_obj[instr])
+ except:
+ log.log_error(traceback.format_exc())
+
+ @classmethod
def _default_is_valid(cls, view, is_valid):
try:
if is_valid is None:
@@ -167,6 +214,62 @@ class PluginCommand(object):
return False
@classmethod
+ def _low_level_il_function_is_valid(cls, view, func, is_valid):
+ try:
+ if is_valid is None:
+ return True
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetLowLevelILOwnerFunction(func))
+ func_obj = lowlevelil.LowLevelILFunction(owner.arch, core.BNNewLowLevelILFunctionReference(func), owner)
+ return is_valid(view_obj, func_obj)
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
+ @classmethod
+ def _low_level_il_instruction_is_valid(cls, view, func, instr, is_valid):
+ try:
+ if is_valid is None:
+ return True
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetLowLevelILOwnerFunction(func))
+ func_obj = lowlevelil.LowLevelILFunction(owner.arch, core.BNNewLowLevelILFunctionReference(func), owner)
+ return is_valid(view_obj, func_obj[instr])
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
+ @classmethod
+ def _medium_level_il_function_is_valid(cls, view, func, is_valid):
+ try:
+ if is_valid is None:
+ return True
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetMediumLevelILOwnerFunction(func))
+ func_obj = mediumlevelil.MediumLevelILFunction(owner.arch, core.BNNewMediumLevelILFunctionReference(func), owner)
+ return is_valid(view_obj, func_obj)
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
+ @classmethod
+ def _medium_level_il_instruction_is_valid(cls, view, func, instr, is_valid):
+ try:
+ if is_valid is None:
+ return True
+ file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ owner = function.Function(view_obj, core.BNGetMediumLevelILOwnerFunction(func))
+ func_obj = mediumlevelil.MediumLevelILFunction(owner.arch, core.BNNewMediumLevelILFunctionReference(func), owner)
+ return is_valid(view_obj, func_obj[instr])
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
+ @classmethod
def register(cls, name, description, action, is_valid = None):
"""
``register`` Register a plugin
@@ -243,6 +346,82 @@ class PluginCommand(object):
core.BNRegisterPluginCommandForFunction(name, description, action_obj, is_valid_obj, None)
@classmethod
+ def register_for_low_level_il_function(cls, name, description, action, is_valid = None):
+ """
+ ``register_for_low_level_il_function`` Register a plugin to be called with a low level IL function argument
+
+ :param str name: name of the plugin
+ :param str description: description of the plugin
+ :param action: function to call with the ``BinaryView`` and a ``LowLevelILFunction`` as arguments
+ :param is_valid: optional argument of a function passed a ``BinaryView`` to determine whether the plugin should be enabled for that view
+ :rtype: None
+
+ .. warning:: Calling ``register_for_low_level_il_function`` with the same function name will replace the existing function but will leak the memory of the original plugin.
+ """
+ startup._init_plugins()
+ action_obj = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNLowLevelILFunction))(lambda ctxt, view, func: cls._low_level_il_function_action(view, func, action))
+ is_valid_obj = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNLowLevelILFunction))(lambda ctxt, view, func: cls._low_level_il_function_is_valid(view, func, is_valid))
+ cls._registered_commands.append((action_obj, is_valid_obj))
+ core.BNRegisterPluginCommandForLowLevelILFunction(name, description, action_obj, is_valid_obj, None)
+
+ @classmethod
+ def register_for_low_level_il_instruction(cls, name, description, action, is_valid = None):
+ """
+ ``register_for_low_level_il_instruction`` Register a plugin to be called with a low level IL instruction argument
+
+ :param str name: name of the plugin
+ :param str description: description of the plugin
+ :param action: function to call with the ``BinaryView`` and a ``LowLevelILInstruction`` as arguments
+ :param is_valid: optional argument of a function passed a ``BinaryView`` to determine whether the plugin should be enabled for that view
+ :rtype: None
+
+ .. warning:: Calling ``register_for_low_level_il_instruction`` with the same function name will replace the existing function but will leak the memory of the original plugin.
+ """
+ startup._init_plugins()
+ action_obj = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNLowLevelILFunction), ctypes.c_ulonglong)(lambda ctxt, view, func, instr: cls._low_level_il_instruction_action(view, func, instr, action))
+ is_valid_obj = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNLowLevelILFunction), ctypes.c_ulonglong)(lambda ctxt, view, func, instr: cls._low_level_il_instruction_is_valid(view, func, instr, is_valid))
+ cls._registered_commands.append((action_obj, is_valid_obj))
+ core.BNRegisterPluginCommandForLowLevelILInstruction(name, description, action_obj, is_valid_obj, None)
+
+ @classmethod
+ def register_for_medium_level_il_function(cls, name, description, action, is_valid = None):
+ """
+ ``register_for_medium_level_il_function`` Register a plugin to be called with a medium level IL function argument
+
+ :param str name: name of the plugin
+ :param str description: description of the plugin
+ :param action: function to call with the ``BinaryView`` and a ``MediumLevelILFunction`` as arguments
+ :param is_valid: optional argument of a function passed a ``BinaryView`` to determine whether the plugin should be enabled for that view
+ :rtype: None
+
+ .. warning:: Calling ``register_for_medium_level_il_function`` with the same function name will replace the existing function but will leak the memory of the original plugin.
+ """
+ startup._init_plugins()
+ action_obj = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNMediumLevelILFunction))(lambda ctxt, view, func: cls._medium_level_il_function_action(view, func, action))
+ is_valid_obj = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNMediumLevelILFunction))(lambda ctxt, view, func: cls._medium_level_il_function_is_valid(view, func, is_valid))
+ cls._registered_commands.append((action_obj, is_valid_obj))
+ core.BNRegisterPluginCommandForMediumLevelILFunction(name, description, action_obj, is_valid_obj, None)
+
+ @classmethod
+ def register_for_medium_level_il_instruction(cls, name, description, action, is_valid = None):
+ """
+ ``register_for_medium_level_il_instruction`` Register a plugin to be called with a medium level IL instruction argument
+
+ :param str name: name of the plugin
+ :param str description: description of the plugin
+ :param action: function to call with the ``BinaryView`` and a ``MediumLevelILInstruction`` as arguments
+ :param is_valid: optional argument of a function passed a ``BinaryView`` to determine whether the plugin should be enabled for that view
+ :rtype: None
+
+ .. warning:: Calling ``register_for_medium_level_il_instruction`` with the same function name will replace the existing function but will leak the memory of the original plugin.
+ """
+ startup._init_plugins()
+ action_obj = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNMediumLevelILFunction), ctypes.c_ulonglong)(lambda ctxt, view, func, instr: cls._medium_level_il_instruction_action(view, func, instr, action))
+ is_valid_obj = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNMediumLevelILFunction), ctypes.c_ulonglong)(lambda ctxt, view, func, instr: cls._medium_level_il_instruction_is_valid(view, func, instr, is_valid))
+ cls._registered_commands.append((action_obj, is_valid_obj))
+ core.BNRegisterPluginCommandForMediumLevelILInstruction(name, description, action_obj, is_valid_obj, None)
+
+ @classmethod
def get_valid_list(cls, context):
"""Dict of registered plugins"""
commands = cls.list
@@ -275,6 +454,36 @@ class PluginCommand(object):
if not self.command.functionIsValid:
return True
return self.command.functionIsValid(self.command.context, context.view.handle, context.function.handle)
+ elif self.command.type == PluginCommandType.LowLevelILFunctionPluginCommand:
+ if context.function is None:
+ return False
+ if not self.command.lowLevelILFunctionIsValid:
+ return True
+ return self.command.lowLevelILFunctionIsValid(self.command.context, context.view.handle, context.function.handle)
+ elif self.command.type == PluginCommandType.LowLevelILInstructionPluginCommand:
+ if context.instruction is None:
+ return False
+ if not isinstance(context.instruction, lowlevelil.LowLevelILInstruction):
+ return False
+ if not self.command.lowLevelILInstructionIsValid:
+ return True
+ return self.command.lowLevelILInstructionIsValid(self.command.context, context.view.handle,
+ context.instruction.function.handle, context.instruction.instr_index)
+ elif self.command.type == PluginCommandType.MediumLevelILFunctionPluginCommand:
+ if context.function is None:
+ return False
+ if not self.command.mediumLevelILFunctionIsValid:
+ return True
+ return self.command.mediumLevelILFunctionIsValid(self.command.context, context.view.handle, context.function.handle)
+ elif self.command.type == PluginCommandType.MediumLevelILInstructionPluginCommand:
+ if context.instruction is None:
+ return False
+ if not isinstance(context.instruction, mediumlevelil.MediumLevelILInstruction):
+ return False
+ if not self.command.mediumLevelILInstructionIsValid:
+ return True
+ return self.command.mediumLevelILInstructionIsValid(self.command.context, context.view.handle,
+ context.instruction.function.handle, context.instruction.instr_index)
return False
def execute(self, context):
@@ -288,6 +497,16 @@ class PluginCommand(object):
self.command.rangeCommand(self.command.context, context.view.handle, context.address, context.length)
elif self.command.type == PluginCommandType.FunctionPluginCommand:
self.command.functionCommand(self.command.context, context.view.handle, context.function.handle)
+ elif self.command.type == PluginCommandType.LowLevelILFunctionPluginCommand:
+ self.command.lowLevelILFunctionCommand(self.command.context, context.view.handle, context.function.handle)
+ elif self.command.type == PluginCommandType.LowLevelILInstructionPluginCommand:
+ self.command.lowLevelILInstructionCommand(self.command.context, context.view.handle,
+ context.instruction.function.handle, context.instruction.instr_index)
+ elif self.command.type == PluginCommandType.MediumLevelILFunctionPluginCommand:
+ self.command.mediumLevelILFunctionCommand(self.command.context, context.view.handle, context.function.handle)
+ elif self.command.type == PluginCommandType.MediumLevelILInstructionPluginCommand:
+ self.command.mediumLevelILInstructionCommand(self.command.context, context.view.handle,
+ context.instruction.function.handle, context.instruction.instr_index)
def __repr__(self):
return "<PluginCommand: %s>" % self.name