Skip to content

Commit 0fb07c2

Browse files
committed
Add zero-copy data pointer access for BinaryData objects for API-side container transforms.
1 parent 183ef5e commit 0fb07c2

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

binaryninjaapi.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5829,6 +5829,18 @@ namespace BinaryNinja {
58295829
*/
58305830
DataBuffer ReadBuffer(uint64_t offset, size_t len);
58315831

5832+
/*! GetDataPointer returns a pointer to the underlying data for zero-copy access
5833+
5834+
\return pointer to data if available for zero-copy access, nullptr otherwise
5835+
*/
5836+
const uint8_t* GetDataPointer() const;
5837+
5838+
/*! GetDataLength returns the length of the underlying data
5839+
5840+
\return length of data if available for zero-copy access, 0 otherwise
5841+
*/
5842+
size_t GetDataLength() const;
5843+
58325844
/*! Write writes `len` bytes data at address `dest` to virtual address `offset`
58335845

58345846
\param offset virtual address to write to

binaryninjacore.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 134
40+
#define BN_CURRENT_CORE_ABI_VERSION 135
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
@@ -4328,6 +4328,8 @@ extern "C"
43284328

43294329
BINARYNINJACOREAPI size_t BNReadViewData(BNBinaryView* view, void* dest, uint64_t offset, size_t len);
43304330
BINARYNINJACOREAPI BNDataBuffer* BNReadViewBuffer(BNBinaryView* view, uint64_t offset, size_t len);
4331+
BINARYNINJACOREAPI const uint8_t* BNGetViewDataPointer(BNBinaryView* view);
4332+
BINARYNINJACOREAPI size_t BNGetViewDataLength(BNBinaryView* view);
43314333

43324334
BINARYNINJACOREAPI size_t BNWriteViewData(BNBinaryView* view, uint64_t offset, const void* data, size_t len);
43334335
BINARYNINJACOREAPI size_t BNWriteViewBuffer(BNBinaryView* view, uint64_t offset, BNDataBuffer* data);

binaryview.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,18 @@ DataBuffer BinaryView::ReadBuffer(uint64_t offset, size_t len)
17471747
}
17481748

17491749

1750+
const uint8_t* BinaryView::GetDataPointer() const
1751+
{
1752+
return BNGetViewDataPointer(m_object);
1753+
}
1754+
1755+
1756+
size_t BinaryView::GetDataLength() const
1757+
{
1758+
return BNGetViewDataLength(m_object);
1759+
}
1760+
1761+
17501762
size_t BinaryView::WriteBuffer(uint64_t offset, const DataBuffer& data)
17511763
{
17521764
return BNWriteViewBuffer(m_object, offset, data.GetBufferObject());

view/kernelcache/core/transformers/KernelCacheTransforms.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ class IMG4PayloadTransform : public Transform
4141
if (!context || !context->GetInput())
4242
return false;
4343

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());
44+
const uint8_t* dataPtr = context->GetInput()->GetDataPointer();
45+
size_t dataLength = context->GetInput()->GetDataLength();
46+
if (!dataPtr || !dataLength)
47+
return false;
48+
4649
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()));
50+
item.data = (DERByte *)dataPtr;
51+
item.length = static_cast<DERSize>(std::min(dataLength, (size_t)std::numeric_limits<DERSize>::max()));
4952
Img4Payload payload = {};
5053
if (auto result = DERImg4DecodePayload(&item, &payload); (result != DR_Success) && (result != DR_DecodeError))
5154
return false;

0 commit comments

Comments
 (0)