Skip to content

Commit

Permalink
More refactoring, renamed reader to image.
Browse files Browse the repository at this point in the history
  • Loading branch information
lkinsella committed Jun 17, 2016
1 parent 372b999 commit 2e82efc
Show file tree
Hide file tree
Showing 22 changed files with 97 additions and 147 deletions.
14 changes: 7 additions & 7 deletions Src/Demo Application/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ static void Main(string[] args)
//string file_name = @"D:\Lloyd\Downloads\Win32DiskImager-0.9.5-install.exe";
string error_message;

if (!ImageReader.IsValid(file_name,out error_message))
if (!ExecutableImage.IsValid(file_name,out error_message))
{
Console.WriteLine("Invalid executable image: " + error_message);

return;
}

ImageReader reader = ImageReader.FromFile(file_name);
ExecutableImage image = ExecutableImage.FromFile(file_name);

LoadConfigDirectory load_config = LoadConfigDirectory.Get(reader.NTHeaders.DataDirectories[DataDirectoryType.LoadConfigTable]);
Certificate cert = Certificate.Get(reader.NTHeaders.DataDirectories[DataDirectoryType.CertificateTable]);
DebugDirectory debug_dir = DebugDirectory.Get(reader.NTHeaders.DataDirectories[DataDirectoryType.Debug]);
//TLSDirectory tls_dir = TLSDirectory.Get(reader.NTHeaders.DataDirectories[DataDirectoryType.TLSTable]);
LoadConfigDirectory load_config = LoadConfigDirectory.Get(image);
Certificate cert = Certificate.Get(image);
DebugDirectory debug_dir = DebugDirectory.Get(image);
TLSDirectory tls_dir = TLSDirectory.Get(image);

ExportDirectory export_dir = ExportDirectory.Get(reader.NTHeaders.DataDirectories[DataDirectoryType.ExportTable]);
ExportDirectory export_dir = ExportDirectory.Get(image);
ExportTable<uint> function_addresses = ExportTable<uint>.GetFunctionAddressTable(export_dir);
ExportTable<uint> name_addresses = ExportTable<uint>.GetNameAddressTable(export_dir);
ExportTable<ushort> ordinals = ExportTable<ushort>.GetOrdinalTable(export_dir);
Expand Down
21 changes: 8 additions & 13 deletions Src/Workshell.PE/Content/Certificates/Certificate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum CertificateType : ushort
PKCS1ModuleSign = 0x0009
}

public sealed class Certificate : DataDirectoryContent, ISupportsBytes
public sealed class Certificate : ExecutableImageContent, ISupportsBytes
{

private WIN_CERTIFICATE cert;
Expand All @@ -32,28 +32,23 @@ internal Certificate(DataDirectory dataDirectory, Location certLocation, WIN_CER

#region Static Methods

public static Certificate Get(DataDirectory directory)
public static Certificate Get(ExecutableImage image)
{
if (directory == null)
throw new ArgumentNullException("directory", "No data directory was specified.");
if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.CertificateTable))
return null;

if (directory.DirectoryType != DataDirectoryType.CertificateTable)
throw new DataDirectoryException("Cannot create instance, directory is not the Certificate Table.");
DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.CertificateTable];

if (directory.VirtualAddress == 0 && directory.Size == 0)
throw new DataDirectoryException("Certificate Table address and size are 0.");
if (DataDirectory.IsNullOrEmpty(directory))
return null;

Stream stream = directory.Directories.Reader.GetStream();
long file_offset = directory.VirtualAddress.ToInt64();

if (file_offset > stream.Length)
throw new DataDirectoryException("Certificate Table offset is beyond end of stream.");
stream.Seek(file_offset, SeekOrigin.Begin);

ulong image_base = directory.Directories.Reader.NTHeaders.OptionalHeader.ImageBase;
Location location = new Location(directory.VirtualAddress, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size);

stream.Seek(file_offset, SeekOrigin.Begin);

WIN_CERTIFICATE win_cert = Utils.Read<WIN_CERTIFICATE>(stream);
Certificate cert = new Certificate(directory, location, win_cert);

