Skip to content

Commit

Permalink
Started work on resources.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lloyd Kinsella committed Aug 8, 2018
1 parent 28d5961 commit d3f9e4a
Show file tree
Hide file tree
Showing 27 changed files with 526 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Src/Workshell.PE/Content/CLR/CLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Workshell.PE.Content
{
public sealed class CLR : DataContent
{
private CLR(PortableExecutableImage image, DataDirectory directory, Location location, CLRHeader header, CLRMetaData metaData) : base(image, directory, location)
private CLR(PortableExecutableImage image, DataDirectory dataDirectory, Location location, CLRHeader header, CLRMetaData metaData) : base(image, dataDirectory, location)
{
Header = header;
MetaData = metaData;
Expand Down
2 changes: 2 additions & 0 deletions Src/Workshell.PE/DataDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public async Task<DataContent> GetContentAsync()
return await DelayedImportDirectory.GetAsync(_image).ConfigureAwait(false);
case DataDirectoryType.ExceptionTable:
return await ExceptionTable.GetAsync(_image).ConfigureAwait(false);
case DataDirectoryType.ResourceTable:
return await ResourceDirectory.GetAsync(_image).ConfigureAwait(false);
default:
{
var calc = _image.GetCalculator();
Expand Down
11 changes: 2 additions & 9 deletions src/Workshell.PE.Testbed/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@ static async Task RunAsync(string[] args)
{
//var image = await PortableExecutableImage.FromFileAsync(@"C:\Users\lkinsella\Downloads\IISCrypto.exe");
var image = await PortableExecutableImage.FromFileAsync(@"C:\Windows\System32\shell32.dll");
var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.DelayImportDescriptor];
var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.ResourceTable];
var content = await dataDirectory.GetContentAsync().ConfigureAwait(false);

var table = await ExceptionTable.GetAsync(image);
var entries = table.Cast<ExceptionTableEntry64>().ToArray();
var entry = entries[41];
//var entry = entries[6506];
var info = await entry.GetUnwindInfoAsync();

//var table = await ImportHintNameTable.GetAsync(image).ConfigureAwait(false);
//var entries = table.ToArray();

}
}
}
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Certificate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum CertificateType : ushort

