Last active
August 17, 2017 23:18
-
-
Save nguerrera/6864d2a907cb07d869be5a2afed8d764 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void OpenEmbeddedResources(string path) | |
{ | |
using (var peStream = File.OpenRead(path)) | |
using (var peReader = new PEReader(peStream)) | |
{ | |
var mdReader = peReader.GetMetadataReader(); | |
foreach (var resourceHandle in mdReader.ManifestResources) | |
{ | |
var resource = mdReader.GetManifestResource(resourceHandle); | |
if (!resource.Implementation.IsNil) | |
{ | |
continue; // resource is not embedded. | |
} | |
using (var resourceStream = peReader.GetEmbeddedResourceStream(resource)) | |
{ | |
// profit! | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// Get the bytes in an embedded resource as a Stream. | |
/// WARNING: It is incorrect to read from this stream after the PEReader has been disposed. | |
/// </summary> | |
static unsafe Stream GetEmbeddedResourceStream(this PEReader peReader, ManifestResource resource) | |
{ | |
if (!resource.Implementation.IsNil) | |
{ | |
throw new ArgumentException("Resource is not embedded in the PE file.", "resource"); | |
} | |
checked // arithmetic overflow here could cause AV | |
{ | |
// Locate start and end of PE image in unmanaged memory. | |
var block = peReader.GetEntireImage(); | |
Debug.Assert(block.Pointer != null && block.Length > 0); | |
byte* peImageStart = block.Pointer; | |
byte* peImageEnd = peImageStart + block.Length; | |
// Locate offset to resources within PE image. | |
int offsetToResources; | |
if (!peReader.PEHeaders.TryGetDirectoryOffset(peReader.PEHeaders.CorHeader.ResourcesDirectory, out offsetToResources)) | |
{ | |
throw new InvalidDataException("Failed to get offset to resources in PE file."); | |
} | |
Debug.Assert(offsetToResources > 0); | |
byte* resourceStart = peImageStart + offsetToResources + resource.Offset; | |
// Get the length of the the resource from the first 4 bytes. | |
if (resourceStart >= peImageEnd - sizeof(int)) | |
{ | |
throw new InvalidDataException("resource offset out of bounds."); | |
} | |
int resourceLength = new BlobReader(resourceStart, sizeof(int)).ReadInt32(); | |
resourceStart += sizeof(int); | |
if (resourceLength < 0 || resourceStart >= peImageEnd - resourceLength) | |
{ | |
throw new InvalidDataException("resource offset or length out of bounds."); | |
} | |
return new UnmanagedMemoryStream(resourceStart, resourceLength); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment