@@ -2268,6 +2268,152 @@ std::optional<SharedCacheMachOHeader> SharedCache::LoadHeaderForAddress(std::sha
22682268 return header;
22692269}
22702270
2271+
2272+ void SharedCache::ProcessSymbols (std::shared_ptr<MMappedFileAccessor> file, const SharedCacheMachOHeader& header, uint64_t stringsOffset, size_t stringsSize, uint64_t nlistEntriesOffset, uint32_t nlistCount, uint32_t nlistStartIndex)
2273+ {
2274+ auto addressSize = m_dscView->GetAddressSize ();
2275+ auto strings = file->ReadBuffer (stringsOffset, stringsSize);
2276+
2277+ std::vector<Ref<Symbol>> symbolList;
2278+ for (uint64_t i = 0 ; i < nlistCount; i++)
2279+ {
2280+ uint64_t entryIndex = (nlistStartIndex + i);
2281+
2282+ nlist_64 nlist = {};
2283+ if (addressSize == 4 )
2284+ {
2285+ // 32-bit DSC
2286+ struct nlist nlist32 = {};
2287+ file->Read (&nlist, nlistEntriesOffset + (entryIndex * sizeof (nlist32)), sizeof (nlist32));
2288+ nlist.n_strx = nlist32.n_strx ;
2289+ nlist.n_type = nlist32.n_type ;
2290+ nlist.n_sect = nlist32.n_sect ;
2291+ nlist.n_desc = nlist32.n_desc ;
2292+ nlist.n_value = nlist32.n_value ;
2293+ }
2294+ else
2295+ {
2296+ // 64-bit DSC
2297+ file->Read (&nlist, nlistEntriesOffset + (entryIndex * sizeof (nlist)), sizeof (nlist));
2298+ }
2299+
2300+ auto symbolAddress = nlist.n_value ;
2301+ if (((nlist.n_type & N_TYPE) == N_INDR) || symbolAddress == 0 )
2302+ continue ;
2303+
2304+ if (nlist.n_strx >= stringsSize)
2305+ {
2306+ m_logger->LogError (" Symbol entry at index %llu has a string offset of %u which is outside the strings buffer of size %llu for file %s" , entryIndex, nlist.n_strx , stringsSize, file->Path ().c_str ());
2307+ continue ;
2308+ }
2309+
2310+ std::string symbolName ((char *)strings.GetDataAt (nlist.n_strx ));
2311+ if (symbolName == " <redacted>" )
2312+ continue ;
2313+
2314+ std::optional<BNSymbolType> symbolType;
2315+ if ((nlist.n_type & N_TYPE) == N_SECT && nlist.n_sect > 0 && (size_t )(nlist.n_sect - 1 ) < header.sections .size ())
2316+ {
2317+ symbolType = DataSymbol;
2318+ }
2319+ else if ((nlist.n_type & N_TYPE) == N_ABS)
2320+ {
2321+ symbolType = DataSymbol;
2322+ }
2323+ else if ((nlist.n_type & N_EXT))
2324+ {
2325+ symbolType = ExternalSymbol;
2326+ }
2327+
2328+ if (!symbolType.has_value ())
2329+ {
2330+ m_logger->LogError (" Symbol %s at address %" PRIx64 " has unknown symbol type" , symbolName.c_str (), symbolAddress);
2331+ continue ;
2332+ }
2333+
2334+ std::optional<uint32_t > flags;
2335+ for (auto s : header.sections )
2336+ {
2337+ if (s.addr <= symbolAddress && symbolAddress < s.addr + s.size )
2338+ {
2339+ flags = s.flags ;
2340+ }
2341+ }
2342+
2343+ if (symbolType != ExternalSymbol)
2344+ {
2345+ if (!flags.has_value ())
2346+ {
2347+ m_logger->LogError (" Symbol %s at address %" PRIx64 " is not in any section" , symbolName.c_str (), symbolAddress);
2348+ continue ;
2349+ }
2350+
2351+ if ((flags.value () & S_ATTR_PURE_INSTRUCTIONS) == S_ATTR_PURE_INSTRUCTIONS
2352+ || (flags.value () & S_ATTR_SOME_INSTRUCTIONS) == S_ATTR_SOME_INSTRUCTIONS)
2353+ symbolType = FunctionSymbol;
2354+ else
2355+ symbolType = DataSymbol;
2356+ }
2357+ if ((nlist.n_desc & N_ARM_THUMB_DEF) == N_ARM_THUMB_DEF)
2358+ symbolAddress++;
2359+
2360+ Ref<Symbol> sym = new Symbol (symbolType.value (), symbolName, symbolAddress, GlobalBinding);
2361+ symbolList.emplace_back (sym);
2362+ }
2363+
2364+ auto symListPtr = std::make_shared<std::vector<Ref<Symbol>>>(symbolList);
2365+ m_modifiedState->symbolInfos .emplace (header.textBase , symListPtr);
2366+ }
2367+
2368+ void SharedCache::ApplySymbol (Ref<BinaryView> view, Ref<TypeLibrary> typeLib, Ref<Symbol> symbol)
2369+ {
2370+ Ref<Function> func = nullptr ;
2371+ auto symbolAddress = symbol->GetAddress ();
2372+
2373+ if (symbol->GetType () == FunctionSymbol)
2374+ {
2375+ Ref<Platform> targetPlatform = view->GetDefaultPlatform ();
2376+ func = view->AddFunctionForAnalysis (targetPlatform, symbolAddress);
2377+ }
2378+
2379+ if (!typeLib)
2380+ {
2381+ // No type library just define the symbol.
2382+ view->DefineAutoSymbol (symbol);
2383+ return ;
2384+ }
2385+
2386+ auto type = m_dscView->ImportTypeLibraryObject (typeLib, {symbol->GetFullName ()});
2387+ if (type)
2388+ view->DefineAutoSymbolAndVariableOrFunction (view->GetDefaultPlatform (), symbol, type);
2389+ else
2390+ view->DefineAutoSymbol (symbol);
2391+
2392+ if (!func)
2393+ func = view->GetAnalysisFunction (view->GetDefaultPlatform (), symbolAddress);
2394+ if (func)
2395+ {
2396+ if (symbol->GetFullName () == " _objc_msgSend" )
2397+ {
2398+ func->SetHasVariableArguments (false );
2399+ }
2400+ else if (symbol->GetFullName ().find (" _objc_retain_x" ) != std::string::npos || symbol->GetFullName ().find (" _objc_release_x" ) != std::string::npos)
2401+ {
2402+ auto x = symbol->GetFullName ().rfind (" x" );
2403+ auto num = symbol->GetFullName ().substr (x + 1 );
2404+
2405+ std::vector<BinaryNinja::FunctionParameter> callTypeParams;
2406+ auto cc = m_dscView->GetDefaultArchitecture ()->GetCallingConventionByName (" apple-arm64-objc-fast-arc-" + num);
2407+
2408+ callTypeParams.push_back ({" obj" , m_dscView->GetTypeByName ({ " id" }), true , BinaryNinja::Variable ()});
2409+
2410+ auto funcType = BinaryNinja::Type::FunctionType (m_dscView->GetTypeByName ({ " id" }), cc, callTypeParams);
2411+ func->SetUserType (funcType);
2412+ }
2413+ }
2414+ }
2415+
2416+
22712417void SharedCache::InitializeHeader (
22722418 std::lock_guard<std::mutex>& lock,
22732419 Ref<BinaryView> view, VM* vm, const SharedCacheMachOHeader& header, std::vector<const MemoryRegion*> regionsToLoad)
@@ -2566,132 +2712,29 @@ void SharedCache::InitializeHeader(
25662712 {
25672713 // Mach-O View symtab processing with
25682714 // a ton of stuff cut out so it can work
2569-
25702715 auto reader = vm->MappingAtAddress (header.linkeditSegment .vmaddr ).first .fileAccessor ->lock ();
2571- // auto symtab = reader->ReadBuffer(header.symtab.symoff, header.symtab.nsyms * sizeof(nlist_64));
2572- auto strtab = reader->ReadBuffer (header.symtab .stroff , header.symtab .strsize );
2573- nlist_64 sym;
2574- memset (&sym, 0 , sizeof (sym));
2575- auto N_TYPE = 0xE ; // idk
2576- std::vector<Ref<Symbol>> symbols;
2577- symbols.reserve (header.symtab .nsyms );
2578-
2579- for (size_t i = 0 ; i < header.symtab .nsyms ; i++)
2580- {
2581- reader->Read (&sym, header.symtab .symoff + i * sizeof (nlist_64), sizeof (nlist_64));
2582- if (sym.n_strx >= header.symtab .strsize || ((sym.n_type & N_TYPE) == N_INDR))
2583- continue ;
2584-
2585- std::string symbol ((char *)strtab.GetDataAt (sym.n_strx ));
2586- // BNLogError("%s: 0x%llx", symbol.c_str(), sym.n_value);
2587- if (symbol == " <redacted>" )
2588- continue ;
2589-
2590- BNSymbolType type = DataSymbol;
2591- uint32_t flags;
2592- if ((sym.n_type & N_TYPE) == N_SECT && sym.n_sect > 0 && (size_t )(sym.n_sect - 1 ) < header.sections .size ())
2593- {}
2594- else if ((sym.n_type & N_TYPE) == N_ABS)
2595- {}
2596- else if ((sym.n_type & 0x1 ))
2597- {
2598- type = ExternalSymbol;
2599- }
2600- else
2601- continue ;
2602-
2603- for (auto s : header.sections )
2604- {
2605- if (s.addr < sym.n_value )
2606- {
2607- if (s.addr + s.size > sym.n_value )
2608- {
2609- flags = s.flags ;
2610- }
2611- }
2612- }
2613-
2614- if (type != ExternalSymbol)
2615- {
2616- if ((flags & S_ATTR_PURE_INSTRUCTIONS) == S_ATTR_PURE_INSTRUCTIONS
2617- || (flags & S_ATTR_SOME_INSTRUCTIONS) == S_ATTR_SOME_INSTRUCTIONS)
2618- type = FunctionSymbol;
2619- else
2620- type = DataSymbol;
2621- }
2622- if ((sym.n_desc & N_ARM_THUMB_DEF) == N_ARM_THUMB_DEF)
2623- sym.n_value ++;
2624-
2625- Ref<Symbol> symbolObj = new Symbol (type, symbol, sym.n_value , GlobalBinding);
2626- if (type == FunctionSymbol)
2627- {
2628- Ref<Platform> targetPlatform = view->GetDefaultPlatform ();
2629- view->AddFunctionForAnalysis (targetPlatform, sym.n_value );
2630- }
2631- if (typeLib)
2632- {
2633- auto _type = m_dscView->ImportTypeLibraryObject (typeLib, {symbolObj->GetFullName ()});
2634- if (_type)
2635- {
2636- view->DefineAutoSymbolAndVariableOrFunction (view->GetDefaultPlatform (), symbolObj, _type);
2637- }
2638- else
2639- view->DefineAutoSymbol (symbolObj);
2640- }
2641- else
2642- view->DefineAutoSymbol (symbolObj);
2643- symbols.push_back (std::move (symbolObj));
2644- }
2645- m_modifiedState->symbolInfos [header.textBase ] = std::make_shared<std::vector<Ref<Symbol>>>(std::move (symbols));
2716+ ProcessSymbols (
2717+ reader,
2718+ header,
2719+ header.symtab .stroff ,
2720+ header.symtab .strsize ,
2721+ header.symtab .symoff ,
2722+ header.symtab .nsyms
2723+ );
26462724 }
26472725
2726+ view->BeginBulkModifySymbols ();
2727+ for (const auto & symbol : *m_modifiedState->symbolInfos [header.textBase ])
2728+ ApplySymbol (view, typeLib, symbol);
2729+
26482730 if (header.exportTriePresent && header.linkeditPresent && vm->AddressIsMapped (header.linkeditSegment .vmaddr ))
26492731 {
26502732 auto symbols = GetExportListForHeader (lock, header, [&]() {
26512733 return vm->MappingAtAddress (header.linkeditSegment .vmaddr ).first .fileAccessor ->lock ();
26522734 });
2653- if (symbols)
2654- {
2655- for (const auto & [symbolAddress, symbol] : *symbols)
2656- {
2657- if (typeLib)
2658- {
2659- auto type = m_dscView->ImportTypeLibraryObject (typeLib, symbol->GetRawName ());
2660-
2661- if (type)
2662- {
2663- view->DefineAutoSymbolAndVariableOrFunction (view->GetDefaultPlatform (), symbol, type);
2664- }
2665- else
2666- view->DefineAutoSymbol (symbol);
2667-
2668- if (view->GetAnalysisFunction (view->GetDefaultPlatform (), symbolAddress))
2669- {
2670- auto func = view->GetAnalysisFunction (view->GetDefaultPlatform (), symbolAddress);
2671- auto name = symbol->GetFullName ();
2672- if (name == " _objc_msgSend" )
2673- {
2674- func->SetHasVariableArguments (false );
2675- }
2676- else if (name.find (" _objc_retain_x" ) != std::string::npos || name.find (" _objc_release_x" ) != std::string::npos)
2677- {
2678- auto x = name.rfind (" x" );
2679- auto num = name.substr (x + 1 );
26802735
2681- std::vector<BinaryNinja::FunctionParameter> callTypeParams;
2682- auto cc = m_dscView->GetDefaultArchitecture ()->GetCallingConventionByName (" apple-arm64-objc-fast-arc-" + num);
2683-
2684- callTypeParams.push_back ({" obj" , m_dscView->GetTypeByName ({ " id" }), true , BinaryNinja::Variable ()});
2685-
2686- auto funcType = BinaryNinja::Type::FunctionType (m_dscView->GetTypeByName ({ " id" }), cc, callTypeParams);
2687- func->SetUserType (funcType);
2688- }
2689- }
2690- }
2691- else
2692- view->DefineAutoSymbol (symbol);
2693- }
2694- }
2736+ for (const auto & [symbolAddress, symbol] : *symbols)
2737+ ApplySymbol (view, typeLib, symbol);
26952738 }
26962739 view->EndBulkModifySymbols ();
26972740
0 commit comments