From c36da75dd1720c91053e1c04f77d375a7aaa9e96 Mon Sep 17 00:00:00 2001 From: WeiN76LQh Date: Sun, 23 Mar 2025 21:31:08 +0000 Subject: [PATCH] [SharedCache] Add a section for sectionless segments In Binary Ninja it can be quite confusing when a segment is added that doesn't have any sections. `libobjc.A.dylib::__OBJC_RW` is an example of this. When scrolling through that segment there is no bar at the top of the linear view indicating where the data came from. When looking at the list of segments there are no names and with the different segment and section lists it can be hard to eyeball where a segment lands within the list of sections. There is an argument here that the better solution is to change the way Binary Ninja displays information. For instance when scrolling through the linear view through a segment with no section, the segment information should be displayed at the top. Additionally segment names could be displayed in the segment list. --- view/sharedcache/core/SharedCache.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index e3c115cd0..15e16d87f 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -2422,6 +2422,7 @@ void SharedCache::InitializeHeader( if (settings && settings->Contains("loader.dsc.processFunctionStarts")) applyFunctionStarts = settings->Get("loader.dsc.processFunctionStarts", view); + std::set regionsWithNoSections(regionsToLoad.begin(), regionsToLoad.end()); for (size_t i = 0; i < header.sections.size(); i++) { bool skip = false; @@ -2429,6 +2430,7 @@ void SharedCache::InitializeHeader( { if (header.sections[i].addr >= region->start && header.sections[i].addr < region->start + region->size) { + regionsWithNoSections.erase(region); if (MemoryRegionIsHeaderInitialized(lock, *region)) skip = true; break; @@ -2549,6 +2551,16 @@ void SharedCache::InitializeHeader( type, header.sections[i].align); } + // Some segments like `libobjc.A.dylib::__OBJC_RW` don't have any sections. A section is added for segments like + // this so that they display nicely in Binary Ninja. Otherwise it can be confusing where data came from if it has + // no section. + for (const auto& region : regionsWithNoSections) + { + if (MemoryRegionIsHeaderInitialized(lock, *region)) + continue; + view->AddUserSection(region->prettyName, region->start, region->size, SectionSemanticsForRegion(*region)); + } + auto typeLib = view->GetTypeLibrary(header.installName); BinaryReader virtualReader(view);