public sealed class Certificate : DataContent
{
private Certificate(PortableExecutableImage image, DataDirectory directory, Location location, WIN_CERTIFICATE cert) : base(image, directory, location)
private Certificate(PortableExecutableImage image, DataDirectory dataDirectory, Location location, WIN_CERTIFICATE cert) : base(image, dataDirectory, location)
{
Length = cert.dwLength;
Revision = cert.wRevision;
Expand Down
6 changes: 3 additions & 3 deletions src/Workshell.PE/Content/DataContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Workshell.PE.Content
{
public class DataContent : ISupportsLocation, ISupportsBytes
{
public DataContent(PortableExecutableImage image, DataDirectory directory, Location location)
public DataContent(PortableExecutableImage image, DataDirectory dataDirectory, Location location)
{
Directory = directory;
DataDirectory = dataDirectory;
Location = location;
Image = image;
}
Expand All @@ -34,7 +34,7 @@ public async Task<byte[]> GetBytesAsync()

#region Properties

public DataDirectory Directory { get; }
public DataDirectory DataDirectory { get; }
public Location Location { get; }
protected PortableExecutableImage Image { get; }

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Debug/DebugDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public sealed class DebugDirectory : DataContent, IEnumerable<DebugDirectoryEntr
{
private readonly DebugDirectoryEntry[] _entries;

private DebugDirectory(PortableExecutableImage image, DataDirectory directory, Location location, DebugDirectoryEntry[] entries) : base(image, directory, location)
private DebugDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, DebugDirectoryEntry[] entries) : base(image, dataDirectory, location)
{
_entries = entries;

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Exceptions/ExceptionTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public abstract class ExceptionTable : DataContent, IEnumerable<ExceptionTableEn
{
private readonly ExceptionTableEntry[] _entries;

protected internal ExceptionTable(PortableExecutableImage image, DataDirectory directory, Location location, ExceptionTableEntry[] entries) : base(image, directory, location)
protected internal ExceptionTable(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ExceptionTableEntry[] entries) : base(image, dataDirectory, location)
{
_entries = entries;

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Exceptions/ExceptionTable32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Workshell.PE.Content
{
public sealed class ExceptionTable32 : ExceptionTable
{
private ExceptionTable32(PortableExecutableImage image, DataDirectory directory, Location location, ExceptionTableEntry[] entries) : base(image, directory, location, entries)
private ExceptionTable32(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ExceptionTableEntry[] entries) : base(image, dataDirectory, location, entries)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Exceptions/ExceptionTable64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Workshell.PE.Content
{
public sealed class ExceptionTable64 : ExceptionTable
{
private ExceptionTable64(PortableExecutableImage image, DataDirectory directory, Location location, ExceptionTableEntry[] entries) : base(image, directory, location, entries)
private ExceptionTable64(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ExceptionTableEntry[] entries) : base(image, dataDirectory, location, entries)
{
}

Expand Down
2 changes: 1 addition & 1 deletion 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.Content
{
public abstract class ExportTable : DataContent
{
protected ExportTable(PortableExecutableImage image, DataDirectory directory, Location location) : base(image, directory, location)
protected ExportTable(PortableExecutableImage image, DataDirectory dataDirectory, Location location) : base(image, dataDirectory, location)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Workshell.PE.Content
{
public sealed class DelayedImportAddressTables: ImportAddressTablesBase<DelayedImportAddressTable, DelayedImportAddressTableEntry>
{
internal DelayedImportAddressTables(PortableExecutableImage image, DataDirectory directory, Location location, Tuple<uint, ulong[], ImportDirectoryEntryBase>[] tables) : base(image, directory, location, tables, false)
internal DelayedImportAddressTables(PortableExecutableImage image, DataDirectory dataDirectory, Location location, Tuple<uint, ulong[], ImportDirectoryEntryBase>[] tables) : base(image, dataDirectory, location, tables, false)
{
}

Expand Down Expand Up @@ -81,7 +81,7 @@ private static async Task<DelayedImportAddressTables> GetTableAsync(PortableExec

var section = calc.RVAToSection(rva);
var location = new Location(fileOffset, rva, va, fileSize, fileSize, section);
var result = new DelayedImportAddressTables(image, directory.Directory, location, tables.ToArray());
var result = new DelayedImportAddressTables(image, directory.DataDirectory, location, tables.ToArray());

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Imports/DelayedImportDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Workshell.PE.Content
{
public sealed class DelayedImportDirectory : ImportDirectoryBase<DelayedImportDirectoryEntry>
{
private DelayedImportDirectory(PortableExecutableImage image, DataDirectory directory, Location location, DelayedImportDirectoryEntry[] entries) : base(image, directory, location, entries)
private DelayedImportDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, DelayedImportDirectoryEntry[] entries) : base(image, dataDirectory, location, entries)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Workshell.PE.Content
{
public sealed class DelayedImportHintNameTable : ImportHintNameTableBase<DelayedImportHintNameEntry>
{
internal DelayedImportHintNameTable(PortableExecutableImage image, DataDirectory directory, Location location, Tuple<ulong, uint, ushort, string, bool>[] entries) : base(image, directory, location, entries, true)
internal DelayedImportHintNameTable(PortableExecutableImage image, DataDirectory dataDirectory, Location location, Tuple<ulong, uint, ushort, string, bool>[] entries) : base(image, dataDirectory, location, entries, true)
{
}

Expand Down Expand Up @@ -93,7 +93,7 @@ public static async Task<DelayedImportHintNameTable> GetAsync(PortableExecutable
location = new Location(0, 0, 0, 0, 0, null);
}

var result = new DelayedImportHintNameTable(image, directory.Directory, location, entries.Values.ToArray());
var result = new DelayedImportHintNameTable(image, directory.DataDirectory, location, entries.Values.ToArray());

return result;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Workshell.PE/Content/Imports/ImportAddressTables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Workshell.PE.Content
{
public sealed class ImportAddressTables: ImportAddressTablesBase<ImportAddressTable, ImportAddressTableEntry>
{
internal ImportAddressTables(PortableExecutableImage image, DataDirectory directory, Location location, Tuple<uint, ulong[], ImportDirectoryEntryBase>[] tables) : base(image, directory, location, tables, false)
internal ImportAddressTables(PortableExecutableImage image, DataDirectory dataDirectory, Location location, Tuple<uint, ulong[], ImportDirectoryEntryBase>[] tables) : base(image, dataDirectory, location, tables, false)
{
}

Expand Down Expand Up @@ -81,7 +81,7 @@ private static async Task<ImportAddressTables> GetTableAsync(PortableExecutableI

var section = calc.RVAToSection(rva);
var location = new Location(fileOffset, rva, va, fileSize, fileSize, section);
var result = new ImportAddressTables(image, directory.Directory, location, tables.ToArray());
var result = new ImportAddressTables(image, directory.DataDirectory, location, tables.ToArray());

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public abstract class ImportAddressTablesBase<TTable, TTableEntry> : DataContent
{
private readonly TTable[] _tables;

protected internal ImportAddressTablesBase(PortableExecutableImage image, DataDirectory directory, Location location, Tuple<uint, ulong[], ImportDirectoryEntryBase>[] tables, bool isDelayed) : base(image, directory, location)
protected internal ImportAddressTablesBase(PortableExecutableImage image, DataDirectory dataDirectory, Location location, Tuple<uint, ulong[], ImportDirectoryEntryBase>[] tables, bool isDelayed) : base(image, dataDirectory, location)
{
_tables = new TTable[tables.Length];

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Imports/ImportDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Workshell.PE.Content
{
public sealed class ImportDirectory : ImportDirectoryBase<ImportDirectoryEntry>
{
private ImportDirectory(PortableExecutableImage image, DataDirectory directory, Location location, ImportDirectoryEntry[] entries) : base(image, directory, location, entries)
private ImportDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ImportDirectoryEntry[] entries) : base(image, dataDirectory, location, entries)
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Imports/ImportDirectoryBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public abstract class ImportDirectoryBase<T> : DataContent, IEnumerable<T> where
{
private readonly T[] _entries;

protected internal ImportDirectoryBase(PortableExecutableImage image, DataDirectory directory, Location location, T[] entries) : base(image, directory, location)
protected internal ImportDirectoryBase(PortableExecutableImage image, DataDirectory dataDirectory, Location location, T[] entries) : base(image, dataDirectory, location)
{
_entries = entries;

Expand Down
4 changes: 2 additions & 2 deletions src/Workshell.PE/Content/Imports/ImportHintNameTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Workshell.PE.Content
{
public sealed class ImportHintNameTable : ImportHintNameTableBase<ImportHintNameEntry>
{
internal ImportHintNameTable(PortableExecutableImage image, DataDirectory directory, Location location, Tuple<ulong, uint, ushort, string, bool>[] entries) : base(image, directory, location, entries, false)
internal ImportHintNameTable(PortableExecutableImage image, DataDirectory dataDirectory, Location location, Tuple<ulong, uint, ushort, string, bool>[] entries) : base(image, dataDirectory, location, entries, false)
{
}

Expand Down Expand Up @@ -93,7 +93,7 @@ public static async Task<ImportHintNameTable> GetAsync(PortableExecutableImage i
location = new Location(0, 0, 0, 0, 0, null);
}

var result = new ImportHintNameTable(image, directory.Directory, location, entries.Values.ToArray());
var result = new ImportHintNameTable(image, directory.DataDirectory, location, entries.Values.ToArray());

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public abstract class ImportHintNameTableBase<TEntry> : DataContent, IEnumerable
{
private readonly TEntry[] _entries;

protected internal ImportHintNameTableBase(PortableExecutableImage image, DataDirectory directory, Location location, Tuple<ulong,uint,ushort,string,bool>[] entries, bool isDelayed) : base(image, directory, location)
protected internal ImportHintNameTableBase(PortableExecutableImage image, DataDirectory dataDirectory, Location location, Tuple<ulong,uint,ushort,string,bool>[] entries, bool isDelayed) : base(image, dataDirectory, location)
{
_entries = BuildTable(entries);

Expand Down
2 changes: 1 addition & 1 deletion src/Workshell.PE/Content/Relocation/RelocationTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public sealed class RelocationTable : DataContent, IEnumerable<RelocationBlock>
{
private readonly RelocationBlock[] _blocks;

private RelocationTable(PortableExecutableImage image, DataDirectory directory, Location location, RelocationBlock[] blocks) : base(image, directory, location)
private RelocationTable(PortableExecutableImage image, DataDirectory dataDirectory, Location location, RelocationBlock[] blocks) : base(image, dataDirectory, location)
{
_blocks = blocks;

Expand Down
38 changes: 38 additions & 0 deletions src/Workshell.PE/Content/Resources/ResourceData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace Workshell.PE.Content
{
public sealed class ResourceData : DataContent
{
internal ResourceData(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ResourceDataEntry entry) : base(image, dataDirectory, location)
{
Entry = entry;
}

#region Methods

public void CopyTo(Stream stream)
{
CopyToAsync(stream).GetAwaiter().GetResult();
}

public async Task CopyToAsync(Stream stream)
{
var buffer = await GetBytesAsync().ConfigureAwait(false);

await stream.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
}

#endregion

#region Properties

public ResourceDataEntry Entry { get; }

#endregion
}
}
85 changes: 85 additions & 0 deletions src/Workshell.PE/Content/Resources/ResourceDataEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

using Workshell.PE.Annotations;
using Workshell.PE.Extensions;
using Workshell.PE.Native;

namespace Workshell.PE.Content
{
public sealed class ResourceDataEntry : DataContent
{
private ResourceData _data;

internal ResourceDataEntry(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ResourceDirectoryEntry directoryEntry) : base(image, dataDirectory, location)
{
_data = null;

DirectoryEntry = directoryEntry;
}

#region Methods

public ResourceData GetData()
{
if (_data == null)
{
var calc = Image.GetCalculator();
var rva = OffsetToData;
var va = Image.NTHeaders.OptionalHeader.ImageBase + rva;
var offset = calc.RVAToOffset(rva);
var size = Size;
var section = calc.RVAToSection(rva);
var location = new Location(offset, rva, va, size, size, section);

_data = new ResourceData(Image, DataDirectory, location, this);
}

return _data;
}

internal async Task LoadAsync()
{
var stream = Image.GetStream();

stream.Seek(Location.FileOffset.ToInt64(), SeekOrigin.Begin);

try
{
var entry = await stream.ReadStructAsync<IMAGE_RESOURCE_DATA_ENTRY>().ConfigureAwait(false);

OffsetToData = entry.OffsetToData;
Size = entry.Size;
CodePage = entry.CodePage;
Reserved = entry.Reserved;
}
catch (Exception ex)
{
throw new PortableExecutableImageException(Image, "Could not read resource data entry from stream.", ex);
}
}

#endregion

#region Properties

public ResourceDirectoryEntry DirectoryEntry { get; }

[FieldAnnotation("Offset to Data")]
public uint OffsetToData { get; private set; }

[FieldAnnotation("Size")]
public uint Size { get; private set; }

[FieldAnnotation("Code Page")]
public uint CodePage { get; private set; }

[FieldAnnotation("Reserved")]
public uint Reserved { get; private set; }

#endregion
}
}
Loading

0 comments on commit d3f9e4a

Please sign in to comment.