MCPcopy Create free account
hub / github.com/Vector35/binaryninja-api / FromFile

Method FromFile

view/sharedcache/core/SharedCache.cpp:46–145  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

44}
45
46CacheEntry CacheEntry::FromFile(const std::string& filePath, const std::string& fileName, CacheEntryType type)
47{
48 auto file = FileAccessorCache::Global().Open(filePath).lock();
49
50 // TODO: Pull this out into another function so we can do IsValidDSCFile or something.
51 // We first want to make sure that the base file is dyld.
52 // All entries must start with "dyld".
53 DataBuffer sig = file->ReadBuffer(0, 4);
54 if (sig.GetLength() != 4)
55 throw std::runtime_error("File is empty!");
56 const char* magic = static_cast<char*>(sig.GetData());
57 if (strncmp(magic, "dyld", 4) != 0)
58 throw std::runtime_error("File does not start with `dyld`!");
59
60 // Read the header, this _should_ be compatible with all known DSC formats.
61 // Mason: the above is not true! https://github.com/Vector35/binaryninja-api/issues/6073
62 // The mappingOffset should point right after the header. We use this to constrain the read size so unsupported fields are zeroed.
63 size_t headerSize = file->ReadUInt32(0x10);
64 dyld_cache_header header = {};
65 // Truncate buffer length (headerSize) if larger than our `dyld_cache_header` for reading.
66 file->Read(&header, 0, std::min(headerSize, sizeof(dyld_cache_header)));
67
68 // Read the mappings using the headers `mappingCount` and `mappingOffset`.
69 dyld_cache_mapping_info currentMapping = {};
70 std::vector<dyld_cache_mapping_info> mappings;
71 for (size_t i = 0; i < header.mappingCount; i++)
72 {
73 file->Read(&currentMapping, header.mappingOffset + (i * sizeof(currentMapping)), sizeof(currentMapping));
74
75 // Cancel adding the entry if we have an invalid mapping.
76 if (currentMapping.fileOffset + currentMapping.size > file->Length())
77 throw std::runtime_error("Invalid mapping in shared cache entry");
78
79 // TODO: Check initProt to make sure its in the range of expected values.
80
81 mappings.push_back(currentMapping);
82 }
83
84 // Handle special entry types.
85 if (fileName.find(".dylddata") != std::string::npos)
86 {
87 // We found a single dyld data cache entry file. Mark it as such!
88 type = CacheEntryType::DyldData;
89 }
90 else if (fileName.find(".symbols") != std::string::npos && mappings.size() == 1)
91 {
92 // We found a single symbols cache entry file. Mark it as such!
93 type = CacheEntryType::Symbols;
94 // Adjust the mapping for the symbol file, they seem to be only for the header.
95 // If we do not adjust the mapping than we will not be able to read the symbol table through the virtual memory.
96 mappings[0].fileOffset = 0;
97 mappings[0].size = file->Length();
98 }
99 else if (mappings.size() == 1 && header.imagesCountOld == 0 && header.imagesCount == 0
100 && header.imagesTextOffset == 0)
101 {
102 // Stub entry file, should only have a single mapping and no images.
103 // NOTE: If we end up identifying something incorrectly as a stub we need to restrict this further.

Callers

nothing calls this directly

Calls 12

push_backMethod · 0.80
findMethod · 0.80
ReadNullTermStringMethod · 0.80
lockMethod · 0.45
OpenMethod · 0.45
ReadBufferMethod · 0.45
GetLengthMethod · 0.45
GetDataMethod · 0.45
ReadUInt32Method · 0.45
ReadMethod · 0.45
LengthMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected