Skip to content

Commit 183ef5e

Browse files
committed
Update IMG4 transform to use DecodeWithContext and synthesize a filename for the payload.
1 parent 92d75df commit 183ef5e

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

binaryninjaapi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8929,6 +8929,7 @@ namespace BinaryNinja {
89298929
};
89308930

89318931
class TransformContext;
8932+
typedef BNTransformCapabilities TransformCapabilities;
89328933

89338934
/*! Allows users to implement custom transformations.
89348935

transform.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ bool Transform::DecodeWithContextCallback(void* ctxt, BNTransformContext* contex
114114
paramMap[params[i].name] = DataBuffer(BNDuplicateDataBuffer(params[i].value));
115115

116116
CallbackRef<Transform> xform(ctxt);
117-
Ref<TransformContext> contextRef = new TransformContext(BNNewTransformContextReference(context));
118-
return xform->DecodeWithContext(contextRef, paramMap);
117+
return xform->DecodeWithContext(new TransformContext(context), paramMap);
119118
}
120119

121120

transformcontext.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Ref<TransformContext> TransformContext::GetParent() const
5050
BNTransformContext* parent = BNTransformContextGetParent(m_object);
5151
if (!parent)
5252
return nullptr;
53-
return new TransformContext(BNNewTransformContextReference(parent));
53+
return new TransformContext(parent);
5454
}
5555

5656

@@ -81,7 +81,7 @@ Ref<TransformContext> TransformContext::GetChild(const string& filename) const
8181
BNTransformContext* child = BNTransformContextGetChild(m_object, filename.c_str());
8282
if (!child)
8383
return nullptr;
84-
return new TransformContext(BNNewTransformContextReference(child));
84+
return new TransformContext(child);
8585
}
8686

8787

@@ -90,7 +90,7 @@ Ref<TransformContext> TransformContext::CreateChild(const DataBuffer& data, cons
9090
BNTransformContext* child = BNTransformContextCreateChild(m_object, data.GetBufferObject(), filename.c_str());
9191
if (!child)
9292
return nullptr;
93-
return new TransformContext(BNNewTransformContextReference(child));
93+
return new TransformContext(child);
9494
}
9595

9696

view/kernelcache/core/transformers/KernelCacheTransforms.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ using namespace BinaryNinja;
1010
#include "libDER/libDER.h"
1111
#include "libimg4/img4.h"
1212
#include "liblzfse/lzfse.h"
13+
#include <algorithm>
1314

1415
class IMG4PayloadTransform : public Transform
1516
{
1617

1718
public:
18-
IMG4PayloadTransform(): Transform(DecodeTransform, TransformSupportsDetection, "IMG4", "IMG4", "Container")
19+
IMG4PayloadTransform(): Transform(DecodeTransform, TransformCapabilities(TransformSupportsDetection | TransformSupportsContext), "IMG4", "IMG4", "Container")
1920
{
2021
}
2122

2223
virtual bool Decode(const DataBuffer& input, DataBuffer& output, const std::map<std::string, DataBuffer>& params) override
2324
{
2425
DERItem item = {};
2526
item.data = (DERByte *)input.GetData();
26-
item.length = input.GetLength();
27-
27+
item.length = static_cast<DERSize>(std::min(input.GetLength(), (size_t)std::numeric_limits<DERSize>::max()));
2828
Img4Payload payload = {};
2929
if (auto result = DERImg4DecodePayload(&item, &payload); (result != DR_Success) && (result != DR_DecodeError))
3030
return false;
@@ -36,6 +36,38 @@ class IMG4PayloadTransform : public Transform
3636
return true;
3737
}
3838

39+
virtual bool DecodeWithContext(Ref<TransformContext> context, const std::map<std::string, DataBuffer>& params) override
40+
{
41+
if (!context || !context->GetInput())
42+
return false;
43+
44+
// TODO: DataBuffers are not zero-copy, so this is inefficient. Investigate a better way.
45+
auto input = context->GetInput()->ReadBuffer(0, context->GetInput()->GetLength());
46+
DERItem item = {};
47+
item.data = (DERByte *)input.GetData();
48+
item.length = static_cast<DERSize>(std::min(input.GetLength(), (size_t)std::numeric_limits<DERSize>::max()));
49+
Img4Payload payload = {};
50+
if (auto result = DERImg4DecodePayload(&item, &payload); (result != DR_Success) && (result != DR_DecodeError))
51+
return false;
52+
if (!payload.payload.data || !payload.payload.length)
53+
return false;
54+
55+
// Synthesize name: <type>[.<version>]
56+
std::string filename = "";
57+
if (payload.type.data && payload.type.length)
58+
filename = std::string((const char*)payload.type.data, payload.type.length);
59+
if (payload.version.data && payload.version.length)
60+
{
61+
if (!filename.empty())
62+
filename += ".";
63+
filename += std::string((const char*)payload.version.data, payload.version.length);
64+
}
65+
66+
context->CreateChild(DataBuffer(payload.payload.data, payload.payload.length), filename);
67+
68+
return true;
69+
}
70+
3971
static void der_put_len(std::vector<uint8_t>& v, size_t len) {
4072
if (len < 0x80) { v.push_back(static_cast<uint8_t>(len)); return; }
4173
uint8_t tmp[9]; size_t n = 0;

0 commit comments

Comments
 (0)