Skip to content

Commit

Permalink
Added certificate table support and a flag indicating if the image is…
Browse files Browse the repository at this point in the history
… signed or not.
  • Loading branch information
lkinsella committed Feb 18, 2016
1 parent fc7f69f commit 5cc50db
Show file tree
Hide file tree
Showing 7 changed files with 220 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 @@ -43,7 +43,7 @@ static void Main(string[] args)
if (content == null)
continue;

if (content.DataDirectory.DirectoryType == DataDirectoryType.ResourceTable)
if (content.DataDirectory.DirectoryType == DataDirectoryType.CertificateTable)
{

}
Expand Down
111 changes: 111 additions & 0 deletions Src/Workshell.PE/Content/Certificates/Certificate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

using Workshell.PE.Native;

namespace Workshell.PE
{

public enum CertificateType : ushort
{
X509Certificate = 0x0001,
PKCSSignedData = 0x0002,
Reserved = 0x0003,
PKCS1ModuleSign = 0x0009
}

public sealed class Certificate : ISupportsLocation, ISupportsBytes
{

private CertificateTableContent content;
private Location location;
private WIN_CERTIFICATE cert;

internal Certificate(CertificateTableContent certContent, Location certLocation, WIN_CERTIFICATE winCert)
{
content = certContent;
location = certLocation;
cert = winCert;
}

#region Methods

public byte[] GetBytes()
{
Stream stream = content.DataDirectory.Directories.Reader.GetStream();
byte[] buffer = Utils.ReadBytes(stream,location);

return buffer;
}

public CertificateType GetCertificateType()
{
return (CertificateType)cert.wCertificateType;
}

public byte[] GetCertificateData()
{
Stream stream = content.DataDirectory.Directories.Reader.GetStream();
ulong offset = location.FileOffset + Convert.ToUInt32(Utils.SizeOf<WIN_CERTIFICATE>());
byte[] buffer = new byte[cert.dwLength];

stream.Seek(Convert.ToInt64(offset),SeekOrigin.Begin);
stream.Read(buffer,0,buffer.Length);

return buffer;
}

#endregion

#region Properties

public CertificateTableContent Content
{
get
{
return content;
}
}

public Location Location
{
get
{
return location;
}
}

public uint Length
{
get
{
return cert.dwLength;
}
}

public ushort Revision
{
get
{
return cert.wRevision;
}
}

public ushort CertificateType
{
get
{
return cert.wCertificateType;
}
}

#endregion

}

}
56 changes: 56 additions & 0 deletions Src/Workshell.PE/Content/Certificates/CertificateTableContent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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 sealed class CertificateTableContent : DataDirectoryContent
{

private Certificate cert;

internal CertificateTableContent(DataDirectory dataDirectory, ulong imageBase) : base(dataDirectory, imageBase)
{
LocationCalculator calc = dataDirectory.Directories.Reader.GetCalculator();
Stream stream = dataDirectory.Directories.Reader.GetStream();

Load(calc, stream, imageBase);
}

#region Methods

private void Load(LocationCalculator calc, Stream stream, ulong imageBase)
{
ulong offset = DataDirectory.VirtualAddress;
Location location = new Location(offset, DataDirectory.VirtualAddress, imageBase + offset, DataDirectory.Size, DataDirectory.Size);

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

WIN_CERTIFICATE win_cert = Utils.Read<WIN_CERTIFICATE>(stream);

cert = new Certificate(this,location,win_cert);
}

#endregion

#region Properties

public Certificate Certificate
{
get
{
return cert;
}
}

#endregion

}

}
3 changes: 3 additions & 0 deletions Src/Workshell.PE/DataDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ public DataDirectoryContent GetContent()
case DataDirectoryType.ResourceTable:
dir_content = new ResourceTableContent(this,image_base);
break;
case DataDirectoryType.CertificateTable:
dir_content = new CertificateTableContent(this,image_base);
break;
default:
dir_content = null;
break;
Expand Down
26 changes: 25 additions & 1 deletion Src/Workshell.PE/ImageReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class PreloadedInformation
public bool Is32Bit;
public bool Is64Bit;
public bool IsCLR;
public bool IsSigned;

}

