From 0307cb72c2316a866e41c6d940fc333fd10b9352 Mon Sep 17 00:00:00 2001 From: Brian Potchik Date: Tue, 18 Aug 2026 11:12:25 -0400 Subject: [PATCH] Register ELF and Mach-O loader settings as per-file load settings instead of global. --- view/elf/elfview.cpp | 70 ++++++++++++++++++++-------------------- view/macho/machoview.cpp | 25 +++++++------- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/view/elf/elfview.cpp b/view/elf/elfview.cpp index 69e0f30cb..70f738ba6 100644 --- a/view/elf/elfview.cpp +++ b/view/elf/elfview.cpp @@ -20,37 +20,6 @@ void BinaryNinja::InitElfViewType() static ElfViewType type; BinaryViewType::Register(&type); g_elfViewType = &type; - - Ref settings = Settings::Instance(); - settings->RegisterSetting("files.elf.maxSectionHeaderCount", - R"({ - "title" : "Maximum ELF Section Header Count", - "type" : "number", - "default" : 100, - "minValue" : 0, - "maxValue" : 65536, - "description" : "Maximum number of entries to include in section header array", - "ignore" : ["SettingsProjectScope"] - })"); - - settings->RegisterSetting("files.elf.detectARMBE8Binary", - R"({ - "title" : "Enable ARM BE8 binary detection", - "type" : "boolean", - "default" : true, - "description" : "Enable ARM BE8 binary detection for mixed little/big endianness for code/data", - "ignore" : ["SettingsProjectScope", "SettingsResourceScope"] - })"); - - settings->RegisterSetting("files.elf.overrideX86Endianness", - R"~({ - "title" : "Override x86 ELF endianness", - "type" : "boolean", - "default" : true, - "description" : "Automatically override endianness to little-endian for x86/x86_64 ELF files (useful for obfuscated binaries)", - "ignore" : ["SettingsProjectScope", "SettingsResourceScope"] - })~"); - } @@ -2247,8 +2216,8 @@ bool ElfView::Init() if (m_sectionHeaderCount != 0) { uint64_t configuredSectionCount = 100; - if (viewSettings && viewSettings->Contains("files.elf.maxSectionHeaderCount")) - configuredSectionCount = viewSettings->Get("files.elf.maxSectionHeaderCount", this); + if (settings && settings->Contains("loader.elf.maxSectionHeaderCount")) + configuredSectionCount = settings->Get("loader.elf.maxSectionHeaderCount", this); uint64_t sectionCount = std::min(m_sectionHeaderCount, configuredSectionCount); if (GetAddressForDataOffset(m_sectionHeaderOffset, addr)) { @@ -2985,7 +2954,10 @@ uint64_t ElfView::ParseHeaders(BinaryView* data, ElfIdent& ident, ElfCommonHeade endianness = headerEndianness; // Check for automatic x86 endianness override - bool overrideX86Endianness = Settings::Instance()->Get("files.elf.overrideX86Endianness"); + Ref loadSettings = data->GetLoadSettings(g_elfViewType->GetName()); + bool overrideX86Endianness = true; + if (loadSettings && loadSettings->Contains("loader.elf.overrideX86Endianness")) + overrideX86Endianness = loadSettings->Get("loader.elf.overrideX86Endianness"); if (overrideX86Endianness) { // Peek at e_machine field (2 bytes at offset 0x12) with little-endian interpretation @@ -3134,7 +3106,9 @@ uint64_t ElfView::ParseHeaders(BinaryView* data, ElfIdent& ident, ElfCommonHeade // retrieve architecture // FIXME: Architecture registration methods should perhaps be virtual and take the raw data, or some additional opaque information. - bool checkForARMBE8 = Settings::Instance()->Get("files.elf.detectARMBE8Binary"); + bool checkForARMBE8 = true; + if (loadSettings && loadSettings->Contains("loader.elf.detectARMBE8Binary")) + checkForARMBE8 = loadSettings->Get("loader.elf.detectARMBE8Binary"); if (checkForARMBE8) endianness = ((commonHeader.arch == EM_ARM) && (header.flags & EF_ARM_BE8)) ? BigEndian : endianness; @@ -3201,6 +3175,32 @@ Ref ElfViewType::GetLoadSettingsForData(BinaryView* data) settings->UpdateProperty(override, "readOnly", false); } + // register additional settings + settings->RegisterSetting("loader.elf.maxSectionHeaderCount", + R"({ + "title" : "Maximum ELF Section Header Count", + "type" : "number", + "default" : 100, + "minValue" : 0, + "maxValue" : 65536, + "description" : "Maximum number of entries to include in section header array" + })"); + + settings->RegisterSetting("loader.elf.detectARMBE8Binary", + R"({ + "title" : "Enable ARM BE8 binary detection", + "type" : "boolean", + "default" : true, + "description" : "Enable ARM BE8 binary detection for mixed little/big endianness for code/data" + })"); + + settings->RegisterSetting("loader.elf.overrideX86Endianness", + R"~({ + "title" : "Override x86 ELF endianness", + "type" : "boolean", + "default" : true, + "description" : "Automatically override endianness to little-endian for x86/x86_64 ELF files (useful for obfuscated binaries)" + })~"); return settings; } diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp index a4971c589..c426f425f 100644 --- a/view/macho/machoview.cpp +++ b/view/macho/machoview.cpp @@ -381,16 +381,6 @@ void BinaryNinja::InitMachoViewType() static MachoViewType type; BinaryViewType::Register(&type); g_machoViewType = &type; - - Settings::Instance()->RegisterSetting("loader.macho.maxRebaseBindEntriesMultiplier", - R"~({ - "title" : "Mach-O Rebase/Bind Table Entry Count Limit Multiplier", - "type" : "number", - "default" : 1.0, - "minValue" : 0.01, - "maxValue" : 10.0, - "description" : "Multiplier applied to the maximum number of rebase/bind entries permitted per table, which is derived from the size of the Mach-O slice divided by its pointer size" - })~"); } MachoView::MachoView(const string& typeName, BinaryView* data, bool parseOnly): BinaryView(typeName, data->GetFile(), data), @@ -2994,7 +2984,10 @@ uint64_t MachoView::GetRebaseBindEntryLimit() ? (GetParentView()->GetLength() - m_universalImageOffset) : 0; uint64_t structuralLimit = sliceSize / m_addressSize; - double entryLimitMultiplier = Settings::Instance()->Get("loader.macho.maxRebaseBindEntriesMultiplier", this); + double entryLimitMultiplier = 1.0; + Ref settings = GetLoadSettings(GetTypeName()); + if (settings && settings->Contains("loader.macho.maxRebaseBindEntriesMultiplier")) + entryLimitMultiplier = settings->Get("loader.macho.maxRebaseBindEntriesMultiplier", this); return (uint64_t)(structuralLimit * entryLimitMultiplier); } @@ -4045,6 +4038,16 @@ Ref MachoViewType::GetLoadSettingsForData(BinaryView* data) "description" : "Add function starts sourced from the Function Starts table to the core for analysis." })"); + settings->RegisterSetting("loader.macho.maxRebaseBindEntriesMultiplier", + R"({ + "title" : "Mach-O Rebase/Bind Table Entry Count Limit Multiplier", + "type" : "number", + "default" : 1.0, + "minValue" : 0.01, + "maxValue" : 10.0, + "description" : "Multiplier applied to the maximum number of rebase/bind entries permitted per table, which is derived from the size of the Mach-O slice divided by its pointer size" + })"); + if (viewRef->GetSectionByName("__thread_starts")) { settings->RegisterSetting("loader.macho.rebaseThreadStarts",