summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h7
-rw-r--r--binaryninjacore.h10
-rw-r--r--python/transform.py36
-rw-r--r--transform.cpp42
4 files changed, 92 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 9da9f677..bd4f6de5 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -8928,6 +8928,8 @@ namespace BinaryNinja {
size_t fixedLength; // Variable length if zero
};
+ class TransformContext;
+
/*! Allows users to implement custom transformations.
New transformations may be added at runtime, so an instance of a transform is created like
@@ -8970,6 +8972,7 @@ namespace BinaryNinja {
void* ctxt, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount);
static bool EncodeCallback(
void* ctxt, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount);
+ static bool DecodeWithContextCallback(void* ctxt, BNTransformContext* context, BNTransformParameter* params, size_t paramCount);
static bool CanDecodeCallback(void* ctxt, BNBinaryView* input);
static std::vector<TransformParameter> EncryptionKeyParameters(size_t fixedKeyLength = 0);
@@ -8987,6 +8990,7 @@ namespace BinaryNinja {
BNTransformType GetType() const;
BNTransformCapabilities GetCapabilities() const;
bool SupportsDetection() const;
+ bool SupportsContext() const;
std::string GetName() const;
std::string GetLongName() const;
std::string GetGroup() const;
@@ -8995,6 +8999,7 @@ namespace BinaryNinja {
virtual bool Decode(const DataBuffer& input, DataBuffer& output, const std::map<std::string, DataBuffer>& params = std::map<std::string, DataBuffer>());
virtual bool Encode(const DataBuffer& input, DataBuffer& output, const std::map<std::string, DataBuffer>& params = std::map<std::string, DataBuffer>());
+ virtual bool DecodeWithContext(Ref<TransformContext> context, const std::map<std::string, DataBuffer>& params = std::map<std::string, DataBuffer>());
virtual bool CanDecode(Ref<BinaryView> input) const;
};
@@ -9011,6 +9016,8 @@ namespace BinaryNinja {
const std::map<std::string, DataBuffer>& params = std::map<std::string, DataBuffer>()) override;
virtual bool Encode(const DataBuffer& input, DataBuffer& output,
const std::map<std::string, DataBuffer>& params = std::map<std::string, DataBuffer>()) override;
+ virtual bool DecodeWithContext(Ref<TransformContext> context,
+ const std::map<std::string, DataBuffer>& params = std::map<std::string, DataBuffer>()) override;
virtual bool CanDecode(Ref<BinaryView> input) const override;
};
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 6299618d..67b17bc4 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -37,14 +37,14 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
-#define BN_CURRENT_CORE_ABI_VERSION 133
+#define BN_CURRENT_CORE_ABI_VERSION 134
// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
// will require rebuilding. The minimum version is increased when there are
// incompatible changes that break binary compatibility, such as changes to
// existing types or functions.
-#define BN_MINIMUM_CORE_ABI_VERSION 133
+#define BN_MINIMUM_CORE_ABI_VERSION 134
#ifdef __GNUC__
#ifdef BINARYNINJACORE_LIBRARY
@@ -353,7 +353,8 @@ extern "C"
typedef enum BNTransformCapabilities
{
TransformNoCapabilities = 0,
- TransformSupportsDetection = 1
+ TransformSupportsDetection = 1,
+ TransformSupportsContext = 2
} BNTransformCapabilities;
typedef enum BNTransformSessionMode
@@ -1770,6 +1771,7 @@ extern "C"
void (*freeParameters)(BNTransformParameterInfo* params, size_t count);
bool (*decode)(void* ctxt, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount);
bool (*encode)(void* ctxt, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount);
+ bool (*decodeWithContext)(void* ctxt, BNTransformContext* context, BNTransformParameter* params, size_t paramCount);
bool (*canDecode)(void* ctxt, BNBinaryView* input);
} BNCustomTransform;
@@ -4634,6 +4636,7 @@ extern "C"
BINARYNINJACOREAPI BNTransformType BNGetTransformType(BNTransform* xform);
BINARYNINJACOREAPI uint32_t BNGetTransformCapabilities(BNTransform* xform);
BINARYNINJACOREAPI bool BNTransformSupportsDetection(BNTransform* xform);
+ BINARYNINJACOREAPI bool BNTransformSupportsContext(BNTransform* xform);
BINARYNINJACOREAPI char* BNGetTransformName(BNTransform* xform);
BINARYNINJACOREAPI char* BNGetTransformLongName(BNTransform* xform);
BINARYNINJACOREAPI char* BNGetTransformGroup(BNTransform* xform);
@@ -4643,6 +4646,7 @@ extern "C"
BNTransform* xform, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount);
BINARYNINJACOREAPI bool BNEncode(
BNTransform* xform, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount);
+ BINARYNINJACOREAPI bool BNDecodeWithContext(BNTransform* xform, BNTransformContext* context, BNTransformParameter* params, size_t paramCount);
BINARYNINJACOREAPI bool BNCanDecode(BNTransform* xform, BNBinaryView* input);
// Transform Context
diff --git a/python/transform.py b/python/transform.py
index 3ef5c4b6..3168982d 100644
--- a/python/transform.py
+++ b/python/transform.py
@@ -116,6 +116,7 @@ class Transform(metaclass=_TransformMetaClass):
self._cb.freeParameters = self._cb.freeParameters.__class__(self._free_parameters)
self._cb.decode = self._cb.decode.__class__(self._decode)
self._cb.encode = self._cb.encode.__class__(self._encode)
+ self._cb.decodeWithContext = self._cb.decodeWithContext.__class__(self._decode_with_context)
self._cb.canDecode = self._cb.canDecode.__class__(self._can_decode)
self._pending_param_lists = {}
self.type = self.__class__.transform_type
@@ -131,6 +132,7 @@ class Transform(metaclass=_TransformMetaClass):
self.type = TransformType(core.BNGetTransformType(self.handle))
self.capabilities = core.BNGetTransformCapabilities(self.handle)
self.supports_detection = core.BNTransformSupportsDetection(self.handle)
+ self.supports_context = core.BNTransformSupportsContext(self.handle)
self.name = core.BNGetTransformName(self.handle)
self.long_name = core.BNGetTransformLongName(self.handle)
self.group = core.BNGetTransformGroup(self.handle)
@@ -232,6 +234,21 @@ class Transform(metaclass=_TransformMetaClass):
log_error_for_exception("Unhandled Python exception in Transform._encode")
return False
+ def _decode_with_context(self, ctxt, context, params, count):
+ try:
+ # TODO: Make Python TransformSession and TransformContext objects
+ from . import transform_context
+ context_obj = transform_context.TransformContext(core.BNNewTransformContextReference(context))
+ param_map = {}
+ for i in range(0, count):
+ data = databuffer.DataBuffer(handle=core.BNDuplicateDataBuffer(params[i].value))
+ param_map[params[i].name] = bytes(data)
+ result = self.perform_decode_with_context(context_obj, param_map)
+ return result if result is not None else False
+ except:
+ log_error_for_exception("Unhandled Python exception in Transform._decode_with_context")
+ return False
+
def _can_decode(self, ctxt, input):
try:
input_obj = binaryview.BinaryView(handle=core.BNNewViewReference(input))
@@ -250,6 +267,9 @@ class Transform(metaclass=_TransformMetaClass):
def perform_encode(self, data, params):
return None
+ def perform_decode_with_context(self, context, params):
+ return False
+
def decode(self, input_buf, params={}):
if isinstance(input_buf, int) or isinstance(input_buf, int):
return None
@@ -282,6 +302,22 @@ class Transform(metaclass=_TransformMetaClass):
return None
return bytes(output_buf)
+ def decode_with_context(self, context, params={}):
+ # TODO: Make Python TransformSession and TransformContext objects
+ from . import transform_context
+ if not isinstance(context, transform_context.TransformContext):
+ return None
+ keys = list(params.keys())
+ param_buf = (core.BNTransformParameter * len(keys))()
+ data = []
+ for i in range(0, len(keys)):
+ data.append(databuffer.DataBuffer(params[keys[i]]))
+ param_buf[i].name = keys[i]
+ param_buf[i].value = data[i].handle
+ if not core.BNDecodeWithContext(self.handle, context.handle, param_buf, len(keys)):
+ return False
+ return True
+
def can_decode(self, input):
"""
``can_decode`` checks if this transform can decode the given input.
diff --git a/transform.cpp b/transform.cpp
index 468cc0f2..735fb1b9 100644
--- a/transform.cpp
+++ b/transform.cpp
@@ -107,6 +107,18 @@ bool Transform::EncodeCallback(
}
+bool Transform::DecodeWithContextCallback(void* ctxt, BNTransformContext* context, BNTransformParameter* params, size_t paramCount)
+{
+ map<string, DataBuffer> paramMap;
+ for (size_t i = 0; i < paramCount; i++)
+ paramMap[params[i].name] = DataBuffer(BNDuplicateDataBuffer(params[i].value));
+
+ CallbackRef<Transform> xform(ctxt);
+ Ref<TransformContext> contextRef = new TransformContext(BNNewTransformContextReference(context));
+ return xform->DecodeWithContext(contextRef, paramMap);
+}
+
+
bool Transform::CanDecodeCallback(void* ctxt, BNBinaryView* input)
{
CallbackRef<Transform> xform(ctxt);
@@ -150,6 +162,7 @@ void Transform::Register(Transform* xform)
callbacks.freeParameters = FreeParametersCallback;
callbacks.decode = DecodeCallback;
callbacks.encode = EncodeCallback;
+ callbacks.decodeWithContext = DecodeWithContextCallback;
callbacks.canDecode = CanDecodeCallback;
xform->AddRefForRegistration();
xform->m_object = BNRegisterTransformTypeWithCapabilities(xform->m_typeForRegister, xform->m_capabilitiesForRegister,
@@ -199,6 +212,12 @@ bool Transform::SupportsDetection() const
}
+bool Transform::SupportsContext() const
+{
+ return BNTransformSupportsContext(m_object);
+}
+
+
string Transform::GetName() const
{
char* name = BNGetTransformName(m_object);
@@ -246,6 +265,12 @@ bool Transform::Encode(const DataBuffer&, DataBuffer&, const map<string, DataBuf
}
+bool Transform::DecodeWithContext(Ref<TransformContext>, const map<string, DataBuffer>&)
+{
+ return false;
+}
+
+
bool Transform::CanDecode(Ref<BinaryView> input) const
{
return false;
@@ -310,6 +335,23 @@ bool CoreTransform::Encode(const DataBuffer& input, DataBuffer& output, const ma
}
+bool CoreTransform::DecodeWithContext(Ref<TransformContext> context, const map<string, DataBuffer>& params)
+{
+ BNTransformParameter* list = new BNTransformParameter[params.size()];
+ size_t idx = 0;
+ for (auto& i : params)
+ {
+ list[idx].name = i.first.c_str();
+ list[idx++].value = i.second.GetBufferObject();
+ }
+
+ bool result = BNDecodeWithContext(m_object, context->GetObject(), list, idx);
+
+ delete[] list;
+ return result;
+}
+
+
bool CoreTransform::CanDecode(Ref<BinaryView> input) const
{
return BNCanDecode(m_object, input->GetObject());