Expand Down
4 changes: 2 additions & 2 deletions Src/Workshell.PE/Content/DataDirectoryContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
namespace Workshell.PE
{

public abstract class DataDirectoryContent : ISupportsLocation
public abstract class ExecutableImageContent : ISupportsLocation
{

private DataDirectory directory;
private Location location;

public DataDirectoryContent(DataDirectory dataDirectory, Location dataLocation)
public ExecutableImageContent(DataDirectory dataDirectory, Location dataLocation)
{
directory = dataDirectory;
location = dataLocation;
Expand Down
21 changes: 7 additions & 14 deletions Src/Workshell.PE/Content/Debug/DebugDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public uint PointerToRawData

}

public sealed class DebugDirectory : DataDirectoryContent, IEnumerable<DebugDirectoryEntry>, ISupportsBytes
public sealed class DebugDirectory : ExecutableImageContent, IEnumerable<DebugDirectoryEntry>, ISupportsBytes
{

private DebugDirectoryEntry[] entries;
Expand All @@ -208,16 +208,15 @@ internal DebugDirectory(DataDirectory dataDirectory, Location dirLocation, Tuple

#region Static Methods

public static DebugDirectory Get(DataDirectory directory)
public static DebugDirectory Get(ExecutableImage image)
{
if (directory == null)
throw new ArgumentNullException("directory", "No data directory was specified.");
if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.Debug))
return null;

if (directory.DirectoryType != DataDirectoryType.Debug)
throw new DataDirectoryException("Cannot create instance, directory is not the Debug Directory.");
DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.Debug];

if (directory.VirtualAddress == 0 && directory.Size == 0)
throw new DataDirectoryException("Debug Directory address and size are 0.");
if (DataDirectory.IsNullOrEmpty(directory))
return null;

LocationCalculator calc = directory.Directories.Reader.GetCalculator();
Section section = calc.RVAToSection(directory.VirtualAddress);
Expand All @@ -226,12 +225,6 @@ public static DebugDirectory Get(DataDirectory directory)
Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section);
Stream stream = directory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Debug Directory offset is beyond end of stream.");

if ((file_offset.ToInt64() + directory.Size) > stream.Length)
throw new DataDirectoryException("Debug Directory is beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

int size = Utils.SizeOf<IMAGE_DEBUG_DIRECTORY>();
Expand Down
28 changes: 10 additions & 18 deletions Src/Workshell.PE/Content/Exports/ExportDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace Workshell.PE
{

public class ExportDirectory : DataDirectoryContent, ISupportsBytes
public class ExportDirectory : ExecutableImageContent, ISupportsBytes
{

private static readonly int size = Utils.SizeOf<IMAGE_EXPORT_DIRECTORY>();
Expand All @@ -35,16 +35,15 @@ internal ExportDirectory(DataDirectory dataDirectory, Location dirLocation, IMAG

#region Static Methods

public static ExportDirectory Get(DataDirectory directory)
public static ExportDirectory Get(ExecutableImage image)
{
if (directory == null)
throw new ArgumentNullException("directory", "No data directory was specified.");
if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ExportTable))
return null;

if (directory.DirectoryType != DataDirectoryType.ExportTable)
throw new DataDirectoryException("Cannot create instance, directory is not the Export Table.");
DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.ExportTable];

if (directory.VirtualAddress == 0 && directory.Size == 0)
throw new DataDirectoryException("Export Table address and size are 0.");
if (DataDirectory.IsNullOrEmpty(directory))
return null;

LocationCalculator calc = directory.Directories.Reader.GetCalculator();
Section section = calc.RVAToSection(directory.VirtualAddress);
Expand All @@ -53,19 +52,12 @@ public static ExportDirectory Get(DataDirectory directory)
Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section);
Stream stream = directory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Export Table offset is beyond end of stream.");

int size = Utils.SizeOf<IMAGE_EXPORT_DIRECTORY>();

if ((file_offset.ToInt64() + size) > stream.Length)
throw new DataDirectoryException("Export directory extends beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

IMAGE_EXPORT_DIRECTORY export_directory = Utils.Read<IMAGE_EXPORT_DIRECTORY>(stream, size);
IMAGE_EXPORT_DIRECTORY export_directory = Utils.Read<IMAGE_EXPORT_DIRECTORY>(stream);
ExportDirectory result = new ExportDirectory(directory, location, export_directory);

return new ExportDirectory(directory, location, export_directory);
return result;
}

#endregion
Expand Down
20 changes: 1 addition & 19 deletions Src/Workshell.PE/Content/Exports/ExportTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace Workshell.PE
{

public sealed class ExportTable<T> : DataDirectoryContent, IEnumerable<T>, ISupportsBytes
public sealed class ExportTable<T> : ExecutableImageContent, IEnumerable<T>, ISupportsBytes
{

private ExportDirectory directory;
Expand All @@ -37,12 +37,6 @@ public static ExportTable<uint> GetFunctionAddressTable(ExportDirectory director
Location location = new Location(file_offset, directory.AddressOfFunctions, image_base + directory.AddressOfFunctions, size, size, section);
Stream stream = directory.DataDirectory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Function addresses are beyond end of stream.");

if ((file_offset.ToInt64() + size) > stream.Length)
throw new DataDirectoryException("Function addresses extend beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

uint[] addresses = new uint[directory.NumberOfFunctions];
Expand Down Expand Up @@ -72,12 +66,6 @@ public static ExportTable<uint> GetNameAddressTable(ExportDirectory directory)
Location location = new Location(file_offset, directory.AddressOfNames, image_base + directory.AddressOfNames, size, size, section);
Stream stream = directory.DataDirectory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Name pointer addresses are beyond end of stream.");

if ((file_offset.ToInt64() + size) > stream.Length)
throw new DataDirectoryException("Name pointer addresses extend beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

uint[] addresses = new uint[directory.NumberOfFunctions];
Expand Down Expand Up @@ -107,12 +95,6 @@ public static ExportTable<ushort> GetOrdinalTable(ExportDirectory directory)
Location location = new Location(file_offset, directory.AddressOfNameOrdinals, image_base + directory.AddressOfNames, size, size, section);
Stream stream = directory.DataDirectory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Ordinals are beyond end of stream.");

if ((file_offset.ToInt64() + size) > stream.Length)
throw new DataDirectoryException("Ordinals extend beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

ushort[] ordinals = new ushort[directory.NumberOfFunctions];
Expand Down
20 changes: 8 additions & 12 deletions Src/Workshell.PE/Content/LoadConfig/LoadConfigDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Workshell.PE
{

public abstract class LoadConfigDirectory : DataDirectoryContent, ISupportsBytes
public abstract class LoadConfigDirectory : ExecutableImageContent, ISupportsBytes
{

internal LoadConfigDirectory(DataDirectory dataDirectory, Location configLocation) : base(dataDirectory,configLocation)
Expand All @@ -21,16 +21,15 @@ internal LoadConfigDirectory(DataDirectory dataDirectory, Location configLocatio

#region Static Methods

public static LoadConfigDirectory Get(DataDirectory directory)
public static LoadConfigDirectory Get(ExecutableImage image)
{
if (directory == null)
throw new ArgumentNullException("directory", "No data directory was specified.");
if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.LoadConfigTable))
return null;

if (directory.DirectoryType != DataDirectoryType.LoadConfigTable)
throw new DataDirectoryException("Cannot create instance, directory is not the Load Configuration Table.");
DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.LoadConfigTable];

if (directory.VirtualAddress == 0 && directory.Size == 0)
throw new DataDirectoryException("Load Configuration Table address and size are 0.");
if (DataDirectory.IsNullOrEmpty(directory))
return null;

LocationCalculator calc = directory.Directories.Reader.GetCalculator();
Section section = calc.RVAToSection(directory.VirtualAddress);
Expand All @@ -39,14 +38,11 @@ public static LoadConfigDirectory Get(DataDirectory directory)
Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section);
Stream stream = directory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Load Configuration offset is beyond end of stream.");
stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

bool is_64bit = directory.Directories.Reader.Is64Bit;
LoadConfigDirectory load_config_dir = null;

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

if (!is_64bit)
{
IMAGE_LOAD_CONFIG_DIRECTORY32 config_dir = Utils.Read<IMAGE_LOAD_CONFIG_DIRECTORY32>(stream);
Expand Down
18 changes: 7 additions & 11 deletions Src/Workshell.PE/Content/Relocation/RelocationTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Workshell.PE
{

public sealed class RelocationTable : DataDirectoryContent, IEnumerable<RelocationBlock>, ISupportsBytes
public sealed class RelocationTable : ExecutableImageContent, IEnumerable<RelocationBlock>, ISupportsBytes
{

private RelocationBlock[] blocks;
Expand All @@ -23,16 +23,15 @@ internal RelocationTable(DataDirectory dataDirectory, Location relocLocation, Tu

#region Static Methods

public static RelocationTable Get(DataDirectory directory)
public static RelocationTable Get(ExecutableImage image)
{
if (directory == null)
throw new ArgumentNullException("directory", "No data directory was specified.");
if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.Debug))
return null;

if (directory.DirectoryType != DataDirectoryType.BaseRelocationTable)
throw new DataDirectoryException("Cannot create instance, directory is not the Base Relocation Table.");
DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.Debug];

if (directory.VirtualAddress == 0 && directory.Size == 0)
throw new DataDirectoryException("Base Relocation Table address and size are 0.");
if (DataDirectory.IsNullOrEmpty(directory))
return null;

LocationCalculator calc = directory.Directories.Reader.GetCalculator();
Section section = calc.RVAToSection(directory.VirtualAddress);
Expand All @@ -41,9 +40,6 @@ public static RelocationTable Get(DataDirectory directory)
Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section);
Stream stream = directory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("Base Relocation Table offset is beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

ulong block_offset = file_offset;
Expand Down
18 changes: 7 additions & 11 deletions Src/Workshell.PE/Content/TLS/TLSDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Workshell.PE
{

public abstract class TLSDirectory : DataDirectoryContent, ISupportsBytes
public abstract class TLSDirectory : ExecutableImageContent, ISupportsBytes
{

internal TLSDirectory(DataDirectory dataDirectory, Location tlsLocation) : base(dataDirectory,tlsLocation)
Expand All @@ -21,16 +21,15 @@ internal TLSDirectory(DataDirectory dataDirectory, Location tlsLocation) : base(

#region Static Methods

public static TLSDirectory Get(DataDirectory directory)
public static TLSDirectory Get(ExecutableImage image)
{
if (directory == null)
throw new ArgumentNullException("directory", "No data directory was specified.");
if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.TLSTable))
return null;

if (directory.DirectoryType != DataDirectoryType.TLSTable)
throw new DataDirectoryException("Cannot create instance, directory is not the TLS Table.");
DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.TLSTable];

if (directory.VirtualAddress == 0 && directory.Size == 0)
throw new DataDirectoryException("TLS Table address and size are 0.");
if (DataDirectory.IsNullOrEmpty(directory))
return null;

LocationCalculator calc = directory.Directories.Reader.GetCalculator();
Section section = calc.RVAToSection(directory.VirtualAddress);
Expand All @@ -39,9 +38,6 @@ public static TLSDirectory Get(DataDirectory directory)
Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section);
Stream stream = directory.Directories.Reader.GetStream();

if (file_offset.ToInt64() > stream.Length)
throw new DataDirectoryException("TLS Table offset is beyond end of stream.");

stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin);

bool is_64bit = directory.Directories.Reader.Is64Bit;
Expand Down
4 changes: 2 additions & 2 deletions Src/Workshell.PE/DOSHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public sealed class DOSHeader : ISupportsLocation, ISupportsBytes

private static readonly int size = Utils.SizeOf<IMAGE_DOS_HEADER>();

private ImageReader reader;
private ExecutableImage reader;
private IMAGE_DOS_HEADER header;
private Location location;

internal DOSHeader(ImageReader exeReader, IMAGE_DOS_HEADER dosHeader, ulong imageBase)
internal DOSHeader(ExecutableImage exeReader, IMAGE_DOS_HEADER dosHeader, ulong imageBase)
{
reader = exeReader;
header = dosHeader;
Expand Down
Loading

0 comments on commit 2e82efc

Please sign in to comment.