From d22e79d1cdeb8c91560bf643989077266822bf75 Mon Sep 17 00:00:00 2001 From: Llod Kinsella Date: Tue, 9 Feb 2016 19:37:47 +0000 Subject: [PATCH] Work on the Debug directories. --- Src/Demo Application/Program.cs | 2 +- .../Content/Debug/DebugContent.cs | 70 +++++ .../Content/Debug/DebugDirectory.cs | 280 ++++++++++++++++++ Src/Workshell.PE/Content/Imports/Imports.cs | 7 +- Src/Workshell.PE/DataDirectory.cs | 3 + Src/Workshell.PE/Workshell.PE.csproj | 2 + 6 files changed, 362 insertions(+), 2 deletions(-) create mode 100644 Src/Workshell.PE/Content/Debug/DebugContent.cs create mode 100644 Src/Workshell.PE/Content/Debug/DebugDirectory.cs diff --git a/Src/Demo Application/Program.cs b/Src/Demo Application/Program.cs index 430e931..6d6eb48 100644 --- a/Src/Demo Application/Program.cs +++ b/Src/Demo Application/Program.cs @@ -41,7 +41,7 @@ static void Main(string[] args) if (content == null) continue; - if (content.DataDirectory.DirectoryType == DataDirectoryType.ImportTable) + if (content.DataDirectory.DirectoryType == DataDirectoryType.Debug) { } diff --git a/Src/Workshell.PE/Content/Debug/DebugContent.cs b/Src/Workshell.PE/Content/Debug/DebugContent.cs new file mode 100644 index 0000000..24d4936 --- /dev/null +++ b/Src/Workshell.PE/Content/Debug/DebugContent.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Workshell.PE.Native; + +namespace Workshell.PE +{ + + public class DebugContent : DataDirectoryContent + { + + private ulong image_base; + private DebugDirectories directories; + + internal DebugContent(DataDirectory dataDirectory, ulong imageBase) : base(dataDirectory,imageBase) + { + image_base = imageBase; + + LocationCalculator calc = DataDirectory.Directories.Reader.GetCalculator(); + Stream stream = DataDirectory.Directories.Reader.GetStream(); + + LoadDirectories(calc, stream, imageBase); + } + + #region Methods + + private void LoadDirectories(LocationCalculator calc, Stream stream, ulong imageBase) + { + ulong offset = calc.RVAToOffset(DataDirectory.VirtualAddress); + Section section = calc.RVAToSection(DataDirectory.VirtualAddress); + Location location = new Location(offset, DataDirectory.VirtualAddress, imageBase + DataDirectory.VirtualAddress, DataDirectory.Size, DataDirectory.Size); + uint size = Convert.ToUInt32(Utils.SizeOf()); + long count = DataDirectory.Size / size; + List> dirs = new List>(); + + stream.Seek(Convert.ToInt64(offset), SeekOrigin.Begin); + + for(var i = 0; i < count; i++) + { + IMAGE_DEBUG_DIRECTORY entry = Utils.Read(stream, Convert.ToInt32(size)); + + dirs.Add(new Tuple(offset,entry)); + + offset += size; + } + + directories = new DebugDirectories(this, location, section, dirs); + } + + #endregion + + #region Properties + + public DebugDirectories Directories + { + get + { + return directories; + } + } + + #endregion + + } + +} diff --git a/Src/Workshell.PE/Content/Debug/DebugDirectory.cs b/Src/Workshell.PE/Content/Debug/DebugDirectory.cs new file mode 100644 index 0000000..938fd77 --- /dev/null +++ b/Src/Workshell.PE/Content/Debug/DebugDirectory.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Workshell.PE.Annotations; +using Workshell.PE.Native; + +namespace Workshell.PE +{ + + public enum DebugDirectoryType + { + [EnumAnnotation("IMAGE_DEBUG_TYPE_UNKNOWN")] + Unknown = 0, + [EnumAnnotation("IMAGE_DEBUG_TYPE_COFF")] + COFF = 1, + [EnumAnnotation("IMAGE_DEBUG_TYPE_CODEVIEW")] + CodeView = 2, + [EnumAnnotation("IMAGE_DEBUG_TYPE_FPO")] + FPO = 3, + [EnumAnnotation("IMAGE_DEBUG_TYPE_MISC")] + Misc = 4, + [EnumAnnotation("IMAGE_DEBUG_TYPE_EXCEPTION")] + Exception = 5, + [EnumAnnotation("IMAGE_DEBUG_TYPE_FIXUP")] + Fixup = 6, + [EnumAnnotation("IMAGE_DEBUG_TYPE_OMAP_TO_SRC")] + OMAPToSrc = 7, + [EnumAnnotation("IMAGE_DEBUG_TYPE_OMAP_FROM_SRC")] + OMAPFromSrc = 8, + [EnumAnnotation("IMAGE_DEBUG_TYPE_BORLAND")] + Bolrand = 9, + [EnumAnnotation("IMAGE_DEBUG_TYPE_RESERVED10")] + Reserved = 10, + [EnumAnnotation("IMAGE_DEBUG_TYPE_CLSID")] + CLSID = 11, + [EnumAnnotation("IMAGE_DEBUG_TYPE_VC_FEATURE")] + VCFeature = 12, + [EnumAnnotation("IMAGE_DEBUG_TYPE_POGO")] + POGO = 13, + [EnumAnnotation("IMAGE_DEBUG_TYPE_ILTCG")] + ILTCG = 14, + [EnumAnnotation("IMAGE_DEBUG_TYPE_MPX")] + MPX = 15 + } + + public class DebugDirectory : ISupportsLocation, ISupportsBytes + { + + public static readonly int size = Utils.SizeOf(); + + private DebugDirectories directories; + private Location location; + private IMAGE_DEBUG_DIRECTORY directory; + + internal DebugDirectory(DebugDirectories debugDirs, Location dirLocation, IMAGE_DEBUG_DIRECTORY dir) + { + directories = debugDirs; + location = dirLocation; + directory = dir; + } + + #region Methods + + public override string ToString() + { + return String.Format("Debug Type: {0}", GetDirectoryType()); + } + + public byte[] GetBytes() + { + Stream stream = directories.Content.DataDirectory.Directories.Reader.GetStream(); + byte[] buffer = Utils.ReadBytes(stream, location); + + return buffer; + } + + public DateTime GetTimeDateStamp() + { + return Utils.ConvertTimeDateStamp(directory.TimeDateStamp); + } + + public DebugDirectoryType GetDirectoryType() + { + return (DebugDirectoryType)directory.Type; + } + + #endregion + + #region Properties + + public DebugDirectories Directory + { + get + { + return directories; + } + } + + public Location Location + { + get + { + return location; + } + } + + [FieldAnnotation("Characteristics")] + public uint Characteristics + { + get + { + return directory.Characteristics; + } + } + + [FieldAnnotation("Date/Time Stamp")] + public uint TimeDateStamp + { + get + { + return directory.TimeDateStamp; + } + } + + [FieldAnnotation("Major Version")] + public ushort MajorVersion + { + get + { + return directory.MajorVersion; + } + } + + [FieldAnnotation("Minor Version")] + public ushort MinorVersion + { + get + { + return directory.MinorVersion; + } + } + + [FieldAnnotation("Type")] + public uint Type + { + get + { + return directory.Type; + } + } + + [FieldAnnotation("Size of Data")] + public uint SizeOfData + { + get + { + return directory.SizeOfData; + } + } + + [FieldAnnotation("Address of Raw Data")] + public uint AddressOfRawData + { + get + { + return directory.AddressOfRawData; + } + } + + [FieldAnnotation("Pointer to Raw Data")] + public uint PointerToRawData + { + get + { + return directory.PointerToRawData; + } + } + + #endregion + + } + + public class DebugDirectories : IEnumerable + { + + private DebugContent content; + private Location location; + private Section section; + private List directories; + + internal DebugDirectories(DebugContent debugContent, Location dirLocation, Section dirSection, List> dirs) + { + content = debugContent; + location = dirLocation; + section = dirSection; + directories = new List(); + + LoadDirectories(dirs); + } + + public IEnumerator GetEnumerator() + { + return directories.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public override string ToString() + { + return String.Format("Debug Entry Count: {0}", directories.Count); + } + + private void LoadDirectories(List> dirEntries) + { + LocationCalculator calc = content.DataDirectory.Directories.Reader.GetCalculator(); + ulong image_base = content.DataDirectory.Directories.Reader.NTHeaders.OptionalHeader.ImageBase; + uint size = Convert.ToUInt32(Utils.SizeOf()); + + foreach(Tuple tuple in dirEntries) + { + uint rva = calc.OffsetToRVA(section, tuple.Item1); + ulong va = image_base + rva; + Location dir_location = new Location(tuple.Item1, rva, va, size, size); + DebugDirectory dir = new DebugDirectory(this, dir_location, tuple.Item2); + + directories.Add(dir); + } + } + + public DebugContent Content + { + get + { + return content; + } + } + + public Location Location + { + get + { + return location; + } + } + + public Section Section + { + get + { + return section; + } + } + + public int Count + { + get + { + return directories.Count; + } + } + + public DebugDirectory this[int index] + { + get + { + return this[index]; + } + } + + } + +} diff --git a/Src/Workshell.PE/Content/Imports/Imports.cs b/Src/Workshell.PE/Content/Imports/Imports.cs index 6db71fc..b25fc5b 100644 --- a/Src/Workshell.PE/Content/Imports/Imports.cs +++ b/Src/Workshell.PE/Content/Imports/Imports.cs @@ -36,6 +36,11 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() return GetEnumerator(); } + public override string ToString() + { + return String.Format("Library Count: {0}", libraries.Count); + } + private void LoadLibraries(IEnumerable> importLibraries) { foreach(Tuple tuple in importLibraries) @@ -74,7 +79,7 @@ public ImportLibrary this[int index] } } - public ImportLibrary this[string libraryName] + public ImportLibrary this[string libraryName] { get { diff --git a/Src/Workshell.PE/DataDirectory.cs b/Src/Workshell.PE/DataDirectory.cs index 6199964..fe69d7d 100644 --- a/Src/Workshell.PE/DataDirectory.cs +++ b/Src/Workshell.PE/DataDirectory.cs @@ -90,6 +90,9 @@ private void LoadContent() case DataDirectoryType.ImportTable: dir_content = new ImportTableContent(this,image_base); break; + case DataDirectoryType.Debug: + dir_content = new DebugContent(this, image_base); + break; default: dir_content = null; break; diff --git a/Src/Workshell.PE/Workshell.PE.csproj b/Src/Workshell.PE/Workshell.PE.csproj index c3e4d0f..0ace72d 100644 --- a/Src/Workshell.PE/Workshell.PE.csproj +++ b/Src/Workshell.PE/Workshell.PE.csproj @@ -44,6 +44,8 @@ + +