Expand All @@ -46,6 +47,7 @@ class PreloadedInformation
private bool _is_32bit;
private bool _is_64bit;
private bool _is_clr;
private bool _is_signed;

private ImageReader(Stream sourceStream, bool ownStream)
{
Expand All @@ -63,6 +65,7 @@ private ImageReader(Stream sourceStream, bool ownStream)
_is_32bit = false;
_is_64bit = false;
_is_clr = false;
_is_signed = false;

Load();
}
Expand Down Expand Up @@ -268,6 +271,17 @@ private static PreloadedInformation TryPreload(Stream stream, out string errorMe
is_clr = true;
}

bool is_signed = false;
int cert_dir_index = (int)DataDirectoryType.CertificateTable;

if (cert_dir_index < 0 || cert_dir_index > (data_directories.Length - 1))
{
IMAGE_DATA_DIRECTORY cert_dir = data_directories[cert_dir_index];

if (cert_dir.VirtualAddress > 0 && cert_dir.Size > 0)
is_signed = true;
}

PreloadedInformation info = new PreloadedInformation() {
DOSHeader = dos_header,
StubOffset = Convert.ToUInt64(stub_offset),
Expand All @@ -280,7 +294,8 @@ private static PreloadedInformation TryPreload(Stream stream, out string errorMe

Is32Bit = is_32bit,
Is64Bit = is_64bit,
IsCLR = is_clr
IsCLR = is_clr,
IsSigned = is_signed
};

return info;
Expand Down Expand Up @@ -369,6 +384,7 @@ private void Load()
_is_32bit = preload_info.Is32Bit;
_is_64bit = preload_info.Is64Bit;
_is_clr = preload_info.IsCLR;
_is_signed = preload_info.IsSigned;
}

#endregion
Expand Down Expand Up @@ -399,6 +415,14 @@ public bool IsCLR
}
}

public bool IsSigned
{
get
{
return _is_signed;
}
}

public DOSHeader DOSHeader
{
get
Expand Down
21 changes: 21 additions & 0 deletions Src/Workshell.PE/Native/WIN_CERTIFICATE.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Workshell.PE.Native
{

[StructLayout(LayoutKind.Sequential)]
public struct WIN_CERTIFICATE
{

public uint dwLength;
public ushort wRevision;
public ushort wCertificateType;

}

}
3 changes: 3 additions & 0 deletions Src/Workshell.PE/Workshell.PE.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
<Compile Include="Annotations\FieldAnnotation.cs" />
<Compile Include="Annotations\EnumAnnotationAttribute.cs" />
<Compile Include="Annotations\FieldAnnotationAttribute.cs" />
<Compile Include="Content\Certificates\Certificate.cs" />
<Compile Include="Content\Certificates\CertificateTableContent.cs" />
<Compile Include="Content\CLR\CLRContent.cs" />
<Compile Include="Content\CLR\CLRDataDirectory.cs" />
<Compile Include="Content\CLR\CLRHeader.cs" />
Expand Down Expand Up @@ -88,6 +90,7 @@
<Compile Include="MoreLinq\MaxBy.cs" />
<Compile Include="MoreLinq\MinBy.cs" />
<Compile Include="MoreLinq\MoreEnumerable.cs" />
<Compile Include="Native\WIN_CERTIFICATE.cs" />
<Compile Include="Native\IMAGE_RESOURCE_DATA_ENTRY.cs" />
<Compile Include="Native\IMAGE_RESOURCE_DIRECTORY_ENTRY.cs" />
<Compile Include="Native\IMAGE_RESOURCE_DIRECTORY.cs" />
Expand Down

0 comments on commit 5cc50db

Please sign in to comment.