@@ -40,19 +40,30 @@ void BinaryNinja::InitElfViewType()
4040 "description" : "Enable ARM BE8 binary detection for mixed little/big endianness for code/data",
4141 "ignore" : ["SettingsProjectScope", "SettingsResourceScope"]
4242 })" );
43+
44+ settings->RegisterSetting (" files.elf.overrideX86Endianness" ,
45+ R"~( {
46+ "title" : "Override x86 ELF endianness",
47+ "type" : "boolean",
48+ "default" : true,
49+ "description" : "Automatically override endianness to little-endian for x86/x86_64 ELF files (useful for obfuscated binaries)",
50+ "ignore" : ["SettingsProjectScope", "SettingsResourceScope"]
51+ })~" );
52+
4353}
4454
4555
4656ElfView::ElfView (BinaryView* data, bool parseOnly): BinaryView(" ELF" , data->GetFile (), data), m_parseOnly(parseOnly)
4757{
58+ CreateLogger (" BinaryView" );
59+ m_logger = CreateLogger (" BinaryView.ElfView" );
60+
4861 Elf64Header header;
4962 string errorMsg;
5063 BNEndianness endian;
51- if (!g_elfViewType-> ParseHeaders (data, m_ident, m_commonHeader, header, &m_arch, &m_plat, errorMsg, endian))
64+ if (!ParseHeaders (data, m_ident, m_commonHeader, header, &m_arch, &m_plat, errorMsg, endian))
5265 throw ElfFormatException (errorMsg);
5366
54- CreateLogger (" BinaryView" );
55- m_logger = CreateLogger (" BinaryView.ElfView" );
5667 m_elf32 = m_ident.fileClass == 1 ;
5768 m_addressSize = (m_ident.fileClass == 1 || (m_plat && m_plat->GetName () == " linux-32" )) ? 4 : 8 ;
5869 m_endian = endian;
@@ -71,9 +82,6 @@ ElfView::ElfView(BinaryView* data, bool parseOnly): BinaryView("ELF", data->GetF
7182 memset (&m_sectionStringTable, 0 , sizeof (m_sectionStringTable));
7283 memset (&m_sectionOpd, 0 , sizeof (m_sectionOpd));
7384
74- m_logger->LogInfo (" Detected %s endian ELF" , m_endian == LittleEndian ? " Little Endian" : " Big Endian" );
75-
76-
7785 if (m_elf32 && (header.sectionHeaderSize != sizeof (Elf32SectionHeader)))
7886 {
7987 m_logger->LogWarn (
@@ -2873,9 +2881,9 @@ bool ElfViewType::IsTypeValidForData(BinaryView* data)
28732881}
28742882
28752883
2876- uint64_t ElfViewType ::ParseHeaders (BinaryView* data, ElfIdent& ident, ElfCommonHeader& commonHeader, Elf64Header& header, Ref<Architecture>* arch, Ref<Platform>* plat, string& errorMsg, BNEndianness& endianness)
2884+ uint64_t ElfView ::ParseHeaders (BinaryView* data, ElfIdent& ident, ElfCommonHeader& commonHeader, Elf64Header& header, Ref<Architecture>* arch, Ref<Platform>* plat, string& errorMsg, BNEndianness& endianness)
28772885{
2878- if (!IsTypeValidForData (data))
2886+ if (!g_elfViewType-> IsTypeValidForData (data))
28792887 {
28802888 errorMsg = " invalid signature" ;
28812889 return 0 ;
@@ -2889,16 +2897,49 @@ uint64_t ElfViewType::ParseHeaders(BinaryView* data, ElfIdent& ident, ElfCommonH
28892897 }
28902898
28912899 BinaryReader reader (data);
2900+
2901+ // Determine endianness from header encoding
2902+ BNEndianness headerEndianness;
28922903 if (ident.encoding <= 1 )
2893- endianness = LittleEndian;
2904+ headerEndianness = LittleEndian;
28942905 else if (ident.encoding == 2 )
2895- endianness = BigEndian;
2906+ headerEndianness = BigEndian;
28962907 else
28972908 {
28982909 errorMsg = " invalid encoding" ;
28992910 return 0 ;
29002911 }
29012912
2913+ // Use header endianness by default
2914+ endianness = headerEndianness;
2915+
2916+ // Check for automatic x86 endianness override
2917+ bool overrideX86Endianness = Settings::Instance ()->Get <bool >(" files.elf.overrideX86Endianness" );
2918+ if (overrideX86Endianness)
2919+ {
2920+ // Peek at e_machine field (2 bytes at offset 0x12) with little-endian interpretation
2921+ uint8_t machineBytes[2 ];
2922+ if (data->Read (machineBytes, 0x12 , 2 ) == 2 )
2923+ {
2924+ uint16_t machineLE = machineBytes[0 ] | (machineBytes[1 ] << 8 );
2925+ if (machineLE == EM_386 || machineLE == EM_X86_64)
2926+ {
2927+ endianness = LittleEndian;
2928+ if (endianness != headerEndianness)
2929+ {
2930+ m_logger->LogWarn (" ELF endianness automatically overridden to little-endian for x86/x86_64 (header specified %s)" ,
2931+ headerEndianness == LittleEndian ? " little-endian" : " big-endian" );
2932+ }
2933+ }
2934+ }
2935+ }
2936+
2937+ // Log detected endianness if no override occurred
2938+ if (endianness == headerEndianness)
2939+ {
2940+ m_logger->LogInfo (" Detected %s ELF" , endianness == LittleEndian ? " little-endian" : " big-endian" );
2941+ }
2942+
29022943 // parse ElfCommonHeader
29032944 reader.SetEndianness (endianness);
29042945 reader.Seek (sizeof (ident));
0 commit comments