@@ -17,7 +17,7 @@ SharedCacheMachOProcessor::SharedCacheMachOProcessor(Ref<BinaryView> view, std::
1717 }
1818}
1919
20- void SharedCacheMachOProcessor::ApplyHeader (SharedCacheMachOHeader& header)
20+ void SharedCacheMachOProcessor::ApplyHeader (const SharedCache& cache, SharedCacheMachOHeader& header)
2121{
2222 auto typeLibraryFromName = [&](const std::string& name) -> Ref<TypeLibrary> {
2323 // Check to see if we have already loaded the type library.
@@ -32,13 +32,16 @@ void SharedCacheMachOProcessor::ApplyHeader(SharedCacheMachOHeader& header)
3232
3333 // Add a section for the header itself.
3434 std::string headerSection = fmt::format (" {}::__macho_header" , header.identifierPrefix );
35- // TODO: Support mach_header (non 64bit)
36- uint64_t headerSectionSize = sizeof (mach_header_64) + header.ident .sizeofcmds ;
35+ uint64_t machHeaderSize = m_vm-> GetAddressSize () == 8 ? sizeof (mach_header_64) : sizeof (mach_header);
36+ uint64_t headerSectionSize = machHeaderSize + header.ident .sizeofcmds ;
3737 m_view->AddUserSection (headerSection, header.textBase , headerSectionSize, ReadOnlyDataSectionSemantics);
3838
3939 ApplyHeaderSections (header);
4040 ApplyHeaderDataVariables (header);
4141
42+ // Pull the available type library for the image we are loading, so we can apply known types.
43+ auto typeLib = typeLibraryFromName (header.installName );
44+
4245 if (header.linkeditPresent && m_vm->IsAddressMapped (header.linkeditSegment .vmaddr ))
4346 {
4447 if (m_applyFunctions && header.functionStartsPresent )
@@ -49,18 +52,16 @@ void SharedCacheMachOProcessor::ApplyHeader(SharedCacheMachOHeader& header)
4952 m_view->AddFunctionForAnalysis (targetPlatform, func, false );
5053 }
5154
52- // Pull the available type library for the image we are loading, so we can apply known types.
53- auto typeLib = typeLibraryFromName (header.installName );
5455 m_view->BeginBulkModifySymbols ();
5556
56- // TODO: Why does this need to only happen in linkeditSegment?
5757 // Apply symbols from symbol table.
5858 if (header.symtab .symoff != 0 )
5959 {
60- // Mach-O View symtab processing with
61- // a ton of stuff cut out so it can work
6260 // NOTE: This table is read relative to the link edit segment file base.
63- const auto symbols = header.ReadSymbolTable (*m_view, *m_vm);
61+ // NOTE: This does not handle the shared .symbols cache entry symbols, that is the responsibility of the caller.
62+ TableInfo symbolInfo = { header.GetLinkEditFileBase () + header.symtab .symoff , header.symtab .nsyms };
63+ TableInfo stringInfo = { header.GetLinkEditFileBase () + header.symtab .stroff , header.symtab .strsize };
64+ const auto symbols = header.ReadSymbolTable (*m_vm, symbolInfo, stringInfo);
6465 for (const auto & sym : symbols)
6566 {
6667 auto [symbol, symbolType] = sym.GetBNSymbolAndType (*m_view);
@@ -72,7 +73,6 @@ void SharedCacheMachOProcessor::ApplyHeader(SharedCacheMachOHeader& header)
7273 if (header.exportTriePresent )
7374 {
7475 // NOTE: This table is read relative to the link edit segment file base.
75- // TODO: Remove this and use the m_symbols in the cache?
7676 const auto exportSymbols = header.ReadExportSymbolTrie (*m_vm);
7777 for (const auto & sym : exportSymbols)
7878 {
@@ -82,6 +82,53 @@ void SharedCacheMachOProcessor::ApplyHeader(SharedCacheMachOHeader& header)
8282 }
8383 m_view->EndBulkModifySymbols ();
8484 }
85+
86+ // Apply symbols from the .symbols cache files.
87+ for (const auto &entry: cache.GetEntries ())
88+ {
89+ // NOTE: We check addr size as we only support 64bit .symbols files currently.
90+ if (entry.GetType () != CacheEntryType::Symbols && m_vm->GetAddressSize () == 8 )
91+ continue ;
92+ const auto & entryHeader = entry.GetHeader ();
93+
94+ // This is where we get the symbol and string table information from in the .symbols file.
95+ dyld_cache_local_symbols_info localSymbolsInfo = {};
96+ auto localSymbolsInfoAddr = entry.GetMappedAddress (entryHeader.localSymbolsOffset );
97+ if (!localSymbolsInfoAddr.has_value ())
98+ continue ;
99+ m_vm->Read (&localSymbolsInfo, *localSymbolsInfoAddr, sizeof (dyld_cache_local_symbols_info));
100+
101+ // Read each symbols entry, looking for the current image entry.
102+ uint64_t localEntriesAddr = *localSymbolsInfoAddr + localSymbolsInfo.entriesOffset ;
103+ uint64_t localSymbolsAddr = *localSymbolsInfoAddr + localSymbolsInfo.nlistOffset ;
104+ uint64_t localStringsAddr = *localSymbolsInfoAddr + localSymbolsInfo.stringsOffset ;
105+
106+ dyld_cache_local_symbols_entry_64 localSymbolsEntry = {};
107+ for (uint32_t i = 0 ; i < localSymbolsInfo.entriesCount ; i++)
108+ {
109+ m_vm->Read (&localSymbolsEntry, localEntriesAddr + i * sizeof (dyld_cache_local_symbols_entry_64),
110+ sizeof (dyld_cache_local_symbols_entry_64));
111+ // The dylibOffset is the offset from the cache base address to the image header.
112+ const auto imageAddr = cache.GetBaseAddress () + localSymbolsEntry.dylibOffset ;
113+ if (imageAddr == header.textBase )
114+ {
115+ // We have found the entry to read!
116+ // TODO: Support 32bit nlist
117+ uint64_t symbolTableStart = localSymbolsAddr + (localSymbolsEntry.nlistStartIndex * sizeof (nlist_64));
118+ TableInfo symbolInfo = {symbolTableStart, localSymbolsEntry.nlistCount };
119+ TableInfo stringInfo = {localStringsAddr, localSymbolsInfo.stringsSize };
120+ m_view->BeginBulkModifySymbols ();
121+ const auto symbols = header.ReadSymbolTable (*m_vm, symbolInfo, stringInfo);
122+ for (const auto &sym: symbols)
123+ {
124+ auto [symbol, symbolType] = sym.GetBNSymbolAndType (*m_view);
125+ ApplySymbol (m_view, typeLib, symbol, symbolType);
126+ }
127+ m_view->EndBulkModifySymbols ();
128+ break ;
129+ }
130+ }
131+ }
85132}
86133
87134uint64_t SharedCacheMachOProcessor::ApplyHeaderSections (SharedCacheMachOHeader& header)
0 commit comments