@@ -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
1415class IMG4PayloadTransform : public Transform
1516{
1617
1718public:
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