Skip to content

Commit

Permalink
Work on the Debug directories.
Browse files Browse the repository at this point in the history
  • Loading branch information
lkinsella committed Feb 9, 2016
1 parent b85d2bd commit d22e79d
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Src/Demo Application/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{

}
Expand Down
70 changes: 70 additions & 0 deletions Src/Workshell.PE/Content/Debug/DebugContent.cs
Original file line number Diff line number Diff line change
@@ -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<IMAGE_DEBUG_DIRECTORY>());
long count = DataDirectory.Size / size;
List<Tuple<ulong,IMAGE_DEBUG_DIRECTORY>> dirs = new List<Tuple<ulong,IMAGE_DEBUG_DIRECTORY>>();

stream.Seek(Convert.ToInt64(offset), SeekOrigin.Begin);

for(var i = 0; i < count; i++)
{
IMAGE_DEBUG_DIRECTORY entry = Utils.Read<IMAGE_DEBUG_DIRECTORY>(stream, Convert.ToInt32(size));

dirs.Add(new Tuple<ulong, IMAGE_DEBUG_DIRECTORY>(offset,entry));

offset += size;
}

directories = new DebugDirectories(this, location, section, dirs);
}

#endregion

#region Properties

public DebugDirectories Directories
{
get
{
return directories;
}
}

#endregion

}

}
280 changes: 280 additions & 0 deletions Src/Workshell.PE/Content/Debug/DebugDirectory.cs
Original file line number Diff line number Diff line change
@@ -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<IMAGE_DEBUG_DIRECTORY>();

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<DebugDirectory>
{

private DebugContent content;
private Location location;
private Section section;
private List<DebugDirectory> directories;

internal DebugDirectories(DebugContent debugContent, Location dirLocation, Section dirSection, List<Tuple<ulong,IMAGE_DEBUG_DIRECTORY>> dirs)
{
content = debugContent;
location = dirLocation;
section = dirSection;
directories = new List<DebugDirectory>();

LoadDirectories(dirs);
}

public IEnumerator<DebugDirectory> 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<Tuple<ulong, IMAGE_DEBUG_DIRECTORY>> dirEntries)
{
LocationCalculator calc = content.DataDirectory.Directories.Reader.GetCalculator();
ulong image_base = content.DataDirectory.Directories.Reader.NTHeaders.OptionalHeader.ImageBase;
uint size = Convert.ToUInt32(Utils.SizeOf<IMAGE_DEBUG_DIRECTORY>());

foreach(Tuple<ulong, IMAGE_DEBUG_DIRECTORY> 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];
}
}

}

}
7 changes: 6 additions & 1 deletion Src/Workshell.PE/Content/Imports/Imports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Tuple<string,ImportAddressTable,ImportHintNameTable>> importLibraries)
{
foreach(Tuple<string,ImportAddressTable,ImportHintNameTable> tuple in importLibraries)
Expand Down Expand Up @@ -74,7 +79,7 @@ public ImportLibrary this[int index]
}
}

public ImportLibrary this[string libraryName]
public ImportLibrary this[string libraryName]
{
get
{
Expand Down
3 changes: 3 additions & 0 deletions Src/Workshell.PE/DataDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit d22e79d

Please sign in to comment.