summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2021-10-02 19:00:41 -0400
committerKyleMiles <krm504@nyu.edu>2021-10-05 18:06:43 -0400
commitc4f4bf5be39c224b619a5928d380d91122ecf1d8 (patch)
tree6d6f0ee095259b05d2e2707621263cbb8b24981b
parentc80d3d99b9e11c4120cd3a36349d8161f01c7a24 (diff)
More HLIL API parity; Resolves #2363
-rw-r--r--basicblock.cpp9
-rw-r--r--binaryninjaapi.h33
-rw-r--r--binaryninjacore.h20
-rw-r--r--plugin.cpp109
-rw-r--r--python/basicblock.py5
-rw-r--r--python/flowgraph.py3
-rw-r--r--python/plugin.py109
-rw-r--r--ui/action.h1
-rw-r--r--ui/flowgraphwidget.h1
-rw-r--r--ui/linearview.h1
-rw-r--r--ui/viewframe.h1
-rw-r--r--workflow.cpp9
12 files changed, 300 insertions, 1 deletions
diff --git a/basicblock.cpp b/basicblock.cpp
index 6045f6ef..d9b49749 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -484,6 +484,15 @@ Ref<MediumLevelILFunction> BasicBlock::GetMediumLevelILFunction() const
}
+Ref<HighLevelILFunction> BasicBlock::GetHighLevelILFunction() const
+{
+ BNHighLevelILFunction* func = BNGetBasicBlockHighLevelILFunction(m_object);
+ if (!func)
+ return nullptr;
+ return new HighLevelILFunction(func);
+}
+
+
bool BasicBlock::GetInstructionContainingAddress(uint64_t addr, uint64_t* start)
{
return BNGetBasicBlockInstructionContainingAddress(m_object, addr, start);
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 917341aa..6549c290 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -3161,6 +3161,7 @@ __attribute__ ((format (printf, 1, 2)))
Ref<Function> GetFunction();
Ref<LowLevelILFunction> GetLowLevelILFunction();
Ref<MediumLevelILFunction> GetMediumLevelILFunction();
+ Ref<HighLevelILFunction> GetHighLevelILFunction();
void SetBasicBlockList(std::vector<Ref<BasicBlock>> basicBlocks);
void SetLiftedILFunction(Ref<LowLevelILFunction> liftedIL);
@@ -3321,6 +3322,7 @@ __attribute__ ((format (printf, 1, 2)))
bool IsMediumLevelILBlock() const;
Ref<LowLevelILFunction> GetLowLevelILFunction() const;
Ref<MediumLevelILFunction> GetMediumLevelILFunction() const;
+ Ref<HighLevelILFunction> GetHighLevelILFunction() const;
bool GetInstructionContainingAddress(uint64_t addr, uint64_t* start);
Ref<BasicBlock> GetSourceBlock() const;
@@ -4944,6 +4946,7 @@ __attribute__ ((format (printf, 1, 2)))
Ref<Function> function;
Ref<LowLevelILFunction> lowLevelILFunction;
Ref<MediumLevelILFunction> mediumLevelILFunction;
+ Ref<HighLevelILFunction> highLevelILFunction;
PluginCommandContext();
};
@@ -5000,6 +5003,18 @@ __attribute__ ((format (printf, 1, 2)))
std::function<bool(BinaryView*, const MediumLevelILInstruction&)> isValid;
};
+ struct RegisteredHighLevelILFunctionCommand
+ {
+ std::function<void(BinaryView*, HighLevelILFunction*)> action;
+ std::function<bool(BinaryView*, HighLevelILFunction*)> isValid;
+ };
+
+ struct RegisteredHighLevelILInstructionCommand
+ {
+ std::function<void(BinaryView*, const HighLevelILInstruction&)> action;
+ std::function<bool(BinaryView*, const HighLevelILInstruction&)> 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);
@@ -5012,6 +5027,10 @@ __attribute__ ((format (printf, 1, 2)))
BNMediumLevelILFunction* func);
static void MediumLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
BNMediumLevelILFunction* func, size_t instr);
+ static void HighLevelILFunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func);
+ static void HighLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func, size_t instr);
static bool DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view);
static bool AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr);
@@ -5025,6 +5044,10 @@ __attribute__ ((format (printf, 1, 2)))
BNMediumLevelILFunction* func);
static bool MediumLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
BNMediumLevelILFunction* func, size_t instr);
+ static bool HighLevelILFunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func);
+ static bool HighLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func, size_t instr);
public:
PluginCommand(const BNPluginCommand& cmd);
@@ -5073,6 +5096,16 @@ __attribute__ ((format (printf, 1, 2)))
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 void RegisterForHighLevelILFunction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, HighLevelILFunction* func)>& action);
+ static void RegisterForHighLevelILFunction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, HighLevelILFunction* func)>& action,
+ const std::function<bool(BinaryView* view, HighLevelILFunction* func)>& isValid);
+ static void RegisterForHighLevelILInstruction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, const HighLevelILInstruction& instr)>& action);
+ static void RegisterForHighLevelILInstruction(const std::string& name, const std::string& description,
+ const std::function<void(BinaryView* view, const HighLevelILInstruction& instr)>& action,
+ const std::function<bool(BinaryView* view, const HighLevelILInstruction& instr)>& isValid);
static std::vector<PluginCommand> GetList();
static std::vector<PluginCommand> GetValidList(const PluginCommandContext& ctxt);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 4396fdda..7a96db2c 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -2024,7 +2024,9 @@ extern "C"
LowLevelILFunctionPluginCommand,
LowLevelILInstructionPluginCommand,
MediumLevelILFunctionPluginCommand,
- MediumLevelILInstructionPluginCommand
+ MediumLevelILInstructionPluginCommand,
+ HighLevelILFunctionPluginCommand,
+ HighLevelILInstructionPluginCommand
};
struct BNPluginCommand
@@ -2042,6 +2044,8 @@ extern "C"
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);
+ void (*highLevelILFunctionCommand)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
+ void (*highLevelILInstructionCommand)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
bool (*defaultIsValid)(void* ctxt, BNBinaryView* view);
bool (*addressIsValid)(void* ctxt, BNBinaryView* view, uint64_t addr);
@@ -2051,6 +2055,8 @@ extern "C"
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);
+ bool (*highLevelILFunctionIsValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func);
+ bool (*highLevelILInstructionIsValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr);
};
struct BNCustomCallingConvention
@@ -3532,6 +3538,7 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI BNFunctionGraphType BNGetBasicBlockFunctionGraphType(BNBasicBlock* block);
BINARYNINJACOREAPI BNLowLevelILFunction* BNGetBasicBlockLowLevelILFunction(BNBasicBlock* block);
BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetBasicBlockMediumLevelILFunction(BNBasicBlock* block);
+ BINARYNINJACOREAPI BNHighLevelILFunction* BNGetBasicBlockHighLevelILFunction(BNBasicBlock* block);
BINARYNINJACOREAPI bool BNGetBasicBlockInstructionContainingAddress(BNBasicBlock* block,
uint64_t addr, uint64_t* start);
BINARYNINJACOREAPI BNBasicBlock* BNGetBasicBlockSourceBlock(BNBasicBlock* block);
@@ -4038,6 +4045,7 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI BNFunction* BNAnalysisContextGetFunction(BNAnalysisContext* analysisContext);
BINARYNINJACOREAPI BNLowLevelILFunction* BNAnalysisContextGetLowLevelILFunction(BNAnalysisContext* analysisContext);
BINARYNINJACOREAPI BNMediumLevelILFunction* BNAnalysisContextGetMediumLevelILFunction(BNAnalysisContext* analysisContext);
+ BINARYNINJACOREAPI BNHighLevelILFunction* BNAnalysisContextGetHighLevelILFunction(BNAnalysisContext* analysisContext);
BINARYNINJACOREAPI void BNSetBasicBlockList(BNAnalysisContext* analysisContext, BNBasicBlock** basicBlocks, size_t count);
BINARYNINJACOREAPI void BNSetLiftedILFunction(BNAnalysisContext* analysisContext, BNLowLevelILFunction* liftedIL);
@@ -4944,6 +4952,12 @@ __attribute__ ((format (printf, 1, 2)))
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 void BNRegisterPluginCommandForHighLevelILFunction(const char* name, const char* description,
+ void (*action)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func), void* context);
+ BINARYNINJACOREAPI void BNRegisterPluginCommandForHighLevelILInstruction(const char* name, const char* description,
+ void (*action)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr),
+ bool (*isValid)(void* ctxt, BNBinaryView* view, BNHighLevelILFunction* func, size_t instr), void* context);
BINARYNINJACOREAPI BNPluginCommand* BNGetAllPluginCommands(size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommands(BNBinaryView* view, size_t* count);
@@ -4961,6 +4975,10 @@ __attribute__ ((format (printf, 1, 2)))
BNMediumLevelILFunction* func, size_t* count);
BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForMediumLevelILInstruction(BNBinaryView* view,
BNMediumLevelILFunction* func, size_t instr, size_t* count);
+ BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForHighLevelILFunction(BNBinaryView* view,
+ BNHighLevelILFunction* func, size_t* count);
+ BINARYNINJACOREAPI BNPluginCommand* BNGetValidPluginCommandsForHighLevelILInstruction(BNBinaryView* view,
+ BNHighLevelILFunction* func, size_t instr, size_t* count);
BINARYNINJACOREAPI void BNFreePluginCommandList(BNPluginCommand* commands);
// Calling conventions
diff --git a/plugin.cpp b/plugin.cpp
index c786b215..c9681a63 100644
--- a/plugin.cpp
+++ b/plugin.cpp
@@ -21,6 +21,7 @@
#include "binaryninjaapi.h"
#include "lowlevelilinstruction.h"
#include "mediumlevelilinstruction.h"
+#include "highlevelilinstruction.h"
using namespace BinaryNinja;
using namespace std;
@@ -142,6 +143,27 @@ void PluginCommand::MediumLevelILInstructionPluginCommandActionCallback(void* ct
}
+void PluginCommand::HighLevelILFunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func)
+{
+ RegisteredHighLevelILFunctionCommand* cmd = (RegisteredHighLevelILFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<HighLevelILFunction> funcObject = new HighLevelILFunction(BNNewHighLevelILFunctionReference(func));
+ cmd->action(viewObject, funcObject);
+}
+
+
+void PluginCommand::HighLevelILInstructionPluginCommandActionCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func, size_t instr)
+{
+ RegisteredHighLevelILInstructionCommand* cmd = (RegisteredHighLevelILInstructionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<HighLevelILFunction> funcObject = new HighLevelILFunction(BNNewHighLevelILFunctionReference(func));
+ HighLevelILInstruction instrObject = funcObject->GetInstruction(instr);
+ cmd->action(viewObject, instrObject);
+}
+
+
bool PluginCommand::DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view)
{
RegisteredDefaultCommand* cmd = (RegisteredDefaultCommand*)ctxt;
@@ -217,6 +239,27 @@ bool PluginCommand::MediumLevelILInstructionPluginCommandIsValidCallback(void* c
}
+bool PluginCommand::HighLevelILFunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func)
+{
+ RegisteredHighLevelILFunctionCommand* cmd = (RegisteredHighLevelILFunctionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<HighLevelILFunction> funcObject = new HighLevelILFunction(BNNewHighLevelILFunctionReference(func));
+ return cmd->isValid(viewObject, funcObject);
+}
+
+
+bool PluginCommand::HighLevelILInstructionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view,
+ BNHighLevelILFunction* func, size_t instr)
+{
+ RegisteredHighLevelILInstructionCommand* cmd = (RegisteredHighLevelILInstructionCommand*)ctxt;
+ Ref<BinaryView> viewObject = new BinaryView(BNNewViewReference(view));
+ Ref<HighLevelILFunction> funcObject = new HighLevelILFunction(BNNewHighLevelILFunctionReference(func));
+ HighLevelILInstruction instrObject = funcObject->GetInstruction(instr);
+ return cmd->isValid(viewObject, instrObject);
+}
+
+
void PluginCommand::Register(const string& name, const string& description,
const function<void(BinaryView* view)>& action)
{
@@ -376,6 +419,48 @@ void PluginCommand::RegisterForMediumLevelILInstruction(const string& name, cons
}
+void PluginCommand::RegisterForHighLevelILFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, HighLevelILFunction* func)>& action)
+{
+ RegisterForHighLevelILFunction(name, description, action,
+ [](BinaryView*, HighLevelILFunction*) { return true; });
+}
+
+
+void PluginCommand::RegisterForHighLevelILFunction(const string& name, const string& description,
+ const function<void(BinaryView* view, HighLevelILFunction* func)>& action,
+ const function<bool(BinaryView* view, HighLevelILFunction* func)>& isValid)
+{
+ RegisteredHighLevelILFunctionCommand* cmd = new RegisteredHighLevelILFunctionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForHighLevelILFunction(name.c_str(), description.c_str(),
+ HighLevelILFunctionPluginCommandActionCallback,
+ HighLevelILFunctionPluginCommandIsValidCallback, cmd);
+}
+
+
+void PluginCommand::RegisterForHighLevelILInstruction(const string& name, const string& description,
+ const function<void(BinaryView* view, const HighLevelILInstruction& instr)>& action)
+{
+ RegisterForHighLevelILInstruction(name, description, action,
+ [](BinaryView*, const HighLevelILInstruction&) { return true; });
+}
+
+
+void PluginCommand::RegisterForHighLevelILInstruction(const string& name, const string& description,
+ const function<void(BinaryView* view, const HighLevelILInstruction& instr)>& action,
+ const function<bool(BinaryView* view, const HighLevelILInstruction& instr)>& isValid)
+{
+ RegisteredHighLevelILInstructionCommand* cmd = new RegisteredHighLevelILInstructionCommand;
+ cmd->action = action;
+ cmd->isValid = isValid;
+ BNRegisterPluginCommandForHighLevelILInstruction(name.c_str(), description.c_str(),
+ HighLevelILInstructionPluginCommandActionCallback,
+ HighLevelILInstructionPluginCommandIsValidCallback, cmd);
+}
+
+
vector<PluginCommand> PluginCommand::GetList()
{
vector<PluginCommand> result;
@@ -461,6 +546,22 @@ bool PluginCommand::IsValid(const PluginCommandContext& ctxt) const
return true;
return m_command.mediumLevelILInstructionIsValid(m_command.context, ctxt.binaryView->GetObject(),
ctxt.mediumLevelILFunction->GetObject(), ctxt.instrIndex);
+ case HighLevelILFunctionPluginCommand:
+ if (!ctxt.highLevelILFunction)
+ return false;
+ if (!m_command.highLevelILFunctionIsValid)
+ return true;
+ return m_command.highLevelILFunctionIsValid(m_command.context, ctxt.binaryView->GetObject(),
+ ctxt.highLevelILFunction->GetObject());
+ case HighLevelILInstructionPluginCommand:
+ if (!ctxt.highLevelILFunction)
+ return false;
+ if (ctxt.instrIndex == BN_INVALID_EXPR)
+ return false;
+ if (!m_command.highLevelILInstructionIsValid)
+ return true;
+ return m_command.highLevelILInstructionIsValid(m_command.context, ctxt.binaryView->GetObject(),
+ ctxt.highLevelILFunction->GetObject(), ctxt.instrIndex);
default:
return false;
}
@@ -502,6 +603,14 @@ void PluginCommand::Execute(const PluginCommandContext& ctxt) const
m_command.mediumLevelILInstructionCommand(m_command.context, ctxt.binaryView->GetObject(),
ctxt.mediumLevelILFunction->GetObject(), ctxt.instrIndex);
break;
+ case HighLevelILFunctionPluginCommand:
+ m_command.highLevelILFunctionCommand(m_command.context, ctxt.binaryView->GetObject(),
+ ctxt.highLevelILFunction->GetObject());
+ break;
+ case HighLevelILInstructionPluginCommand:
+ m_command.highLevelILInstructionCommand(m_command.context, ctxt.binaryView->GetObject(),
+ ctxt.highLevelILFunction->GetObject(), ctxt.instrIndex);
+ break;
default:
break;
}
diff --git a/python/basicblock.py b/python/basicblock.py
index 413199a7..758b9b5f 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -483,6 +483,11 @@ class BasicBlock:
"""Whether the basic block contains Medium Level IL"""
return core.BNIsMediumLevelILBasicBlock(self.handle)
+ @property
+ def is_high_level_il(self) -> bool:
+ """Whether the basic block contains High Level IL"""
+ return core.BNIsHighLevelILBasicBlock(self.handle)
+
@staticmethod
def get_iterated_dominance_frontier(blocks:List['BasicBlock']) -> List['BasicBlock']:
if len(blocks) == 0:
diff --git a/python/flowgraph.py b/python/flowgraph.py
index 1d3d9504..725af442 100644
--- a/python/flowgraph.py
+++ b/python/flowgraph.py
@@ -168,6 +168,9 @@ class FlowGraphNode:
elif core.BNIsMediumLevelILBasicBlock(block):
mlil_func = mediumlevelil.MediumLevelILFunction(func.arch, core.BNGetBasicBlockMediumLevelILFunction(block), func)
block = mediumlevelil.MediumLevelILBasicBlock(block, mlil_func, view)
+ elif core.BNIsHighLevelILBasicBlock(block):
+ hlil_func = highlevelil.HighLevelILFunction(func.arch, core.BNGetBasicBlockHighLevelILFunction(block), func)
+ block = highlevelil.HighLevelILBasicBlock(block, hlil_func, view)
else:
block = basicblock.BasicBlock(block, view)
return block
diff --git a/python/plugin.py b/python/plugin.py
index d4e3f988..beba9781 100644
--- a/python/plugin.py
+++ b/python/plugin.py
@@ -32,6 +32,7 @@ from . import function
from .log import log_error
from . import lowlevelil
from . import mediumlevelil
+from . import highlevelil
class PluginCommandContext:
@@ -191,6 +192,28 @@ class PluginCommand(metaclass=_PluginCommandMetaClass):
log_error(traceback.format_exc())
@staticmethod
+ def _high_level_il_function_action(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.BNGetHighLevelILOwnerFunction(func))
+ func_obj = highlevelil.HighLevelILFunction(owner.arch, core.BNNewHighLevelILFunctionReference(func), owner)
+ action(view_obj, func_obj)
+ except:
+ log_error(traceback.format_exc())
+
+ @staticmethod
+ def _high_level_il_instruction_action(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.BNGetHighLevelILOwnerFunction(func))
+ func_obj = highlevelil.HighLevelILFunction(owner.arch, core.BNNewHighLevelILFunctionReference(func), owner)
+ action(view_obj, func_obj[instr])
+ except:
+ log_error(traceback.format_exc())
+
+ @staticmethod
def _default_is_valid(view, is_valid):
try:
if is_valid is None:
@@ -295,6 +318,34 @@ class PluginCommand(metaclass=_PluginCommandMetaClass):
log_error(traceback.format_exc())
return False
+ @staticmethod
+ def _high_level_il_function_is_valid(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.BNGetHighLevelILOwnerFunction(func))
+ func_obj = highlevelil.HighLevelILFunction(owner.arch, core.BNNewHighLevelILFunctionReference(func), owner)
+ return is_valid(view_obj, func_obj)
+ except:
+ log_error(traceback.format_exc())
+ return False
+
+ @staticmethod
+ def _high_level_il_instruction_is_valid(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.BNGetHighLevelILOwnerFunction(func))
+ func_obj = highlevelil.HighLevelILFunction(owner.arch, core.BNNewHighLevelILFunctionReference(func), owner)
+ return is_valid(view_obj, func_obj[instr])
+ except:
+ log_error(traceback.format_exc())
+ return False
+
@classmethod
def register(cls, name, description, action, is_valid = None):
r"""
@@ -448,6 +499,44 @@ class PluginCommand(metaclass=_PluginCommandMetaClass):
core.BNRegisterPluginCommandForMediumLevelILInstruction(name, description, action_obj, is_valid_obj, None)
@classmethod
+ def register_for_high_level_il_function(cls, name, description, action, is_valid = None):
+ r"""
+ ``register_for_high_level_il_function`` Register a plugin to be called with a high level IL function argument
+
+ :param str name: name of the plugin (use 'Folder\\Name' to have the menu item nested in a folder)
+ :param str description: description of the plugin
+ :param callback action: function to call with the :class:`~binaryview.BinaryView` and a :class:`~highlevelil.HighLevelILFunction` as arguments
+ :param callback is_valid: optional argument of a function passed a :class:`~binaryview.BinaryView` and :class:`~highlevelil.HighLevelILFunction` to determine whether the plugin should be enabled for that view
+ :rtype: None
+
+ .. warning:: Calling ``register_for_high_level_il_function`` with the same function name will replace the existing function but will leak the memory of the original plugin.
+ """
+ binaryninja._init_plugins()
+ action_obj = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNHighLevelILFunction))(lambda ctxt, view, func: cls._high_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.BNHighLevelILFunction))(lambda ctxt, view, func: cls._high_level_il_function_is_valid(view, func, is_valid))
+ cls._registered_commands.append((action_obj, is_valid_obj))
+ core.BNRegisterPluginCommandForHighLevelILFunction(name, description, action_obj, is_valid_obj, None)
+
+ @classmethod
+ def register_for_high_level_il_instruction(cls, name, description, action, is_valid = None):
+ r"""
+ ``register_for_high_level_il_instruction`` Register a plugin to be called with a high level IL instruction argument
+
+ :param str name: name of the plugin (use 'Folder\\Name' to have the menu item nested in a folder)
+ :param str description: description of the plugin
+ :param callback action: function to call with the :class:`~binaryview.BinaryView` and a :class:`~highlevelil.HighLevelILInstruction` as arguments
+ :param callback is_valid: optional argument of a function passed a :class:`~binaryview.BinaryView` and :class:`~highlevelil.HighLevelILInstruction` to determine whether the plugin should be enabled for that view
+ :rtype: None
+
+ .. warning:: Calling ``register_for_high_level_il_instruction`` with the same function name will replace the existing function but will leak the memory of the original plugin.
+ """
+ binaryninja._init_plugins()
+ action_obj = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNHighLevelILFunction), ctypes.c_ulonglong)(lambda ctxt, view, func, instr: cls._high_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.BNHighLevelILFunction), ctypes.c_ulonglong)(lambda ctxt, view, func, instr: cls._high_level_il_instruction_is_valid(view, func, instr, is_valid))
+ cls._registered_commands.append((action_obj, is_valid_obj))
+ core.BNRegisterPluginCommandForHighLevelILInstruction(name, description, action_obj, is_valid_obj, None)
+
+ @classmethod
def get_valid_list(cls, context):
"""Dict of registered plugins"""
commands = list(cls)
@@ -510,6 +599,21 @@ class PluginCommand(metaclass=_PluginCommandMetaClass):
return True
return self._command.mediumLevelILInstructionIsValid(self._command.context, context.view.handle,
context.instruction.function.handle, context.instruction.instr_index)
+ elif self._command.type == PluginCommandType.HighLevelILFunctionPluginCommand:
+ if context.function is None:
+ return False
+ if not self._command.highLevelILFunctionIsValid:
+ return True
+ return self._command.highLevelILFunctionIsValid(self._command.context, context.view.handle, context.function.handle)
+ elif self._command.type == PluginCommandType.HighLevelILInstructionPluginCommand:
+ if context.instruction is None:
+ return False
+ if not isinstance(context.instruction, highlevelil.HighLevelILInstruction):
+ return False
+ if not self._command.highLevelILInstructionIsValid:
+ return True
+ return self._command.highLevelILInstructionIsValid(self._command.context, context.view.handle,
+ context.instruction.function.handle, context.instruction.instr_index)
return False
def execute(self, context):
@@ -543,6 +647,11 @@ class PluginCommand(metaclass=_PluginCommandMetaClass):
elif self._command.type == PluginCommandType.MediumLevelILInstructionPluginCommand:
self._command.mediumLevelILInstructionCommand(self._command.context, context.view.handle,
context.instruction.function.handle, context.instruction.instr_index)
+ elif self._command.type == PluginCommandType.HighLevelILFunctionPluginCommand:
+ self._command.highLevelILFunctionCommand(self._command.context, context.view.handle, context.function.handle)
+ elif self._command.type == PluginCommandType.HighLevelILInstructionPluginCommand:
+ self._command.highLevelILInstructionCommand(self._command.context, context.view.handle,
+ context.instruction.function.handle, context.instruction.instr_index)
def __repr__(self):
return "<PluginCommand: %s>" % self._name
diff --git a/ui/action.h b/ui/action.h
index a9c70937..19f3d317 100644
--- a/ui/action.h
+++ b/ui/action.h
@@ -58,6 +58,7 @@ struct BINARYNINJAUIAPI UIActionContext
FunctionRef function;
LowLevelILFunctionRef lowLevelILFunction;
MediumLevelILFunctionRef mediumLevelILFunction;
+ HighLevelILFunctionRef highLevelILFunction;
LinearViewCursorPosition* cursorPosition;
UIActionContext();
diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h
index 0ba5c823..6a77b829 100644
--- a/ui/flowgraphwidget.h
+++ b/ui/flowgraphwidget.h
@@ -251,6 +251,7 @@ public:
virtual LowLevelILFunctionRef getCurrentLowLevelILFunction() override;
virtual MediumLevelILFunctionRef getCurrentMediumLevelILFunction() override;
+ virtual HighLevelILFunctionRef getCurrentHighLevelILFunction() override;
virtual size_t getCurrentILInstructionIndex() override;
void scrollToCursor();
diff --git a/ui/linearview.h b/ui/linearview.h
index 42395b20..d7a4983e 100644
--- a/ui/linearview.h
+++ b/ui/linearview.h
@@ -311,6 +311,7 @@ public:
virtual FunctionRef getCurrentFunction() override;
virtual LowLevelILFunctionRef getCurrentLowLevelILFunction() override;
virtual MediumLevelILFunctionRef getCurrentMediumLevelILFunction() override;
+ virtual HighLevelILFunctionRef getCurrentHighLevelILFunction() override;
virtual BasicBlockRef getCurrentBasicBlock() override;
virtual ArchitectureRef getCurrentArchitecture() override;
virtual size_t getCurrentILInstructionIndex() override;
diff --git a/ui/viewframe.h b/ui/viewframe.h
index 1445c780..6681582f 100644
--- a/ui/viewframe.h
+++ b/ui/viewframe.h
@@ -206,6 +206,7 @@ public:
virtual LowLevelILFunctionRef getCurrentLowLevelILFunction() { return nullptr; }
virtual MediumLevelILFunctionRef getCurrentMediumLevelILFunction() { return nullptr; }
+ virtual HighLevelILFunctionRef getCurrentHighLevelILFunction() { return nullptr; }
virtual BNFunctionGraphType getILViewType() { return InvalidILViewType; }
virtual void setILViewType(BNFunctionGraphType ilViewType) { }
virtual size_t getCurrentILInstructionIndex() { return BN_INVALID_EXPR; }
diff --git a/workflow.cpp b/workflow.cpp
index 70cd1ced..1d8c67a1 100644
--- a/workflow.cpp
+++ b/workflow.cpp
@@ -48,6 +48,15 @@ Ref<MediumLevelILFunction> AnalysisContext::GetMediumLevelILFunction()
}
+Ref<HighLevelILFunction> AnalysisContext::GetHighLevelILFunction()
+{
+ BNHighLevelILFunction* func = BNAnalysisContextGetHighLevelILFunction(m_object);
+ if (!func)
+ return nullptr;
+ return new HighLevelILFunction(func);
+}
+
+
void AnalysisContext::SetBasicBlockList(vector<Ref<BasicBlock>> basicBlocks)
{
BNBasicBlock** blocks = new BNBasicBlock*[basicBlocks.size()];