From f9fcd8749b6153ec8be551709953bb6931b46dd4 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 15 Mar 2022 10:50:40 -0700 Subject: [PATCH] Add arbitrary reads to NE --- .../Microsoft/NE/NewExecutable.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs b/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs index 13a0c12f..0e2e825c 100644 --- a/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs +++ b/BurnOutSharp/ExecutableType/Microsoft/NE/NewExecutable.cs @@ -2,6 +2,7 @@ using System; using System.IO; using BurnOutSharp.ExecutableType.Microsoft.MZ.Headers; using BurnOutSharp.ExecutableType.Microsoft.NE.Headers; +using BurnOutSharp.Tools; namespace BurnOutSharp.ExecutableType.Microsoft.NE { @@ -152,5 +153,73 @@ namespace BurnOutSharp.ExecutableType.Microsoft.NE } #endregion + + #region Helpers + + /// + /// Read an arbitrary range from the source + /// + /// The start of where to read data from, -1 means start of source + /// How many bytes to read, -1 means read until end + /// + public byte[] ReadArbitraryRange(int rangeStart = -1, int length = -1) + { + // If we have a source stream, use that + if (this.SourceStream != null) + return ReadArbitraryRangeFromSourceStream(rangeStart, length); + + // If we have a source array, use that + if (this.SourceArray != null) + return ReadArbitraryRangeFromSourceArray(rangeStart, length); + + // Otherwise, return null + return null; + } + + /// + /// Read an arbitrary range from the stream source, if possible + /// + /// The start of where to read data from, -1 means start of source + /// How many bytes to read, -1 means read until end + /// + private byte[] ReadArbitraryRangeFromSourceStream(int rangeStart, int length) + { + lock (this.SourceStream) + { + int startingIndex = (int)Math.Max(rangeStart, 0); + int readLength = (int)Math.Min(length == -1 ? length = Int32.MaxValue : length, this.SourceStream.Length); + + long originalPosition = this.SourceStream.Position; + this.SourceStream.Seek(startingIndex, SeekOrigin.Begin); + byte[] sectionData = this.SourceStream.ReadBytes(readLength); + this.SourceStream.Seek(originalPosition, SeekOrigin.Begin); + return sectionData; + } + } + + /// + /// Read an arbitrary range from the array source, if possible + /// + /// The start of where to read data from, -1 means start of source + /// How many bytes to read, -1 means read until end + /// + private byte[] ReadArbitraryRangeFromSourceArray(int rangeStart, int length) + { + int startingIndex = (int)Math.Max(rangeStart, 0); + int readLength = (int)Math.Min(length == -1 ? length = Int32.MaxValue : length, this.SourceArray.Length); + + try + { + return this.SourceArray.ReadBytes(ref startingIndex, readLength); + } + catch + { + // Just absorb errors for now + // TODO: Investigate why and when this would be hit + return null; + } + } + + #endregion } } \ No newline at end of file