public override void Analyze(BinaryAnalyzerContext context) { IELF elf = context.ELFBinary().ELF; if (elf.Type == FileType.Executable) { context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Error, context, null, nameof(RuleResources.BA3001_Error), context.TargetUri.GetFileName())); return; } else if (elf.Type == FileType.SharedObject) { // Check that it is an executable SO instead of a normal shared library // Looking for a program header segment seems to work well here. if (elf.Segments.Where(seg => seg.Type == SegmentType.ProgramHeader).Any()) { context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA3001_Pass_Executable), context.TargetUri.GetFileName())); return; } else { // '{0}' does not have an imports section that is marked as executable. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA3001_Pass_Library), context.TargetUri.GetFileName())); return; } } }
public OpenRiscExecutable(IELF elf) { _elf = elf; _instructionSet = Resolver.CreateInstructionSet(); _disassemble(); }
/// <summary> /// Get the compilers used to create an ELF binary. /// </summary> /// <param name="elf">ELF binary</param> /// <returns>List of compiler tools from the .comment section</returns> internal static ELFCompiler[] GetELFCompilers(IELF elf) { ISection commentSection = elf.Sections.Where(s => s.Name == ".comment").FirstOrDefault(); if (commentSection != null) { try { string[] commentData = NullTermAsciiToStrings(commentSection.GetContents()); var compilers = new ELFCompiler[commentData.Length]; for (int i = 0; i < commentData.Length; i++) { compilers[i] = new ELFCompiler(commentData[i]); } return(compilers); } // Catch cases when the .comment section is not formatted the way we expect it to be. catch (Exception ex) when(ex is ArgumentException || ex is ArgumentNullException) { return(new ELFCompiler[] { new ELFCompiler(string.Empty) }); } } else { return(new ELFCompiler[] { new ELFCompiler(string.Empty) }); } }
public override void Analyze(BinaryAnalyzerContext context) { IELF elf = context.ELFBinary().ELF; HashSet <string> symbolNames = new HashSet <string> ( ELFUtility.GetAllSymbols(elf).Select <ISymbolEntry, string>(sym => sym.Name) ); foreach (string stack_chk in stack_check_symbols) { if (symbolNames.Contains(stack_chk)) { context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA3003_Pass), context.TargetUri.GetFileName())); return; } } // If we haven't found the stack protector, we assume it wasn't used. context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Error, context, null, nameof(RuleResources.BA3003_Error), context.TargetUri.GetFileName())); }
public DWARFData(IELF elf) { // The order of loaded sections matters, do not change. StringSection = new DebugStringsSection(elf.GetSection(".debug_str")); AbbrevSection = new DebugAbbrevSection(elf.GetSection(".debug_abbrev")); InfoSection = new DebugInfoSection(this, elf.GetSection(".debug_info")); LineSection = new DebugLineSection(this, elf.GetSection(".debug_line")); }
protected static ISection?GetSection(IELF elf, string sectionName) { if (!elf.TryGetSection(sectionName, out ISection section)) { return(null); } return(section); }
protected AnELF(Stream stream, string filePath, IELF elf, ISymbolTable dynsymSection, ISection rodataSection, ISymbolTable?symSection) { this.filePath = filePath; this.elf = elf; elfStream = stream; dynamicSymbolsSection = dynsymSection; this.rodataSection = rodataSection; symbolsSection = symSection; }
public static void Main(string[] args) { Console.Title = "MinecraftSymbols"; Console.WriteLine("File path :"); Console.Write("> "); string FilePath = Console.ReadLine(); if (!File.Exists(FilePath)) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("File not found."); Console.ReadKey(); return; } InitDump(); Thread.Sleep(1000); writeCpp("// File automatically generated by MinecraftSymbols"); writeCpp(""); IELF Elf = ELFReader.Load(FilePath); SymbolTable <uint> Symbols = (SymbolTable <uint>)Elf.GetSection(".dynsym"); foreach (var Symbol in Symbols.Entries) { Console.Title = "MinecraftSymbols || " + Dumped + " symbols"; if (Symbol.Value != 0 && Symbol.Name.StartsWith("_Z")) { // ToDo more work on writeCpp if (Symbol.Type == SymbolType.Object) { writeCpp("// Address : " + Symbol.Value.ToString("x8")); writeCpp("extern \"C\"" + Environment.NewLine + "{" + Environment.NewLine + " void* " + Symbol.Name + ";\n}"); writeCpp(""); } if (Symbol.Type == SymbolType.Function) { writeCpp("// Address : " + Symbol.Value.ToString("x8")); writeCpp("extern \"C\"" + Environment.NewLine + "{" + Environment.NewLine + " void* " + Symbol.Name + "_ptr;\n}"); writeCpp(""); } Dumped++; Console.WriteLine("Dumped symbol : " + Symbol.Name + " (" + Symbol.Value.ToString("x8") + ")"); } } Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("All the Minecraft symbols have been dumped."); Console.ReadKey(); }
/// <summary> /// Checks if Fortified functions are used--the -DFORTIFY_SOURCE=2 flag enables these when -O2 is enabled. /// /// Check implementation: /// -Get all function symbols in the ELF binary /// -Check for any fortified functions--if we find any, we used the option. /// -Check for any unfortified functions. If we only find unfortified functions, one of two things is true: /// 1) Fortify Source wasn't used; or /// 2) Fortify Source was used, but gcc/clang was unable to statically find anything that needed to be fortified. /// We report on both cases. /// -If no fortifiable functions were used at all, the rule doesn't apply. /// </summary> public override void Analyze(BinaryAnalyzerContext context) { IELF elf = context.ELFBinary().ELF; IEnumerable <ISymbolEntry> symbols = ELFUtility.GetAllSymbols(elf).Where(sym => sym.Type == SymbolType.Function || sym.Type == SymbolType.Object); List <ISymbolEntry> protectedFunctions = new List <ISymbolEntry>(); List <ISymbolEntry> unprotectedFunctions = new List <ISymbolEntry>(); foreach (ISymbolEntry e in symbols) { if (unfortifiedFunctions.Contains(e.Name)) { unprotectedFunctions.Add(e); } else if (fortifiedFunctions.Contains(e.Name)) { protectedFunctions.Add(e); } } if (protectedFunctions.Any()) { if (unprotectedFunctions.Any()) { context.Logger.Log(this, RuleUtilities.BuildResult(ResultKind.Pass, context, null, nameof(RuleResources.BA3030_Pass_SomeFunctionsChecked), context.TargetUri.GetFileName())); } else { context.Logger.Log(this, RuleUtilities.BuildResult(ResultKind.Pass, context, null, nameof(RuleResources.BA3030_Pass_AllFunctionsChecked), context.TargetUri.GetFileName())); } } else if (unprotectedFunctions.Any()) { context.Logger.Log(this, RuleUtilities.BuildResult(FailureLevel.Error, context, null, nameof(RuleResources.BA3030_Error), context.TargetUri.GetFileName())); } else { context.Logger.Log(this, RuleUtilities.BuildResult(ResultKind.Pass, context, null, nameof(RuleResources.BA3030_Pass_NoCheckableFunctions), context.TargetUri.GetFileName())); } }
/// <summary> /// Gets all of the symbol entries from an ELF binary and returns it /// as an IEnumerable. /// </summary> /// <param name="elf">ELF to get the symbols from</param> /// <returns>List of all entries in every symbol table in the ELF binary</returns> public static IEnumerable <ISymbolEntry> GetAllSymbols(IELF elf) { IEnumerable <ISymbolTable> symbolTables = elf.GetSections <ISymbolTable>(); return(symbolTables.Aggregate( new List <ISymbolEntry>(), (agg, next) => { agg.AddRange(next.Entries); return agg; } )); }
public static int GetBitness(this IELF elf) { if (elf is ELF <uint> ) { return(32); } if (elf is ELF <ulong> ) { return(64); } throw new ArgumentException(ExceptionMessage); }
public static ulong GetEntryPoint(this IELF elf) { if (elf is ELF <uint> elf32) { return(elf32.EntryPoint); } if (elf is ELF <ulong> elf64) { return(elf64.EntryPoint); } throw new ArgumentException(ExceptionMessage); }
public override AnalysisApplicability CanAnalyzeElf(ELFBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing) { IELF elf = target.ELF; if (elf.Type == FileType.Core || elf.Type == FileType.None || elf.Type == FileType.Relocatable) { reasonForNotAnalyzing = reasonForNotAnalyzing = MetadataConditions.ElfIsCoreNoneOrObject; return(AnalysisApplicability.NotApplicableToSpecifiedTarget); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
/// <summary> /// Loads the symbols from ELF and puts the symbols into the SymbolLookup. /// </summary> /// <param name="elf">Elf.</param> public void LoadELF(IELF elf, bool useVirtualAddress) { if (elf is ELF <uint> elf32) { LoadELF(elf32, useVirtualAddress); } else if (elf is ELF <ulong> elf64) { LoadELF(elf64, useVirtualAddress); } else { throw new ArgumentException("Unsupported ELF format - only 32 and 64-bit ELFs are supported"); } }
private async Task Collect(string path) { var files = Directory.GetFiles(path); _logger.LogInformation("Path {path} has {length} files to process", path, files.Length); foreach (var file in files) { _logger.LogInformation("Processing file: {file}.", file); IELF elf = null; try { if (!ELFReader.TryLoad(file, out elf)) { _logger.LogWarning("Couldn't load': {file} with ELF reader.", file); continue; } var hasBuildId = elf.TryGetSection(".note.gnu.build-id", out var buildId); if (!hasBuildId) { _logger.LogWarning("No Debug Id in {file}", file); continue; } var hasUnwindingInfo = elf.TryGetSection(".eh_frame", out _); var hasDwarfDebugInfo = elf.TryGetSection(".debug_frame", out _); if (!hasUnwindingInfo && !hasDwarfDebugInfo) { _logger.LogWarning("No unwind nor DWARF debug info in {file}", file); continue; } await ProcessFile(file, hasUnwindingInfo, hasDwarfDebugInfo, buildId, elf); } catch (Exception e) { // You would expect TryLoad doesn't throw but that's not the case _logger.LogError(e, "Failed processing file {file}.", file); } finally { elf?.Dispose(); } } }
public static bool TryLoad(Stream stream, bool shouldOwnStream, out IELF elf) { switch (CheckELFType(stream)) { case Class.Bit32: elf = new ELF <uint>(stream, shouldOwnStream); return(true); case Class.Bit64: elf = new ELF <ulong>(stream, shouldOwnStream); return(true); default: elf = null; return(false); } }
public static bool TryLoad(string fileName, out IELF elf) { switch (CheckELFType(fileName)) { case Class.Bit32: elf = new ELF <uint>(fileName); return(true); case Class.Bit64: elf = new ELF <long>(fileName); return(true); default: elf = null; return(false); } }
private Symbol LoadDebugContextInfo(IELF elfFile) { var symbols = ((ISymbolTable)elfFile.GetSection(".symtab")).Entries.Where(x => x.Type == SymbolType.Object); if (_debugCtxSymbol == null) { var entry = symbols.FirstOrDefault(s => s.Name == "dbg_context"); if (entry != null) { return(new Symbol { Size = (uint)entry.Size, Location = (uint)(entry.Value - _entryOffset) }); } } return(null); }
private static Cpu GetCpu(IELF elfData) { switch (elfData.Machine) { case Machine.Intel386: return Cpu.I386; case Machine.Intel486: return Cpu.I486; case Machine.AMD64: return Cpu.X64; case Machine.PPC: return Cpu.Ppc; case Machine.PPC64: return Cpu.Ppc64; default: return Cpu.Unknown; } }
protected static ISymbolTable?GetSymbolTable(IELF elf, string sectionName) { ISection?section = GetSection(elf, sectionName); if (section == null) { return(null); } var symtab = section as ISymbolTable; if (symtab == null) { return(null); } return(symtab); }
/// <summary> /// Dumps the Sections and Segments from an .ELF loaded via ElfSharp /// </summary> /// <param name="inElf"></param> public static void DumpElfInfo(IELF inElf) { ConsoleColor oldColor = Console.ForegroundColor; Console.WriteLine("\nNum ELF sections: " + inElf.Sections.Count); for (int i = 0; i < inElf.Sections.Count; i++) { Section <UInt32> sect = (inElf.Sections[i] as Section <UInt32>); Console.ForegroundColor = (sect.Size == 0)? ConsoleColor.Red : oldColor; Console.WriteLine($"Section {i}: {sect.Name}"); Console.WriteLine($" Addr: 0x{sect.LoadAddress.ToString("X")}"); Console.WriteLine($" Size: 0x{sect.Size.ToString( "X" )} (0x{sect.EntrySize.ToString("X")})"); Console.WriteLine($" Flags: {sect.Flags}"); //byte[] b = sect.GetContents(); //File.WriteAllBytes( "sect_" + sect.Name, b ); } Console.WriteLine("\nNum ELF segments: " + inElf.Segments.Count); for (int i = 0; i < inElf.Segments.Count; i++) { Segment <UInt32> seg = inElf.Segments[i] as Segment <UInt32>; // Some segs have the .elf magic number Console.ForegroundColor = HasElfHeader(seg.GetFileContents()) ? ConsoleColor.Red : oldColor; Console.WriteLine("Segment " + i); Console.WriteLine($" Offset : 0x{seg.Offset.ToString("X")}"); Console.WriteLine($" Size : 0x{seg.Size.ToString("X")} (0x{seg.FileSize.ToString("X")})"); Console.WriteLine($" PhysAddr : 0x{seg.PhysicalAddress.ToString("X")} for 0x{seg.Address.ToString("X")}"); Console.WriteLine($" Flags : " + seg.Flags); Console.WriteLine($" Type : " + seg.Type); //byte[] b = seg.GetFileContents(); //File.WriteAllBytes( "seg_" + i, b ); } Console.ForegroundColor = oldColor; }
public override void InitFromElf(IELF elf) { base.InitFromElf(elf); var bamSection = elf.GetSections <Section <uint> >().FirstOrDefault(x => x.Name == ".__bam_bootarea"); if (bamSection != null) { var bamSectionContents = bamSection.GetContents(); var isValidResetConfigHalfWord = bamSectionContents[1] == 0x5a; if (!isValidResetConfigHalfWord) { this.Log(LogLevel.Warning, "Invalid BAM section, ignoring."); } else { StartInVle = (bamSectionContents[0] & 0x1) == 1; this.Log(LogLevel.Info, "Will {0}start in VLE mode.", StartInVle ? "" : "not "); } } }
/// <inheritdoc/> internal override bool Analyze(DirectoryInfo baseDirectory, FileInfo file) { if (!base.Analyze(baseDirectory, file)) { return(false); } if (!HasMagicBytes(file)) { return(false); } Name = file.Name; Architecture = new Architecture(OS.Linux, Cpu.All); IELF elfData = null; try { if (ELFReader.TryLoad(file.FullName, out elfData)) { if (elfData.Class == Class.NotELF || elfData.Type != FileType.Executable) { return(false); } Architecture = new Architecture(OS.Linux, GetCpu(elfData)); } } catch (NullReferenceException) {} finally { if (elfData != null) { elfData.Dispose(); } } return(true); }
private List <MemSegment> ReadFlash(string fileName, out bool containsBootloader) { IELF elf = ELFReader.Load(fileName); List <MemSegment> segments = new List <MemSegment>(); containsBootloader = false; foreach (var seg in elf.Segments) { ELFSharp.ELF.Segments.Segment <uint> sec32 = seg as ELFSharp.ELF.Segments.Segment <uint>; if (sec32 == null || sec32.Type != ELFSharp.ELF.Segments.SegmentType.Load || sec32.Size == 0) { continue; } if ((sec32.PhysicalAddress + sec32.Size) > FlashEnd) { continue; } if (sec32.PhysicalAddress < BootloaderEnd) { containsBootloader = true; } MemSegment memSeg = new MemSegment(sec32.PhysicalAddress, sec32.GetMemoryContents()); var match = segments.Where(s => s.Contains(memSeg)).FirstOrDefault(); if (match != null) { match.Add(memSeg); } else { segments.Add(memSeg); } } return(segments); }
public override AnalysisApplicability CanAnalyzeElf(ELFBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing) { IELF elf = target.ELF; if (elf.Type == FileType.Core || elf.Type == FileType.None || elf.Type == FileType.Relocatable) { reasonForNotAnalyzing = MetadataConditions.ElfIsCoreNoneOrObject; return(AnalysisApplicability.NotApplicableToSpecifiedTarget); } // We check for "any usage of non-gcc" as a default/standard compilation with clang leads to [GCC, Clang] // either because it links with a gcc-compiled object (cstdlib) or the linker also reading as GCC. // This has a potential for a False Negative if teams are using GCC and other tools. if (target.Compilers.Any(c => c.Compiler != ELFCompilerType.GCC)) { reasonForNotAnalyzing = MetadataConditions.ElfNotBuiltWithGcc; return(AnalysisApplicability.NotApplicableToSpecifiedTarget); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
private static Cpu GetCpu(IELF elfData) { switch (elfData.Machine) { case Machine.Intel386: return(Cpu.I386); case Machine.Intel486: return(Cpu.I486); case Machine.AMD64: return(Cpu.X64); case Machine.PPC: return(Cpu.Ppc); case Machine.PPC64: return(Cpu.Ppc64); default: return(Cpu.Unknown); } }
public override void Analyze(BinaryAnalyzerContext context) { IELF elf = context.ELFBinary().ELF; foreach (var seg in elf.Segments) { if (((uint)seg.Type) == GNU_RELRO_ID) { // Pass context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Pass, context, null, nameof(RuleResources.BA3010_Pass), context.TargetUri.GetFileName())); return; } } // Fail context.Logger.Log(this, RuleUtilities.BuildResult(ResultLevel.Error, context, null, nameof(RuleResources.BA3010_Error), context.TargetUri.GetFileName())); }
public override void Analyze(BinaryAnalyzerContext context) { IELF elf = context.ELFBinary().ELF; // Look for the GNU_STACK segment foreach (ISegment seg in elf.Segments) { if (((uint)seg.Type) == GNU_STACK_ID) { // if we find it, we'll check if it's NX... if ((seg.Flags & SegmentFlags.Execute) != 0) { // Fail -- stack seg is marked executable context.Logger.Log(this, RuleUtilities.BuildResult(FailureLevel.Error, context, null, nameof(RuleResources.BA3002_Error_StackExec), context.TargetUri.GetFileName())); return; } else { // Pass -- stack segment isn't executable context.Logger.Log(this, RuleUtilities.BuildResult(ResultKind.Pass, context, null, nameof(RuleResources.BA3002_Pass), context.TargetUri.GetFileName())); return; } } } // If the GNU_STACK isn't present, the stack is probably loaded as executable context.Logger.Log(this, RuleUtilities.BuildResult(FailureLevel.Error, context, null, nameof(RuleResources.BA3002_Error_NoStackSeg), context.TargetUri.GetFileName())); }
public override void Analyze(BinaryAnalyzerContext context) { IELF elf = context.ELFBinary().ELF; if (elf.Type == FileType.Executable) { context.Logger.Log(this, RuleUtilities.BuildResult(FailureLevel.Error, context, null, nameof(RuleResources.BA3001_Error), context.TargetUri.GetFileName())); return; } else if (elf.Type == FileType.SharedObject) { // Check that it is an executable SO instead of a normal shared library // Looking for a program header segment seems to work well here. if (elf.Segments.Where(seg => seg.Type == SegmentType.ProgramHeader).Any()) { // PIE enabled on executable '{0}'. context.Logger.Log(this, RuleUtilities.BuildResult(ResultKind.Pass, context, null, nameof(RuleResources.BA3001_Pass_Executable), context.TargetUri.GetFileName())); return; } else { // '{0}' is a shared object library rather than an executable, // and is automatically position independent. context.Logger.Log(this, RuleUtilities.BuildResult(ResultKind.Pass, context, null, nameof(RuleResources.BA3001_Pass_Library), context.TargetUri.GetFileName())); return; } } }
void IControllableCPU.InitFromElf(IELF elf) { // do nothing }
private static Cpu GetCpu(IELF elfData) => elfData.Machine switch {