@@ -36,7 +36,7 @@ std::vector<std::string> CacheImage::GetDependencies() const
3636}
3737
3838CacheEntry::CacheEntry (std::string filePath, std::string fileName, CacheEntryType type, dyld_cache_header header,
39- std::vector<dyld_cache_mapping_info> mappings, std::vector<std::pair<std::string, dyld_cache_image_info>> images)
39+ std::vector<dyld_cache_mapping_info>&& mappings, std::vector<std::pair<std::string, dyld_cache_image_info>>&& images)
4040{
4141 m_filePath = std::move (filePath);
4242 m_fileName = std::move (fileName);
@@ -46,7 +46,7 @@ CacheEntry::CacheEntry(std::string filePath, std::string fileName, CacheEntryTyp
4646 m_images = std::move (images);
4747}
4848
49- std::optional< CacheEntry> CacheEntry::FromFile (const std::string& filePath, const std::string& fileName, CacheEntryType type)
49+ CacheEntry CacheEntry::FromFile (const std::string& filePath, const std::string& fileName, CacheEntryType type)
5050{
5151 auto file = FileAccessorCache::Global ().Open (filePath).lock ();
5252
@@ -55,22 +55,33 @@ std::optional<CacheEntry> CacheEntry::FromFile(const std::string& filePath, cons
5555 // All entries must start with "dyld".
5656 DataBuffer sig = file->ReadBuffer (0 , 4 );
5757 if (sig.GetLength () != 4 )
58- return std::nullopt ;
59- const char * magic = ( char *) sig.GetData ();
58+ throw std::runtime_error ( " File is empty! " ) ;
59+ const char * magic = static_cast < char *>( sig.GetData () );
6060 if (strncmp (magic, " dyld" , 4 ) != 0 )
61- return std::nullopt ;
61+ throw std::runtime_error ( " File does not start with `dyld`! " ) ;
6262
6363 // Read the header, this _should_ be compatible with all known DSC formats.
6464 // Mason: the above is not true! https://github.com/Vector35/binaryninja-api/issues/6073
6565 dyld_cache_header header = {};
6666 file->Read (&header, 0 , sizeof (header));
6767
68+ // Adjust the array count to actually be the "real" number for comparisons with what we load.
69+ // This is required so we can check if we loaded the required number of caches, in view init.
70+ header.subCacheArrayCount += header.cacheSubType ;
71+
6872 // Read the mappings using the headers `mappingCount` and `mappingOffset`.
6973 dyld_cache_mapping_info currentMapping = {};
7074 std::vector<dyld_cache_mapping_info> mappings;
7175 for (size_t i = 0 ; i < header.mappingCount ; i++)
7276 {
7377 file->Read (¤tMapping, header.mappingOffset + (i * sizeof (currentMapping)), sizeof (currentMapping));
78+
79+ // Cancel adding the entry if we have an invalid mapping.
80+ if (currentMapping.fileOffset + currentMapping.size > file->Length ())
81+ throw std::runtime_error (" Invalid mapping in shared cache entry" );
82+
83+ // TODO: Check initProt to make sure its in the range of expected values.
84+
7485 mappings.push_back (currentMapping);
7586 }
7687
@@ -134,7 +145,7 @@ std::optional<CacheEntry> CacheEntry::FromFile(const std::string& filePath, cons
134145 images.emplace_back (imageName, branchIslandImg);
135146 }
136147
137- return CacheEntry ( filePath, fileName, type, header, mappings, images);
148+ return { filePath, fileName, type, header, std::move ( mappings), std::move ( images)} ;
138149}
139150
140151WeakFileAccessor CacheEntry::GetAccessor () const
0 commit comments