diff --git a/Build/build.bat b/Build/build.bat deleted file mode 100644 index da5fe8d..0000000 --- a/Build/build.bat +++ /dev/null @@ -1,2 +0,0 @@ -..\Tools\nuget pack ..\Src\Workshell.PE\Workshell.PE.csproj -Build -Prop Configuration=Release; -..\Tools\nuget pack ..\Src\Workshell.PE.Resources\Workshell.PE.Resources.csproj -Build -Prop Configuration=Release; \ No newline at end of file diff --git a/Src/Debug Application/App.config b/Src/Debug Application/App.config deleted file mode 100644 index 8e15646..0000000 --- a/Src/Debug Application/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Src/Debug Application/Debug Application.csproj b/Src/Debug Application/Debug Application.csproj deleted file mode 100644 index 47ca090..0000000 --- a/Src/Debug Application/Debug Application.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - - Debug - AnyCPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F} - Exe - Properties - Workshell.PE.Demo - pedebug - v4.5 - 512 - - - AnyCPU - true - full - false - ..\..\Bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - ..\..\Bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - {2b06cbf8-136a-4bec-8624-861992139489} - Workshell.PE.Resources - - - {2e173d25-1c2e-4a7b-8b37-d231324d372d} - Workshell.PE - - - - - \ No newline at end of file diff --git a/Src/Debug Application/Program.cs b/Src/Debug Application/Program.cs deleted file mode 100644 index 56a12f3..0000000 --- a/Src/Debug Application/Program.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE; -using Workshell.PE.Imports; -using Workshell.PE.Resources; -using Workshell.PE.Relocations; - -namespace Workshell.PE.Demo -{ - - class Program - { - - static void Main(string[] args) - { - //string file_name = Environment.GetCommandLineArgs()[0]; - //string file_name = Assembly.GetEntryAssembly().Location; - //string file_name = @"C:\Windows\SysWOW64\kernel32.dll"; - //string file_name = @"C:\Windows\System32\kernel32.dll"; - //string file_name = @"C:\Windows\SysWOW64\shell32.dll"; - //string file_name = @"C:\Windows\System32\shell32.dll"; - //string file_name = @"C:\Windows\System32\user32.dll"; - //string file_name = @"C:\Windows\explorer.exe"; - //string file_name = @"C:\Windows\SysWOW64\xpsservices.dll"; - //string file_name = @"c:\windows\system32\advapi32.dll"; - //string file_name = @"C:\Program Files (x86)\Notepad++\notepad++.exe"; - string file_name = @"C:\Windows\System32\dsparse.dll"; - string error_message; - - if (!ExecutableImage.IsValid(file_name,out error_message)) - { - Console.WriteLine("Invalid executable image: " + error_message); - - return; - } - - MessageTableResource.Register(); - - var image = ExecutableImage.FromFile(file_name); - var delayedImports = DelayImportCollection.Get(image); - - } - - } - -} diff --git a/Src/Debug Application/Properties/AssemblyInfo.cs b/Src/Debug Application/Properties/AssemblyInfo.cs deleted file mode 100644 index f62e741..0000000 --- a/Src/Debug Application/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Demo Application")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Demo Application")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("772dcbca-dca9-42e6-b69e-3b16c8a4b72e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Src/PE Dump/App.config b/Src/PE Dump/App.config deleted file mode 100644 index 74ade9d..0000000 --- a/Src/PE Dump/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Src/PE Dump/Options.cs b/Src/PE Dump/Options.cs deleted file mode 100644 index f4b9d7c..0000000 --- a/Src/PE Dump/Options.cs +++ /dev/null @@ -1,1474 +0,0 @@ -// -// Options.cs -// -// Authors: -// Jonathan Pryor -// Federico Di Gregorio -// Rolf Bjarne Kvinge -// -// Copyright (C) 2008 Novell (http://www.novell.com) -// Copyright (C) 2009 Federico Di Gregorio. -// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -// Compile With: -// gmcs -debug+ -r:System.Core Options.cs -o:NDesk.Options.dll -// gmcs -debug+ -d:LINQ -r:System.Core Options.cs -o:NDesk.Options.dll -// -// The LINQ version just changes the implementation of -// OptionSet.Parse(IEnumerable), and confers no semantic changes. - -// -// A Getopt::Long-inspired option parsing library for C#. -// -// NDesk.Options.OptionSet is built upon a key/value table, where the -// key is a option format string and the value is a delegate that is -// invoked when the format string is matched. -// -// Option format strings: -// Regex-like BNF Grammar: -// name: .+ -// type: [=:] -// sep: ( [^{}]+ | '{' .+ '}' )? -// aliases: ( name type sep ) ( '|' name type sep )* -// -// Each '|'-delimited name is an alias for the associated action. If the -// format string ends in a '=', it has a required value. If the format -// string ends in a ':', it has an optional value. If neither '=' or ':' -// is present, no value is supported. `=' or `:' need only be defined on one -// alias, but if they are provided on more than one they must be consistent. -// -// Each alias portion may also end with a "key/value separator", which is used -// to split option values if the option accepts > 1 value. If not specified, -// it defaults to '=' and ':'. If specified, it can be any character except -// '{' and '}' OR the *string* between '{' and '}'. If no separator should be -// used (i.e. the separate values should be distinct arguments), then "{}" -// should be used as the separator. -// -// Options are extracted either from the current option by looking for -// the option name followed by an '=' or ':', or is taken from the -// following option IFF: -// - The current option does not contain a '=' or a ':' -// - The current option requires a value (i.e. not a Option type of ':') -// -// The `name' used in the option format string does NOT include any leading -// option indicator, such as '-', '--', or '/'. All three of these are -// permitted/required on any named option. -// -// Option bundling is permitted so long as: -// - '-' is used to start the option group -// - all of the bundled options are a single character -// - at most one of the bundled options accepts a value, and the value -// provided starts from the next character to the end of the string. -// -// This allows specifying '-a -b -c' as '-abc', and specifying '-D name=value' -// as '-Dname=value'. -// -// Option processing is disabled by specifying "--". All options after "--" -// are returned by OptionSet.Parse() unchanged and unprocessed. -// -// Unprocessed options are returned from OptionSet.Parse(). -// -// Examples: -// int verbose = 0; -// OptionSet p = new OptionSet () -// .Add ("v", v => ++verbose) -// .Add ("name=|value=", v => Console.WriteLine (v)); -// p.Parse (new string[]{"-v", "--v", "/v", "-name=A", "/name", "B", "extra"}); -// -// The above would parse the argument string array, and would invoke the -// lambda expression three times, setting `verbose' to 3 when complete. -// It would also print out "A" and "B" to standard output. -// The returned array would contain the string "extra". -// -// C# 3.0 collection initializers are supported and encouraged: -// var p = new OptionSet () { -// { "h|?|help", v => ShowHelp () }, -// }; -// -// System.ComponentModel.TypeConverter is also supported, allowing the use of -// custom data types in the callback type; TypeConverter.ConvertFromString() -// is used to convert the value option to an instance of the specified -// type: -// -// var p = new OptionSet () { -// { "foo=", (Foo f) => Console.WriteLine (f.ToString ()) }, -// }; -// -// Random other tidbits: -// - Boolean options (those w/o '=' or ':' in the option format string) -// are explicitly enabled if they are followed with '+', and explicitly -// disabled if they are followed with '-': -// string a = null; -// var p = new OptionSet () { -// { "a", s => a = s }, -// }; -// p.Parse (new string[]{"-a"}); // sets v != null -// p.Parse (new string[]{"-a+"}); // sets v != null -// p.Parse (new string[]{"-a-"}); // sets v == null -// - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Globalization; -using System.IO; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; -using System.Text.RegularExpressions; - -#if LINQ -using System.Linq; -#endif - -#if TEST -using NDesk.Options; -#endif - -#if NDESK_OPTIONS -namespace NDesk.Options -#else -namespace Mono.Options -#endif -{ - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - static class StringCoda - { - - public static IEnumerable WrappedLines(string self, params int[] widths) - { - IEnumerable w = widths; - return WrappedLines(self, w); - } - - public static IEnumerable WrappedLines(string self, IEnumerable widths) - { - if (widths == null) - throw new ArgumentNullException("widths"); - return CreateWrappedLinesIterator(self, widths); - } - - private static IEnumerable CreateWrappedLinesIterator(string self, IEnumerable widths) - { - if (string.IsNullOrEmpty(self)) - { - yield return string.Empty; - yield break; - } - using (IEnumerator ewidths = widths.GetEnumerator()) - { - bool? hw = null; - int width = GetNextWidth(ewidths, int.MaxValue, ref hw); - int start = 0, end; - do - { - end = GetLineEnd(start, width, self); - char c = self[end - 1]; - if (char.IsWhiteSpace(c)) - --end; - bool needContinuation = end != self.Length && !IsEolChar(c); - string continuation = ""; - if (needContinuation) - { - --end; - continuation = "-"; - } - string line = self.Substring(start, end - start) + continuation; - yield return line; - start = end; - if (char.IsWhiteSpace(c)) - ++start; - width = GetNextWidth(ewidths, width, ref hw); - } while (start < self.Length); - } - } - - private static int GetNextWidth(IEnumerator ewidths, int curWidth, ref bool? eValid) - { - if (!eValid.HasValue || (eValid.HasValue && eValid.Value)) - { - curWidth = (eValid = ewidths.MoveNext()).Value ? ewidths.Current : curWidth; - // '.' is any character, - is for a continuation - const string minWidth = ".-"; - if (curWidth < minWidth.Length) - throw new ArgumentOutOfRangeException("widths", - string.Format("Element must be >= {0}, was {1}.", minWidth.Length, curWidth)); - return curWidth; - } - // no more elements, use the last element. - return curWidth; - } - - private static bool IsEolChar(char c) - { - return !char.IsLetterOrDigit(c); - } - - private static int GetLineEnd(int start, int length, string description) - { - int end = System.Math.Min(start + length, description.Length); - int sep = -1; - for (int i = start; i < end; ++i) - { - if (description[i] == '\n') - return i + 1; - if (IsEolChar(description[i])) - sep = i + 1; - } - if (sep == -1 || end == description.Length) - return end; - return sep; - } - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public class OptionValueCollection : IList, IList - { - - List values = new List(); - OptionContext c; - - internal OptionValueCollection(OptionContext c) - { - this.c = c; - } - - #region ICollection - void ICollection.CopyTo(Array array, int index) { (values as ICollection).CopyTo(array, index); } - bool ICollection.IsSynchronized { get { return (values as ICollection).IsSynchronized; } } - object ICollection.SyncRoot { get { return (values as ICollection).SyncRoot; } } - #endregion - - #region ICollection - public void Add(string item) { values.Add(item); } - public void Clear() { values.Clear(); } - public bool Contains(string item) { return values.Contains(item); } - public void CopyTo(string[] array, int arrayIndex) { values.CopyTo(array, arrayIndex); } - public bool Remove(string item) { return values.Remove(item); } - public int Count { get { return values.Count; } } - public bool IsReadOnly { get { return false; } } - #endregion - - #region IEnumerable - IEnumerator IEnumerable.GetEnumerator() { return values.GetEnumerator(); } - #endregion - - #region IEnumerable - public IEnumerator GetEnumerator() { return values.GetEnumerator(); } - #endregion - - #region IList - int IList.Add(object value) { return (values as IList).Add(value); } - bool IList.Contains(object value) { return (values as IList).Contains(value); } - int IList.IndexOf(object value) { return (values as IList).IndexOf(value); } - void IList.Insert(int index, object value) { (values as IList).Insert(index, value); } - void IList.Remove(object value) { (values as IList).Remove(value); } - void IList.RemoveAt(int index) { (values as IList).RemoveAt(index); } - bool IList.IsFixedSize { get { return false; } } - object IList.this[int index] { get { return this[index]; } set { (values as IList)[index] = value; } } - #endregion - - #region IList - public int IndexOf(string item) { return values.IndexOf(item); } - public void Insert(int index, string item) { values.Insert(index, item); } - public void RemoveAt(int index) { values.RemoveAt(index); } - - private void AssertValid(int index) - { - if (c.Option == null) - throw new InvalidOperationException("OptionContext.Option is null."); - if (index >= c.Option.MaxValueCount) - throw new ArgumentOutOfRangeException("index"); - if (c.Option.OptionValueType == OptionValueType.Required && - index >= values.Count) - throw new OptionException(string.Format( - c.OptionSet.MessageLocalizer("Missing required value for option '{0}'."), c.OptionName), - c.OptionName); - } - - public string this[int index] - { - get - { - AssertValid(index); - return index >= values.Count ? null : values[index]; - } - set - { - values[index] = value; - } - } - #endregion - - public List ToList() - { - return new List(values); - } - - public string[] ToArray() - { - return values.ToArray(); - } - - public override string ToString() - { - return string.Join(", ", values.ToArray()); - } - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public class OptionContext - { - private Option option; - private string name; - private int index; - private OptionSet set; - private OptionValueCollection c; - - public OptionContext(OptionSet set) - { - this.set = set; - this.c = new OptionValueCollection(this); - } - - public Option Option - { - get { return option; } - set { option = value; } - } - - public string OptionName - { - get { return name; } - set { name = value; } - } - - public int OptionIndex - { - get { return index; } - set { index = value; } - } - - public OptionSet OptionSet - { - get { return set; } - } - - public OptionValueCollection OptionValues - { - get { return c; } - } - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public enum OptionValueType - { - None, - Optional, - Required, - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public abstract class Option - { - string prototype, description; - string[] names; - OptionValueType type; - int count; - string[] separators; - bool hidden; - - protected Option(string prototype, string description) - : this(prototype, description, 1, false) - { - } - - protected Option(string prototype, string description, int maxValueCount) - : this(prototype, description, maxValueCount, false) - { - } - - protected Option(string prototype, string description, int maxValueCount, bool hidden) - { - if (prototype == null) - throw new ArgumentNullException("prototype"); - if (prototype.Length == 0) - throw new ArgumentException("Cannot be the empty string.", "prototype"); - if (maxValueCount < 0) - throw new ArgumentOutOfRangeException("maxValueCount"); - - this.prototype = prototype; - this.description = description; - this.count = maxValueCount; - this.names = (this is OptionSet.Category) - // append GetHashCode() so that "duplicate" categories have distinct - // names, e.g. adding multiple "" categories should be valid. - ? new[] { prototype + this.GetHashCode() } - : prototype.Split('|'); - - if (this is OptionSet.Category) - return; - - this.type = ParsePrototype(); - this.hidden = hidden; - - if (this.count == 0 && type != OptionValueType.None) - throw new ArgumentException( - "Cannot provide maxValueCount of 0 for OptionValueType.Required or " + - "OptionValueType.Optional.", - "maxValueCount"); - if (this.type == OptionValueType.None && maxValueCount > 1) - throw new ArgumentException( - string.Format("Cannot provide maxValueCount of {0} for OptionValueType.None.", maxValueCount), - "maxValueCount"); - if (Array.IndexOf(names, "<>") >= 0 && - ((names.Length == 1 && this.type != OptionValueType.None) || - (names.Length > 1 && this.MaxValueCount > 1))) - throw new ArgumentException( - "The default option handler '<>' cannot require values.", - "prototype"); - } - - public string Prototype { get { return prototype; } } - public string Description { get { return description; } } - public OptionValueType OptionValueType { get { return type; } } - public int MaxValueCount { get { return count; } } - public bool Hidden { get { return hidden; } } - - public string[] GetNames() - { - return (string[])names.Clone(); - } - - public string[] GetValueSeparators() - { - if (separators == null) - return new string[0]; - return (string[])separators.Clone(); - } - - protected static T Parse(string value, OptionContext c) - { - Type tt = typeof(T); - bool nullable = tt.IsValueType && tt.IsGenericType && - !tt.IsGenericTypeDefinition && - tt.GetGenericTypeDefinition() == typeof(Nullable<>); - Type targetType = nullable ? tt.GetGenericArguments()[0] : typeof(T); - TypeConverter conv = TypeDescriptor.GetConverter(targetType); - T t = default(T); - try - { - if (value != null) - t = (T)conv.ConvertFromString(value); - } - catch (Exception e) - { - throw new OptionException( - string.Format( - c.OptionSet.MessageLocalizer("Could not convert string `{0}' to type {1} for option `{2}'."), - value, targetType.Name, c.OptionName), - c.OptionName, e); - } - return t; - } - - internal string[] Names { get { return names; } } - internal string[] ValueSeparators { get { return separators; } } - - static readonly char[] NameTerminator = new char[] { '=', ':' }; - - private OptionValueType ParsePrototype() - { - char type = '\0'; - List seps = new List(); - for (int i = 0; i < names.Length; ++i) - { - string name = names[i]; - if (name.Length == 0) - throw new ArgumentException("Empty option names are not supported.", "prototype"); - - int end = name.IndexOfAny(NameTerminator); - if (end == -1) - continue; - names[i] = name.Substring(0, end); - if (type == '\0' || type == name[end]) - type = name[end]; - else - throw new ArgumentException( - string.Format("Conflicting option types: '{0}' vs. '{1}'.", type, name[end]), - "prototype"); - AddSeparators(name, end, seps); - } - - if (type == '\0') - return OptionValueType.None; - - if (count <= 1 && seps.Count != 0) - throw new ArgumentException( - string.Format("Cannot provide key/value separators for Options taking {0} value(s).", count), - "prototype"); - if (count > 1) - { - if (seps.Count == 0) - this.separators = new string[] { ":", "=" }; - else if (seps.Count == 1 && seps[0].Length == 0) - this.separators = null; - else - this.separators = seps.ToArray(); - } - - return type == '=' ? OptionValueType.Required : OptionValueType.Optional; - } - - private static void AddSeparators(string name, int end, ICollection seps) - { - int start = -1; - for (int i = end + 1; i < name.Length; ++i) - { - switch (name[i]) - { - case '{': - if (start != -1) - throw new ArgumentException( - string.Format("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - start = i + 1; - break; - case '}': - if (start == -1) - throw new ArgumentException( - string.Format("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - seps.Add(name.Substring(start, i - start)); - start = -1; - break; - default: - if (start == -1) - seps.Add(name[i].ToString()); - break; - } - } - if (start != -1) - throw new ArgumentException( - string.Format("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - } - - public void Invoke(OptionContext c) - { - OnParseComplete(c); - c.OptionName = null; - c.Option = null; - c.OptionValues.Clear(); - } - - protected abstract void OnParseComplete(OptionContext c); - - public override string ToString() - { - return Prototype; - } - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public abstract class ArgumentSource - { - - protected ArgumentSource() - { - } - - public abstract string[] GetNames(); - public abstract string Description { get; } - public abstract bool GetArguments(string value, out IEnumerable replacement); - - public static IEnumerable GetArgumentsFromFile(string file) - { - return GetArguments(File.OpenText(file), true); - } - - public static IEnumerable GetArguments(TextReader reader) - { - return GetArguments(reader, false); - } - - // Cribbed from mcs/driver.cs:LoadArgs(string) - static IEnumerable GetArguments(TextReader reader, bool close) - { - try - { - StringBuilder arg = new StringBuilder(); - - string line; - while ((line = reader.ReadLine()) != null) - { - int t = line.Length; - - for (int i = 0; i < t; i++) - { - char c = line[i]; - - if (c == '"' || c == '\'') - { - char end = c; - - for (i++; i < t; i++) - { - c = line[i]; - - if (c == end) - break; - arg.Append(c); - } - } - else if (c == ' ') - { - if (arg.Length > 0) - { - yield return arg.ToString(); - arg.Length = 0; - } - } - else - arg.Append(c); - } - if (arg.Length > 0) - { - yield return arg.ToString(); - arg.Length = 0; - } - } - } - finally - { - if (close) - reader.Close(); - } - } - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public class ResponseFileSource : ArgumentSource - { - - public override string[] GetNames() - { - return new string[] { "@file" }; - } - - public override string Description - { - get { return "Read response file for more options."; } - } - - public override bool GetArguments(string value, out IEnumerable replacement) - { - if (string.IsNullOrEmpty(value) || !value.StartsWith("@")) - { - replacement = null; - return false; - } - replacement = ArgumentSource.GetArgumentsFromFile(value.Substring(1)); - return true; - } - } - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - [Serializable] - public class OptionException : Exception - { - private string option; - - public OptionException() - { - } - - public OptionException(string message, string optionName) - : base(message) - { - this.option = optionName; - } - - public OptionException(string message, string optionName, Exception innerException) - : base(message, innerException) - { - this.option = optionName; - } - - protected OptionException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - this.option = info.GetString("OptionName"); - } - - public string OptionName - { - get { return this.option; } - } - - [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("OptionName", option); - } - } - - public delegate void OptionAction(TKey key, TValue value); - - [System.Reflection.Obfuscation(ApplyToMembers = true, StripAfterObfuscation = true)] - public class OptionSet : KeyedCollection - { - public OptionSet() - : this(delegate (string f) { return f; }) - { - } - - public OptionSet(Converter localizer) - { - this.localizer = localizer; - this.roSources = new ReadOnlyCollection(sources); - } - - Converter localizer; - - public Converter MessageLocalizer - { - get { return localizer; } - } - - List sources = new List(); - ReadOnlyCollection roSources; - - public ReadOnlyCollection ArgumentSources - { - get { return roSources; } - } - - - protected override string GetKeyForItem(Option item) - { - if (item == null) - throw new ArgumentNullException("option"); - if (item.Names != null && item.Names.Length > 0) - return item.Names[0]; - // This should never happen, as it's invalid for Option to be - // constructed w/o any names. - throw new InvalidOperationException("Option has no names!"); - } - - [Obsolete("Use KeyedCollection.this[string]")] - protected Option GetOptionForName(string option) - { - if (option == null) - throw new ArgumentNullException("option"); - try - { - return base[option]; - } - catch (KeyNotFoundException) - { - return null; - } - } - - protected override void InsertItem(int index, Option item) - { - base.InsertItem(index, item); - AddImpl(item); - } - - protected override void RemoveItem(int index) - { - Option p = Items[index]; - base.RemoveItem(index); - // KeyedCollection.RemoveItem() handles the 0th item - for (int i = 1; i < p.Names.Length; ++i) - { - Dictionary.Remove(p.Names[i]); - } - } - - protected override void SetItem(int index, Option item) - { - base.SetItem(index, item); - AddImpl(item); - } - - private void AddImpl(Option option) - { - if (option == null) - throw new ArgumentNullException("option"); - List added = new List(option.Names.Length); - try - { - // KeyedCollection.InsertItem/SetItem handle the 0th name. - for (int i = 1; i < option.Names.Length; ++i) - { - Dictionary.Add(option.Names[i], option); - added.Add(option.Names[i]); - } - } - catch (Exception) - { - foreach (string name in added) - Dictionary.Remove(name); - throw; - } - } - - public OptionSet Add(string header) - { - if (header == null) - throw new ArgumentNullException("header"); - Add(new Category(header)); - return this; - } - - internal sealed class Category : Option - { - - // Prototype starts with '=' because this is an invalid prototype - // (see Option.ParsePrototype(), and thus it'll prevent Category - // instances from being accidentally used as normal options. - public Category(string description) - : base("=:Category:= " + description, description) - { - } - - protected override void OnParseComplete(OptionContext c) - { - throw new NotSupportedException("Category.OnParseComplete should not be invoked."); - } - } - - - public new OptionSet Add(Option option) - { - base.Add(option); - return this; - } - - sealed class ActionOption : Option - { - Action action; - - public ActionOption(string prototype, string description, int count, Action action) - : this(prototype, description, count, action, false) - { - } - - public ActionOption(string prototype, string description, int count, Action action, bool hidden) - : base(prototype, description, count, hidden) - { - if (action == null) - throw new ArgumentNullException("action"); - this.action = action; - } - - protected override void OnParseComplete(OptionContext c) - { - action(c.OptionValues); - } - } - - public OptionSet Add(string prototype, Action action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, Action action) - { - return Add(prototype, description, action, false); - } - - public OptionSet Add(string prototype, string description, Action action, bool hidden) - { - if (action == null) - throw new ArgumentNullException("action"); - Option p = new ActionOption(prototype, description, 1, - delegate (OptionValueCollection v) { action(v[0]); }, hidden); - base.Add(p); - return this; - } - - public OptionSet Add(string prototype, OptionAction action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, OptionAction action) - { - return Add(prototype, description, action, false); - } - - public OptionSet Add(string prototype, string description, OptionAction action, bool hidden) - { - if (action == null) - throw new ArgumentNullException("action"); - Option p = new ActionOption(prototype, description, 2, - delegate (OptionValueCollection v) { action(v[0], v[1]); }, hidden); - base.Add(p); - return this; - } - - sealed class ActionOption : Option - { - Action action; - - public ActionOption(string prototype, string description, Action action) - : base(prototype, description, 1) - { - if (action == null) - throw new ArgumentNullException("action"); - this.action = action; - } - - protected override void OnParseComplete(OptionContext c) - { - action(Parse(c.OptionValues[0], c)); - } - } - - sealed class ActionOption : Option - { - OptionAction action; - - public ActionOption(string prototype, string description, OptionAction action) - : base(prototype, description, 2) - { - if (action == null) - throw new ArgumentNullException("action"); - this.action = action; - } - - protected override void OnParseComplete(OptionContext c) - { - action( - Parse(c.OptionValues[0], c), - Parse(c.OptionValues[1], c)); - } - } - - public OptionSet Add(string prototype, Action action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, Action action) - { - return Add(new ActionOption(prototype, description, action)); - } - - public OptionSet Add(string prototype, OptionAction action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, OptionAction action) - { - return Add(new ActionOption(prototype, description, action)); - } - - public OptionSet Add(ArgumentSource source) - { - if (source == null) - throw new ArgumentNullException("source"); - sources.Add(source); - return this; - } - - protected virtual OptionContext CreateOptionContext() - { - return new OptionContext(this); - } - - public List Parse(IEnumerable arguments) - { - if (arguments == null) - throw new ArgumentNullException("arguments"); - OptionContext c = CreateOptionContext(); - c.OptionIndex = -1; - bool process = true; - List unprocessed = new List(); - Option def = Contains("<>") ? this["<>"] : null; - ArgumentEnumerator ae = new ArgumentEnumerator(arguments); - foreach (string argument in ae) - { - ++c.OptionIndex; - if (argument == "--") - { - process = false; - continue; - } - if (!process) - { - Unprocessed(unprocessed, def, c, argument); - continue; - } - if (AddSource(ae, argument)) - continue; - if (!Parse(argument, c)) - Unprocessed(unprocessed, def, c, argument); - } - if (c.Option != null) - c.Option.Invoke(c); - return unprocessed; - } - - class ArgumentEnumerator : IEnumerable - { - List> sources = new List>(); - - public ArgumentEnumerator(IEnumerable arguments) - { - sources.Add(arguments.GetEnumerator()); - } - - public void Add(IEnumerable arguments) - { - sources.Add(arguments.GetEnumerator()); - } - - public IEnumerator GetEnumerator() - { - do - { - IEnumerator c = sources[sources.Count - 1]; - if (c.MoveNext()) - yield return c.Current; - else - { - c.Dispose(); - sources.RemoveAt(sources.Count - 1); - } - } while (sources.Count > 0); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - - bool AddSource(ArgumentEnumerator ae, string argument) - { - foreach (ArgumentSource source in sources) - { - IEnumerable replacement; - if (!source.GetArguments(argument, out replacement)) - continue; - ae.Add(replacement); - return true; - } - return false; - } - - private static bool Unprocessed(ICollection extra, Option def, OptionContext c, string argument) - { - if (def == null) - { - extra.Add(argument); - return false; - } - c.OptionValues.Add(argument); - c.Option = def; - c.Option.Invoke(c); - return false; - } - - private readonly Regex ValueOption = new Regex( - @"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$"); - - protected bool GetOptionParts(string argument, out string flag, out string name, out string sep, out string value) - { - if (argument == null) - throw new ArgumentNullException("argument"); - - flag = name = sep = value = null; - Match m = ValueOption.Match(argument); - if (!m.Success) - { - return false; - } - flag = m.Groups["flag"].Value; - name = m.Groups["name"].Value; - if (m.Groups["sep"].Success && m.Groups["value"].Success) - { - sep = m.Groups["sep"].Value; - value = m.Groups["value"].Value; - } - return true; - } - - protected virtual bool Parse(string argument, OptionContext c) - { - if (c.Option != null) - { - ParseValue(argument, c); - return true; - } - - string f, n, s, v; - if (!GetOptionParts(argument, out f, out n, out s, out v)) - return false; - - Option p; - if (Contains(n)) - { - p = this[n]; - c.OptionName = f + n; - c.Option = p; - switch (p.OptionValueType) - { - case OptionValueType.None: - c.OptionValues.Add(n); - c.Option.Invoke(c); - break; - case OptionValueType.Optional: - case OptionValueType.Required: - ParseValue(v, c); - break; - } - return true; - } - // no match; is it a bool option? - if (ParseBool(argument, n, c)) - return true; - // is it a bundled option? - if (ParseBundledValue(f, string.Concat(n + s + v), c)) - return true; - - return false; - } - - private void ParseValue(string option, OptionContext c) - { - if (option != null) - foreach (string o in c.Option.ValueSeparators != null - ? option.Split(c.Option.ValueSeparators, c.Option.MaxValueCount - c.OptionValues.Count, StringSplitOptions.None) - : new string[] { option }) - { - c.OptionValues.Add(o); - } - if (c.OptionValues.Count == c.Option.MaxValueCount || - c.Option.OptionValueType == OptionValueType.Optional) - c.Option.Invoke(c); - else if (c.OptionValues.Count > c.Option.MaxValueCount) - { - throw new OptionException(localizer(string.Format( - "Error: Found {0} option values when expecting {1}.", - c.OptionValues.Count, c.Option.MaxValueCount)), - c.OptionName); - } - } - - private bool ParseBool(string option, string n, OptionContext c) - { - Option p; - string rn; - if (n.Length >= 1 && (n[n.Length - 1] == '+' || n[n.Length - 1] == '-') && - Contains((rn = n.Substring(0, n.Length - 1)))) - { - p = this[rn]; - string v = n[n.Length - 1] == '+' ? option : null; - c.OptionName = option; - c.Option = p; - c.OptionValues.Add(v); - p.Invoke(c); - return true; - } - return false; - } - - private bool ParseBundledValue(string f, string n, OptionContext c) - { - if (f != "-") - return false; - for (int i = 0; i < n.Length; ++i) - { - Option p; - string opt = f + n[i].ToString(); - string rn = n[i].ToString(); - if (!Contains(rn)) - { - if (i == 0) - return false; - throw new OptionException(string.Format(localizer( - "Cannot bundle unregistered option '{0}'."), opt), opt); - } - p = this[rn]; - switch (p.OptionValueType) - { - case OptionValueType.None: - Invoke(c, opt, n, p); - break; - case OptionValueType.Optional: - case OptionValueType.Required: - { - string v = n.Substring(i + 1); - c.Option = p; - c.OptionName = opt; - ParseValue(v.Length != 0 ? v : null, c); - return true; - } - default: - throw new InvalidOperationException("Unknown OptionValueType: " + p.OptionValueType); - } - } - return true; - } - - private static void Invoke(OptionContext c, string name, string value, Option option) - { - c.OptionName = name; - c.Option = option; - c.OptionValues.Add(value); - option.Invoke(c); - } - - private const int OptionWidth = 29; - private const int Description_FirstWidth = 80 - OptionWidth; - private const int Description_RemWidth = 80 - OptionWidth - 2; - - public void WriteOptionDescriptions(TextWriter o) - { - foreach (Option p in this) - { - int written = 0; - - if (p.Hidden) - continue; - - Category c = p as Category; - if (c != null) - { - WriteDescription(o, p.Description, "", 80, 80); - continue; - } - - if (!WriteOptionPrototype(o, p, ref written)) - continue; - - if (written < OptionWidth) - o.Write(new string(' ', OptionWidth - written)); - else - { - o.WriteLine(); - o.Write(new string(' ', OptionWidth)); - } - - WriteDescription(o, p.Description, new string(' ', OptionWidth + 2), - Description_FirstWidth, Description_RemWidth); - } - - foreach (ArgumentSource s in sources) - { - string[] names = s.GetNames(); - if (names == null || names.Length == 0) - continue; - - int written = 0; - - Write(o, ref written, " "); - Write(o, ref written, names[0]); - for (int i = 1; i < names.Length; ++i) - { - Write(o, ref written, ", "); - Write(o, ref written, names[i]); - } - - if (written < OptionWidth) - o.Write(new string(' ', OptionWidth - written)); - else - { - o.WriteLine(); - o.Write(new string(' ', OptionWidth)); - } - - WriteDescription(o, s.Description, new string(' ', OptionWidth + 2), - Description_FirstWidth, Description_RemWidth); - } - } - - void WriteDescription(TextWriter o, string value, string prefix, int firstWidth, int remWidth) - { - bool indent = false; - foreach (string line in GetLines(localizer(GetDescription(value)), firstWidth, remWidth)) - { - if (indent) - o.Write(prefix); - o.WriteLine(line); - indent = true; - } - } - - bool WriteOptionPrototype(TextWriter o, Option p, ref int written) - { - string[] names = p.Names; - - int i = GetNextOptionIndex(names, 0); - if (i == names.Length) - return false; - - if (names[i].Length == 1) - { - Write(o, ref written, " -"); - Write(o, ref written, names[0]); - } - else - { - Write(o, ref written, " --"); - Write(o, ref written, names[0]); - } - - for (i = GetNextOptionIndex(names, i + 1); - i < names.Length; i = GetNextOptionIndex(names, i + 1)) - { - Write(o, ref written, ", "); - Write(o, ref written, names[i].Length == 1 ? "-" : "--"); - Write(o, ref written, names[i]); - } - - if (p.OptionValueType == OptionValueType.Optional || - p.OptionValueType == OptionValueType.Required) - { - if (p.OptionValueType == OptionValueType.Optional) - { - Write(o, ref written, localizer("[")); - } - Write(o, ref written, localizer("=" + GetArgumentName(0, p.MaxValueCount, p.Description))); - string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0 - ? p.ValueSeparators[0] - : " "; - for (int c = 1; c < p.MaxValueCount; ++c) - { - Write(o, ref written, localizer(sep + GetArgumentName(c, p.MaxValueCount, p.Description))); - } - if (p.OptionValueType == OptionValueType.Optional) - { - Write(o, ref written, localizer("]")); - } - } - return true; - } - - static int GetNextOptionIndex(string[] names, int i) - { - while (i < names.Length && names[i] == "<>") - { - ++i; - } - return i; - } - - static void Write(TextWriter o, ref int n, string s) - { - n += s.Length; - o.Write(s); - } - - private static string GetArgumentName(int index, int maxIndex, string description) - { - if (description == null) - return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); - string[] nameStart; - if (maxIndex == 1) - nameStart = new string[] { "{0:", "{" }; - else - nameStart = new string[] { "{" + index + ":" }; - for (int i = 0; i < nameStart.Length; ++i) - { - int start, j = 0; - do - { - start = description.IndexOf(nameStart[i], j); - } while (start >= 0 && j != 0 ? description[j++ - 1] == '{' : false); - if (start == -1) - continue; - int end = description.IndexOf("}", start); - if (end == -1) - continue; - return description.Substring(start + nameStart[i].Length, end - start - nameStart[i].Length); - } - return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); - } - - private static string GetDescription(string description) - { - if (description == null) - return string.Empty; - StringBuilder sb = new StringBuilder(description.Length); - int start = -1; - for (int i = 0; i < description.Length; ++i) - { - switch (description[i]) - { - case '{': - if (i == start) - { - sb.Append('{'); - start = -1; - } - else if (start < 0) - start = i + 1; - break; - case '}': - if (start < 0) - { - if ((i + 1) == description.Length || description[i + 1] != '}') - throw new InvalidOperationException("Invalid option description: " + description); - ++i; - sb.Append("}"); - } - else - { - sb.Append(description.Substring(start, i - start)); - start = -1; - } - break; - case ':': - if (start < 0) - goto default; - start = i + 1; - break; - default: - if (start < 0) - sb.Append(description[i]); - break; - } - } - return sb.ToString(); - } - - private static IEnumerable GetLines(string description, int firstWidth, int remWidth) - { - return StringCoda.WrappedLines(description, firstWidth, remWidth); - } - } - -} - diff --git a/Src/PE Dump/PE Dump.csproj b/Src/PE Dump/PE Dump.csproj deleted file mode 100644 index b833498..0000000 --- a/Src/PE Dump/PE Dump.csproj +++ /dev/null @@ -1,72 +0,0 @@ - - - - - Debug - AnyCPU - {3A01212E-8461-41A0-B154-22CBA75929A3} - Exe - Properties - Workshell.PE.Dump - pedump - v4.0 - 512 - - - - AnyCPU - true - full - false - ..\..\Bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - ..\..\Bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - {2b06cbf8-136a-4bec-8624-861992139489} - Workshell.PE.Resources - - - {2e173d25-1c2e-4a7b-8b37-d231324d372d} - Workshell.PE - - - - - \ No newline at end of file diff --git a/Src/PE Dump/Program.cs b/Src/PE Dump/Program.cs deleted file mode 100644 index fb57e75..0000000 --- a/Src/PE Dump/Program.cs +++ /dev/null @@ -1,1044 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Mono.Options; -using Workshell.PE; -using Workshell.PE.Annotations; -using Workshell.PE.Debug; -using Workshell.PE.LoadConfiguration; - -namespace Workshell.PE.Dump -{ - - class Program - { - - private OptionSet options; - private string offset_type; - private bool show_all; - private bool show_dos_header; - private bool show_dos_stub; - private bool show_file_header; - private bool show_opt_header; - private bool show_data_directories; - private bool show_section_table; - private bool show_debug; - private bool show_load_config; - - public Program() - { - options = new OptionSet(); - - options.Add("offset=", "", v => offset_type = v); - options.Add("all", "", v => show_all = v != null); - options.Add("dos-header", "", v => show_dos_header = v != null); - options.Add("dos-stub", "", v => show_dos_stub = v != null); - options.Add("file-header", "", v => show_file_header = v != null); - options.Add("optional-header", "", v => show_opt_header = v != null); - options.Add("data-directories", "", v => show_data_directories = v != null); - options.Add("sections", "", v => show_section_table = v != null); - options.Add("debug", "", v => show_debug = v != null); - options.Add("load-config", "", v => show_load_config = v != null); - - offset_type = "fo"; - show_all = false; - show_dos_header = false; - show_dos_stub = false; - show_file_header = false; - show_opt_header = false; - show_data_directories = false; - show_section_table = false; - show_debug = false; - show_load_config = false; - } - - #region Static Methods - - static int Main(string[] args) - { - return (new Program()).Run(args); - } - - #endregion - - #region Methods - - public int Run(string[] args) - { - try - { - if (args.Length == 0) - { - Usage(); - - return 1; - } - - List extra = options.Parse(args); - - if (extra.Count == 0) - { - Console.WriteLine("Error: No file specified."); - - return 2; - } - - string[] address_types = { "fo", "vo", "va", "rva" }; - - if (!address_types.Contains(offset_type, StringComparer.OrdinalIgnoreCase)) - { - Console.WriteLine("Error: Unknown address type - " + offset_type); - - return 3; - } - - string file_name = extra[0]; - string valid_message = null; - - if (!ExecutableImage.IsValid(file_name, out valid_message)) - { - Console.WriteLine("Error: {0}", valid_message); - - return 4; - } - - ExecutableImage image = ExecutableImage.FromFile(file_name); - - try - { - if (show_all) - { - show_dos_header = true; - show_dos_stub = true; - show_file_header = true; - show_opt_header = true; - show_data_directories = true; - show_section_table = true; - show_debug = true; - show_load_config = true; - } - - int result = ShowBasicDetails(image, file_name); - - if (result == 0 && show_dos_header) - result = ShowDOSHeader(image); - - if (result == 0 && show_dos_stub) - result = ShowDOSStub(image); - - if (result == 0 && show_file_header) - result = ShowFileHeader(image); - - if (result == 0 && show_opt_header) - result = ShowOptionalHeader(image); - - if (result == 0 && show_data_directories) - result = ShowDataDirectories(image); - - if (result == 0 && show_section_table) - result = ShowSectionTable(image); - - if (result == 0 && show_debug) - result = ShowDebugDirectory(image); - - if (result == 0 && show_load_config) - result = ShowLoadConfig(image); - - return result; - } - finally - { - image.Dispose(); - } - } - catch (Exception ex) - { -#if DEBUG - throw; -#else - Console.WriteLine("Error: {0}", ex.Message); - - return 666; -#endif - } - } - - private void Usage() - { - - } - - private int ShowBasicDetails(ExecutableImage image, string fileName) - { - Stream stream = image.GetStream(); - string image_type = "Unknown"; - CharacteristicsType characteristics = image.NTHeaders.FileHeader.GetCharacteristics(); - - if ((characteristics & CharacteristicsType.IsDLL) == CharacteristicsType.IsDLL) - { - image_type = "Dynamic Link Library"; - } - else - { - SubSystemType sub_system = image.NTHeaders.OptionalHeader.GetSubsystem(); - - if (sub_system == SubSystemType.WindowsCUI) - { - image_type = "Console Application"; - } - else if (sub_system == SubSystemType.WindowsGUI) - { - image_type = "Windows Application"; - } - } - - Console.WriteLine("[ Basic Details ]"); - Console.WriteLine(); - - Console.WriteLine(" Filename: {0}", Path.GetFileName(fileName)); - Console.WriteLine(" Path: {0}", Path.GetDirectoryName(fileName)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(stream.Length), stream.Length); - Console.WriteLine(" Architecture: {0}", (image.Is64Bit ? "64-Bit" : "32-Bit")); - Console.WriteLine(" Image Type: {0}", image_type); - Console.WriteLine(" Is .NET: {0}", (image.IsCLR ? "Yes" : "No")); - Console.WriteLine(" Is Signed: {0}", (image.IsSigned ? "Yes" : "No")); - - Console.WriteLine(); - Console.WriteLine(); - - return 0; - } - - private int ShowDOSHeader(ExecutableImage image) - { - Console.WriteLine("[ MS-DOS Header ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(image.DOSHeader.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(image.DOSHeader.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(image.DOSHeader.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(image.DOSHeader.Location.FileSize)), image.DOSHeader.Location.FileSize); - - Console.WriteLine(); - - List> tuples = new List>(); - ulong offset; - - if (offset_type == "fo") - { - offset = image.DOSHeader.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = image.DOSHeader.Location.VirtualAddress; - } - else - { - offset = image.DOSHeader.Location.RelativeVirtualAddress; - } - - int address_size = (image.Is64Bit ? 16 : 8); - - FieldAnnotations annotations = FieldAnnotations.Get(image.DOSHeader); - - foreach (FieldAnnotation annotation in annotations) - { - int size = annotation.Size; - int array_size = (annotation.IsArray ? annotation.ArraySize : annotation.Size); - object value = (annotation.IsArray ? Utils.GetDefaultValue(annotation.Type.GetElementType()) : annotation.Value); - - Tuple tuple = new Tuple(Utils.IntToHex(offset, address_size), Utils.IntToHex(value, size * 2), annotation.Description); - - tuples.Add(tuple); - - offset += Convert.ToUInt32(array_size); - } - - int max_value_len = 0; - int max_desc_len = 0; - - foreach(var tuple in tuples) - { - if (tuple.Item2.Length > max_value_len) - max_value_len = tuple.Item2.Length; - - if (tuple.Item3.Length > max_desc_len) - max_desc_len = tuple.Item3.Length; - } - - string header = String.Format("{0} {1} {2}", "Address".PadRight(address_size + 2), "Value".PadRight(max_value_len), "Description".PadRight(max_desc_len)); - - Console.WriteLine(" " + header); - Console.WriteLine(" " + String.Empty.PadRight(header.Length, '-')); - - foreach (var tuple in tuples) - Console.WriteLine(" {0} {1} {2}", tuple.Item1.PadRight(address_size + 2), tuple.Item2.PadRight(max_value_len), tuple.Item3.PadRight(max_desc_len)); - - Console.WriteLine(); - Console.WriteLine(); - - return 0; - } - - private int ShowDOSStub(ExecutableImage image) - { - Console.WriteLine("[ MS-DOS Stub ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(image.DOSStub.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(image.DOSStub.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(image.DOSStub.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(image.DOSStub.Location.FileSize)), image.DOSStub.Location.FileSize); - - Console.WriteLine(); - Console.WriteLine(); - - return 0; - } - - private int ShowFileHeader(ExecutableImage image) - { - Console.WriteLine("[ File Header ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(image.NTHeaders.FileHeader.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(image.NTHeaders.FileHeader.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(image.NTHeaders.FileHeader.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(image.NTHeaders.FileHeader.Location.FileSize)), image.NTHeaders.FileHeader.Location.FileSize); - - Console.WriteLine(); - - List> tuples = new List>(); - ulong offset; - - if (offset_type == "fo") - { - offset = image.NTHeaders.FileHeader.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = image.NTHeaders.FileHeader.Location.VirtualAddress; - } - else - { - offset = image.NTHeaders.FileHeader.Location.RelativeVirtualAddress; - } - - int address_size = (image.Is64Bit ? 16 : 8); - - FieldAnnotations annotations = FieldAnnotations.Get(image.NTHeaders.FileHeader); - - foreach (FieldAnnotation annotation in annotations) - { - int size = annotation.Size; - int array_size = (annotation.IsArray ? annotation.ArraySize : annotation.Size); - object value = (annotation.IsArray ? Utils.GetDefaultValue(annotation.Type.GetElementType()) : annotation.Value); - - Tuple tuple = new Tuple(Utils.IntToHex(offset, address_size), Utils.IntToHex(value, size * 2), annotation.Description); - - tuples.Add(tuple); - - offset += Convert.ToUInt32(array_size); - } - - int max_value_len = 0; - int max_desc_len = 0; - - foreach (var tuple in tuples) - { - if (tuple.Item2.Length > max_value_len) - max_value_len = tuple.Item2.Length; - - if (tuple.Item3.Length > max_desc_len) - max_desc_len = tuple.Item3.Length; - } - - string header = String.Format("{0} {1} {2}", "Address".PadRight(address_size + 2), "Value".PadRight(max_value_len), "Description".PadRight(max_desc_len)); - - Console.WriteLine(" " + header); - Console.WriteLine(" " + String.Empty.PadRight(header.Length, '-')); - - foreach (var tuple in tuples) - Console.WriteLine(" {0} {1} {2}", tuple.Item1.PadRight(address_size + 2), tuple.Item2.PadRight(max_value_len), tuple.Item3.PadRight(max_desc_len)); - - Console.WriteLine(); - - ShowFileHeader_Characteristics(image); - - Console.WriteLine(); - - return 0; - } - - private void ShowFileHeader_Characteristics(ExecutableImage image) - { - List lines = new List(); - - CharacteristicsType characteristics = image.NTHeaders.FileHeader.GetCharacteristics(); - long enum_value = Convert.ToInt64(characteristics); - EnumAnnotations enum_annotations = new EnumAnnotations(); - - foreach (EnumAnnotation annotation in enum_annotations) - { - long value = Convert.ToInt64(annotation.Value); - bool selected = ((enum_value & value) == value); - - if (!selected) - continue; - - string line = String.Format("{0} {1}", Utils.IntToHex(value, 4), annotation.HeaderName); - - lines.Add(line); - } - - int max_len = 0; - - foreach (var line in lines) - { - if (line.Length > max_len) - max_len = line.Length; - } - - max_len = max_len + 2; - - Console.WriteLine(" Characteristics".PadRight(max_len)); - Console.WriteLine(" " + String.Empty.PadRight(max_len, '-')); - - foreach(var line in lines) - Console.WriteLine(" " + line.PadRight(max_len)); - - Console.WriteLine(); - } - - private int ShowOptionalHeader(ExecutableImage image) - { - Console.WriteLine("[ Optional Header ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(image.NTHeaders.OptionalHeader.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(image.NTHeaders.OptionalHeader.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(image.NTHeaders.OptionalHeader.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(image.NTHeaders.OptionalHeader.Location.FileSize)), image.NTHeaders.OptionalHeader.Location.FileSize); - Console.WriteLine(); - - List> tuples = new List>(); - ulong offset; - - if (offset_type == "fo") - { - offset = image.NTHeaders.OptionalHeader.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = image.NTHeaders.OptionalHeader.Location.VirtualAddress; - } - else - { - offset = image.NTHeaders.OptionalHeader.Location.RelativeVirtualAddress; - } - - int address_size = (image.Is64Bit ? 16 : 8); - - string[] VARY_FIELDS = { "ImageBase", "SizeOfStackReserve", "SizeOfStackCommit", "SizeOfHeapReserve", "SizeOfHeapCommit" }; - FieldAnnotations annotations = FieldAnnotations.Get(image.NTHeaders.OptionalHeader); - - foreach (FieldAnnotation annotation in annotations) - { - int size = annotation.Size * 2; - - if (VARY_FIELDS.Contains(annotation.Name, StringComparer.OrdinalIgnoreCase)) - size = (image.Is64Bit ? 16 : 8); - - int array_size = (annotation.IsArray ? annotation.ArraySize : annotation.Size); - object value = (annotation.IsArray ? Utils.GetDefaultValue(annotation.Type.GetElementType()) : annotation.Value); - - Tuple tuple = new Tuple(Utils.IntToHex(offset, address_size), Utils.IntToHex(value, size), annotation.Description); - - tuples.Add(tuple); - - offset += Convert.ToUInt32(array_size); - } - - int max_value_len = 0; - int max_desc_len = 0; - - foreach (var tuple in tuples) - { - if (tuple.Item2.Length > max_value_len) - max_value_len = tuple.Item2.Length; - - if (tuple.Item3.Length > max_desc_len) - max_desc_len = tuple.Item3.Length; - } - - string header = String.Format("{0} {1} {2}", "Address".PadRight(address_size + 2), "Value".PadRight(max_value_len), "Description".PadRight(max_desc_len)); - - Console.WriteLine(" " + header); - Console.WriteLine(" " + String.Empty.PadRight(header.Length, '-')); - - foreach (var tuple in tuples) - Console.WriteLine(" {0} {1} {2}", tuple.Item1.PadRight(address_size + 2), tuple.Item2.PadRight(max_value_len), tuple.Item3.PadRight(max_desc_len)); - - Console.WriteLine(); - - ShowOptionalHeader_SubSystem(image); - ShowOptionalHeader_DllCharacteristics(image); - - Console.WriteLine(); - - return 0; - } - - private void ShowOptionalHeader_SubSystem(ExecutableImage image) - { - List lines = new List(); - - SubSystemType sub_system = image.NTHeaders.OptionalHeader.GetSubsystem(); - long enum_value = Convert.ToInt64(sub_system); - EnumAnnotations enum_annotations = new EnumAnnotations(); - - foreach (EnumAnnotation annotation in enum_annotations) - { - long value = Convert.ToInt64(annotation.Value); - - if (value == 0) - continue; - - bool selected = ((enum_value & value) == value); - - if (!selected) - continue; - - string line = String.Format("{0} {1}", Utils.IntToHex(value, 4), annotation.HeaderName); - - lines.Add(line); - } - - int max_len = 0; - - foreach (var line in lines) - { - if (line.Length > max_len) - max_len = line.Length; - } - - max_len = max_len + 2; - - Console.WriteLine(" Sub-System".PadRight(max_len)); - Console.WriteLine(" " + String.Empty.PadRight(max_len, '-')); - - foreach (var line in lines) - Console.WriteLine(" " + line.PadRight(max_len)); - - Console.WriteLine(); - } - - private void ShowOptionalHeader_DllCharacteristics(ExecutableImage image) - { - List lines = new List(); - - DllCharacteristicsType dll_chars = image.NTHeaders.OptionalHeader.GetDllCharacteristics(); - long enum_value = Convert.ToInt64(dll_chars); - EnumAnnotations enum_annotations = new EnumAnnotations(); - - foreach (EnumAnnotation annotation in enum_annotations) - { - long value = Convert.ToInt64(annotation.Value); - - if (value == 0) - continue; - - bool selected = ((enum_value & value) == value); - - if (!selected) - continue; - - string line = String.Format("{0} {1}", Utils.IntToHex(value, 4), annotation.HeaderName); - - lines.Add(line); - } - - int max_len = 0; - - foreach (var line in lines) - { - if (line.Length > max_len) - max_len = line.Length; - } - - max_len = max_len + 2; - - Console.WriteLine(" DLL Characteristics".PadRight(max_len)); - Console.WriteLine(" " + String.Empty.PadRight(max_len, '-')); - - foreach (var line in lines) - Console.WriteLine(" " + line.PadRight(max_len)); - - Console.WriteLine(); - } - - private int ShowDataDirectories(ExecutableImage image) - { - Console.WriteLine("[ Data Directories ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(image.NTHeaders.DataDirectories.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(image.NTHeaders.DataDirectories.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(image.NTHeaders.DataDirectories.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(image.NTHeaders.DataDirectories.Location.FileSize)), image.NTHeaders.DataDirectories.Location.FileSize); - Console.WriteLine(); - - int address_size = (image.Is64Bit ? 16 : 8); - ulong offset; - - if (offset_type == "fo") - { - offset = image.NTHeaders.DataDirectories.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = image.NTHeaders.DataDirectories.Location.VirtualAddress; - } - else - { - offset = image.NTHeaders.DataDirectories.Location.RelativeVirtualAddress; - } - - for(var i = 0; i < image.NTHeaders.DataDirectories.Count - 1; i++) - { - DataDirectory directory = image.NTHeaders.DataDirectories[i]; - string name; - - switch (directory.DirectoryType) - { - case DataDirectoryType.Unknown: - name = String.Empty; - break; - case DataDirectoryType.ExportTable: - name = "Export Table"; - break; - case DataDirectoryType.ImportTable: - name = "Import Table"; - break; - case DataDirectoryType.ResourceTable: - name = "Resource Table"; - break; - case DataDirectoryType.ExceptionTable: - name = "Exception Table"; - break; - case DataDirectoryType.CertificateTable: - name = "Certificate Table"; - break; - case DataDirectoryType.BaseRelocationTable: - name = "Base Relocation Table"; - break; - case DataDirectoryType.Debug: - name = "Debug Directory"; - break; - case DataDirectoryType.Architecture: - name = "Architecture"; - break; - case DataDirectoryType.GlobalPtr: - name = "Global Pointer"; - break; - case DataDirectoryType.TLSTable: - name = "TLS Table"; - break; - case DataDirectoryType.LoadConfigTable: - name = "Load Configuration Table"; - break; - case DataDirectoryType.BoundImport: - name = "Bound Import Table"; - break; - case DataDirectoryType.ImportAddressTable: - name = "Import Address Table"; - break; - case DataDirectoryType.DelayImportDescriptor: - name = "Delayed Import Descriptors"; - break; - case DataDirectoryType.CLRRuntimeHeader: - name = ".NET Common Language Runtime Header"; - break; - default: - name = "Unknown"; - break; - } - - List lines = new List(); - - lines.Add(String.Format("Entry Offset: {0}",Utils.IntToHex(offset, address_size))); - lines.Add(String.Format("RVA: {0}", Utils.IntToHex(directory.VirtualAddress))); - lines.Add(String.Format("Size: {0} ({1})", directory.Size, Utils.FormatBytes(directory.Size))); - - string section = directory.GetSectionName(); - - if (!String.IsNullOrWhiteSpace(section)) - lines.Add(String.Format("Section: {0}", section)); - - int max_len = name.Length; - - foreach(var line in lines) - { - if (line.Length > max_len) - max_len = line.Length; - } - - max_len = max_len + 2; - - Console.WriteLine(" " + name.PadRight(max_len)); - Console.WriteLine(" " + String.Empty.PadRight(max_len, '-')); - - foreach(var line in lines) - Console.WriteLine(" " + line.PadRight(max_len)); - - Console.WriteLine(); - - offset += sizeof(uint) * 2; - } - - Console.WriteLine(); - - return 0; - } - - private int ShowSectionTable(ExecutableImage image) - { - Console.WriteLine("[ Section Table ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(image.SectionTable.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(image.SectionTable.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(image.SectionTable.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(image.SectionTable.Location.FileSize)), image.SectionTable.Location.FileSize); - Console.WriteLine(); - - int address_size = (image.Is64Bit ? 16 : 8); - ulong offset; - - if (offset_type == "fo") - { - offset = image.SectionTable.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = image.SectionTable.Location.VirtualAddress; - } - else - { - offset = image.SectionTable.Location.RelativeVirtualAddress; - } - - foreach(SectionTableEntry section in image.SectionTable) - { - string name = section.Name; - string[] chars = ShowSectionTable_Characteristics(section); - List lines = new List(); - - lines.Add(String.Format("Entry Offset: {0}", Utils.IntToHex(offset, address_size))); - lines.Add(String.Format("Virtual Size: {0} ({1})", section.VirtualSizeOrPhysicalAddress, Utils.FormatBytes(section.VirtualSizeOrPhysicalAddress))); - lines.Add(String.Format("RVA: {0}", Utils.IntToHex(section.VirtualAddress))); - lines.Add(String.Format("Size of Raw Data: {0} ({1})", section.SizeOfRawData, Utils.FormatBytes(section.SizeOfRawData))); - lines.Add(String.Format("Pointer to Raw Data: {0}", Utils.IntToHex(section.PointerToRawData))); - lines.Add(String.Format("Pointer to Relocations: {0}", Utils.IntToHex(section.PointerToRelocations))); - lines.Add(String.Format("Pointer to Line Numbers: {0}", Utils.IntToHex(section.PointerToLineNumbers))); - lines.Add(String.Format("Number of Relocations: {0}", section.NumberOfRelocations)); - lines.Add(String.Format("Number of Line Numbers: {0}", section.NumberOfLineNumbers)); - - if (chars.Length > 0) - { - lines.Add(String.Format("Characteristics: {0}", chars.First())); - - if (chars.Length > 1) - { - foreach(string line in chars.Skip(1)) - lines.Add(String.Format(" {0}", line)); - } - } - - int max_len = name.Length; - - foreach (var line in lines) - { - if (line.Length > max_len) - max_len = line.Length; - } - - max_len = max_len + 2; - - Console.WriteLine(" " + name.PadRight(max_len)); - Console.WriteLine(" " + String.Empty.PadRight(max_len, '-')); - - foreach (var line in lines) - Console.WriteLine(" " + line.PadRight(max_len)); - - Console.WriteLine(); - - offset += section.Location.FileSize; - } - - Console.WriteLine(); - - return 0; - } - - private string[] ShowSectionTable_Characteristics(SectionTableEntry section) - { - List results = new List(); - - SectionCharacteristicsType chars = section.GetCharacteristics(); - long enum_value = Convert.ToInt64(chars); - EnumAnnotations enum_annotations = new EnumAnnotations(); - - foreach (EnumAnnotation annotation in enum_annotations) - { - long value = Convert.ToInt64(annotation.Value); - - if (value == 0) - continue; - - bool selected = ((enum_value & value) == value); - - if (!selected) - continue; - - string line = String.Format("{0} {1}", Utils.IntToHex(value, 8), annotation.HeaderName); - - results.Add(line); - } - - int max_len = 0; - - foreach (var line in results) - { - if (line.Length > max_len) - max_len = line.Length; - } - - return results.ToArray(); - } - - private int ShowDebugDirectory(ExecutableImage image) - { - DebugDirectory directory = DebugDirectory.Get(image); - - if (directory == null) - return 0; - - Console.WriteLine("[ Debug Directory ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(directory.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(directory.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(directory.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(directory.Location.FileSize)), directory.Location.FileSize); - Console.WriteLine(); - - int address_size = (image.Is64Bit ? 16 : 8); - ulong offset; - - if (offset_type == "fo") - { - offset = directory.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = directory.Location.VirtualAddress; - } - else - { - offset = directory.Location.RelativeVirtualAddress; - } - - foreach (DebugDirectoryEntry entry in directory) - { - string name = entry.GetEntryType().ToString(); - string type = ShowDebugDirectory_Type(entry); - List lines = new List(); - - lines.Add(String.Format("Entry Offset: {0}", Utils.IntToHex(offset, address_size))); - lines.Add(String.Format("Characteristics: {0}", Utils.IntToHex(entry.Characteristics))); - lines.Add(String.Format("Date/Time Stamp: {0}", Utils.IntToHex(entry.TimeDateStamp))); - lines.Add(String.Format("Major Version: {0}", Utils.IntToHex(entry.MajorVersion))); - lines.Add(String.Format("Minor Version: {0}", Utils.IntToHex(entry.MinorVersion))); - lines.Add(String.Format("Type: {0}", type)); - lines.Add(String.Format("Size of Data: {0} ({1})", entry.SizeOfData, Utils.FormatBytes(entry.SizeOfData))); - lines.Add(String.Format("Address of Raw Data: {0}", Utils.IntToHex(entry.AddressOfRawData))); - lines.Add(String.Format("Pointer to Raw Data: {0}", Utils.IntToHex(entry.PointerToRawData))); - - int max_len = name.Length; - - foreach (var line in lines) - { - if (line.Length > max_len) - max_len = line.Length; - } - - max_len = max_len + 2; - - Console.WriteLine(" " + name.PadRight(max_len)); - Console.WriteLine(" " + String.Empty.PadRight(max_len, '-')); - - foreach (var line in lines) - Console.WriteLine(" " + line.PadRight(max_len)); - - Console.WriteLine(); - - offset += entry.Location.FileSize; - } - - Console.WriteLine(); - - return 0; - } - - private string ShowDebugDirectory_Type(DebugDirectoryEntry directoryEntry) - { - DebugDirectoryEntryType type = directoryEntry.GetEntryType(); - EnumAnnotations annotations = new EnumAnnotations(); - EnumAnnotation annotation = annotations.FirstOrDefault(a => a.Value == type); - - if (annotation == null) - return null; - - long value = Convert.ToInt64(annotation.Value); - string result = String.Format("{0} {1}", Utils.IntToHex(value, 8), annotation.HeaderName); - - return result; - } - - private int ShowLoadConfig(ExecutableImage image) - { - LoadConfigDirectory directory = LoadConfigDirectory.Get(image); - - if (directory == null) - return 0; - - Console.WriteLine("[ Load Configuration ]"); - Console.WriteLine(); - - Console.WriteLine(" File Offset: {0}", Utils.IntToHex(directory.Location.FileOffset)); - Console.WriteLine(" Virtual Address: {0}", Utils.IntToHex(directory.Location.VirtualAddress)); - Console.WriteLine(" RVA: {0}", Utils.IntToHex(directory.Location.RelativeVirtualAddress)); - Console.WriteLine(" Size: {1} ({0})", Utils.FormatBytes(Convert.ToInt64(directory.Location.FileSize)), directory.Location.FileSize); - Console.WriteLine(); - - List> tuples = new List>(); - ulong offset; - - if (offset_type == "fo") - { - offset = directory.Location.FileOffset; - } - else if (offset_type == "vo") - { - offset = 0; - } - else if (offset_type == "va") - { - offset = directory.Location.VirtualAddress; - } - else - { - offset = directory.Location.RelativeVirtualAddress; - } - - int address_size = (image.Is64Bit ? 16 : 8); - - string[] VARY_FIELDS = { - "DeCommitFreeBlockThreshold", - "DeCommitTotalFreeThreshold", - "LockPrefixTable", - "MaximumAllocationSize", - "VirtualMemoryThreshold", - "ProcessAffinityMask", - "EditList", - "SecurityCookie", - "SEHandlerTable", - "SEHandlerCount", - "GuardCFCheckFunctionPointer", - "Reserved2", - "GuardCFFunctionTable", - "GuardCFFunctionCount" - }; - FieldAnnotations annotations = FieldAnnotations.Get(directory); - - foreach (FieldAnnotation annotation in annotations) - { - int size = annotation.Size * 2; - - if (VARY_FIELDS.Contains(annotation.Name, StringComparer.OrdinalIgnoreCase)) - size = (image.Is64Bit ? 16 : 8); - - int array_size = (annotation.IsArray ? annotation.ArraySize : annotation.Size); - object value = (annotation.IsArray ? Utils.GetDefaultValue(annotation.Type.GetElementType()) : annotation.Value); - - Tuple tuple = new Tuple(Utils.IntToHex(offset, address_size), Utils.IntToHex(value, size), annotation.Description); - - tuples.Add(tuple); - - offset += Convert.ToUInt32(array_size); - } - - int max_value_len = 0; - int max_desc_len = 0; - - foreach (var tuple in tuples) - { - if (tuple.Item2.Length > max_value_len) - max_value_len = tuple.Item2.Length; - - if (tuple.Item3.Length > max_desc_len) - max_desc_len = tuple.Item3.Length; - } - - string header = String.Format("{0} {1} {2}", "Address".PadRight(address_size + 2), "Value".PadRight(max_value_len), "Description".PadRight(max_desc_len)); - - Console.WriteLine(" " + header); - Console.WriteLine(" " + String.Empty.PadRight(header.Length, '-')); - - foreach (var tuple in tuples) - Console.WriteLine(" {0} {1} {2}", tuple.Item1.PadRight(address_size + 2), tuple.Item2.PadRight(max_value_len), tuple.Item3.PadRight(max_desc_len)); - - Console.WriteLine(); - - //ShowOptionalHeader_SubSystem(image); - //ShowOptionalHeader_DllCharacteristics(image); - // - //Console.WriteLine(); - - return 0; - } - - #endregion - - } - -} diff --git a/Src/PE Dump/Properties/AssemblyInfo.cs b/Src/PE Dump/Properties/AssemblyInfo.cs deleted file mode 100644 index 70ef2ff..0000000 --- a/Src/PE Dump/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("PE Dump")] -[assembly: AssemblyDescription("A console application to view and dump information about a Portable Executable.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Workshell Ltd")] -[assembly: AssemblyProduct("PE Dump")] -[assembly: AssemblyCopyright("Copyright ©2016 Workshell Ltd")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("3a01212e-8461-41a0-b154-22cba75929a3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.4.*")] -[assembly: AssemblyInformationalVersion("1.4.0")] diff --git a/Src/PE Dump/Utils.cs b/Src/PE Dump/Utils.cs deleted file mode 100644 index f1a6b80..0000000 --- a/Src/PE Dump/Utils.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Workshell.PE.Dump -{ - - public enum NumberStyle : int - { - Decimal, - Hexadecimal - } - - internal class Utils - { - - public static bool IsNumeric(object value) - { - switch (Type.GetTypeCode(value.GetType())) - { - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.Int16: - case TypeCode.UInt32: - case TypeCode.Int32: - case TypeCode.UInt64: - case TypeCode.Int64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - return true; - default: - return false; - } - } - - public static string IntToHex(object value) - { - switch (Type.GetTypeCode(value.GetType())) - { - case TypeCode.Byte: return IntToHex(value, 2); - case TypeCode.SByte: return IntToHex(value, 2); - case TypeCode.UInt16: return IntToHex(value, 4); - case TypeCode.Int16: return IntToHex(value, 4); - case TypeCode.UInt32: return IntToHex(value, 8); - case TypeCode.Int32: return IntToHex(value, 8); - case TypeCode.UInt64: return IntToHex(value, 16); - case TypeCode.Int64: return IntToHex(value, 16); - default: - throw new FormatException("Unknown integer value type."); - } - } - - public static string IntToHex(object value, int size) - { - string result = String.Empty; - - switch (Type.GetTypeCode(value.GetType())) - { - case TypeCode.Byte: - result = "0x" + ((byte)(value)).ToString("X" + size); - break; - case TypeCode.SByte: - result = "0x" + ((sbyte)(value)).ToString("X" + size); - break; - case TypeCode.UInt16: - result = "0x" + ((ushort)(value)).ToString("X" + size); - break; - case TypeCode.Int16: - result = "0x" + ((short)(value)).ToString("X" + size); - break; - case TypeCode.UInt32: - result = "0x" + ((uint)(value)).ToString("X" + size); - break; - case TypeCode.Int32: - result = "0x" + ((int)(value)).ToString("X" + size); - break; - case TypeCode.UInt64: - result = "0x" + ((ulong)(value)).ToString("X" + size); - break; - case TypeCode.Int64: - result = "0x" + ((long)(value)).ToString("X" + size); - break; - default: - throw new FormatException("Unknown integer value type."); - } - - return result; - } - - public static string FormatNumber(object value, NumberStyle numberStyle) - { - if (!IsNumeric(value)) - throw new FormatException("Unknown numeric value type."); - - if (numberStyle == NumberStyle.Decimal) - { - return value.ToString(); - } - else - { - return IntToHex(value); - } - } - - public static string FormatNumber(object value, NumberStyle numberStyle, int size) - { - if (!IsNumeric(value)) - throw new FormatException("Unknown numeric value type."); - - string result = String.Empty; - - if (numberStyle == NumberStyle.Decimal) - { - switch (Type.GetTypeCode(value.GetType())) - { - case TypeCode.Byte: - result = ((byte)(value)).ToString("D" + size); - break; - case TypeCode.SByte: - result = ((sbyte)(value)).ToString("D" + size); - break; - case TypeCode.UInt16: - result = ((ushort)(value)).ToString("D" + size); - break; - case TypeCode.Int16: - result = ((short)(value)).ToString("D" + size); - break; - case TypeCode.UInt32: - result = ((uint)(value)).ToString("D" + size); - break; - case TypeCode.Int32: - result = ((int)(value)).ToString("D" + size); - break; - case TypeCode.UInt64: - result = ((ulong)(value)).ToString("D" + size); - break; - case TypeCode.Int64: - result = ((long)(value)).ToString("D" + size); - break; - default: - throw new FormatException("Unknown integer value type."); - } - } - else - { - result = IntToHex(value, size); - } - - return result; - } - - public static object GetDefaultValue(Type type) - { - if (type.IsValueType) - { - return Activator.CreateInstance(type); - } - else - { - return null; - } - } - - private static readonly string[] suf = { "Bytes", "KB", "MB", "GB", "TB", "PB", "EB" }; - - public static string FormatBytes(long byteCount) - { - if (byteCount == 0) - return "0 B"; - - long bytes = Math.Abs(byteCount); - int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); - double num = Math.Round(bytes / Math.Pow(1024, place), 1); - - return String.Format("{0} {1}", (Math.Sign(byteCount) * num), suf[place]); - } - - } - -} diff --git a/Src/Workshell.PE.Resources/Accelerators/AcceleratorResource.cs b/Src/Workshell.PE.Resources/Accelerators/AcceleratorResource.cs deleted file mode 100644 index 7308481..0000000 --- a/Src/Workshell.PE.Resources/Accelerators/AcceleratorResource.cs +++ /dev/null @@ -1,270 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - [Flags] - public enum AcceleratorFlags : ushort - { - [EnumAnnotation("FVIRTKEY")] - VirtualKey = 0x0001, - [EnumAnnotation("FNOINVERT")] - NoInvert = 0x0002, - [EnumAnnotation("FSHIFT")] - Shift = 0x0004, - [EnumAnnotation("FCONTROL")] - Control = 0x0008, - [EnumAnnotation("FALT")] - Alt = 0x0010, - End = 0x0080 - } - - public sealed class AcceleratorEntry - { - - private ushort flags; - private ushort key; - private ushort id; - - internal AcceleratorEntry(ushort accelFlag, ushort accelKey, ushort accelId) - { - flags = accelFlag; - key = accelKey; - id = accelId; - } - - #region Methods - - public override string ToString() - { - return String.Format("Id: {0}; Key: {1}; Flags: {2}", id, GetKey(), GetFlags()); - } - - public AcceleratorFlags GetFlags() - { - return (AcceleratorFlags)flags; - } - - public Keys GetKey() - { - return (Keys)key; - } - - #endregion - - #region Properties - - public ushort Flags - { - get - { - return flags; - } - } - - public ushort Key - { - get - { - return key; - } - } - - public ushort Id - { - get - { - return id; - } - } - - #endregion - - } - - public sealed class Accelerators : IEnumerable - { - - private AcceleratorResource resource; - private uint language_id; - private AcceleratorEntry[] accelerators; - - internal Accelerators(AcceleratorResource acceleratorResource, uint languageId, AcceleratorEntry[] acceleratorEntries) - { - resource = acceleratorResource; - language_id = languageId; - accelerators = acceleratorEntries; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < accelerators.Length; i++) - yield return accelerators[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public AcceleratorResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public int Count - { - get - { - return accelerators.Length; - } - } - - public AcceleratorEntry this[int index] - { - get - { - return accelerators[index]; - } - } - - #endregion - - } - - /* - public enum AcceleratorSaveFormat - { - Raw - } - */ - - public sealed class AcceleratorResource : Resource - { - - public AcceleratorResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_ACCELERATOR); - - return ResourceType.Register(resource_type, typeof(AcceleratorResource)); - } - - #endregion - - #region Methods - - public Accelerators Get(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - int size = Utils.SizeOf(); - long count = mem.Length / size; - - AcceleratorEntry[] accelerators = new AcceleratorEntry[count]; - - for (var i = 0; i < count; i++) - { - ACCELTABLEENTRY table_entry = Utils.Read(mem, size); - AcceleratorEntry entry = new AcceleratorEntry(table_entry.fFlags, table_entry.wAnsi, table_entry.wId); - - accelerators[i] = entry; - } - - Accelerators result = new Accelerators(this, languageId, accelerators); - - return result; - } - } - - /* - public void Save(string fileName, uint languageId, AcceleratorSaveFormat format) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, languageId, format); - file.Flush(); - } - } - - public void Save(Stream stream, uint languageId, AcceleratorSaveFormat format) - { - if (format == AcceleratorSaveFormat.Raw) - { - byte[] data = GetBytes(languageId); - - stream.Write(data, 0, data.Length); - } - } - */ - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/CharacterSet.cs b/Src/Workshell.PE.Resources/CharacterSet.cs deleted file mode 100644 index eff7e17..0000000 --- a/Src/Workshell.PE.Resources/CharacterSet.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; - -namespace Workshell.PE.Resources -{ - - public enum CharacterSet : byte - { - [EnumAnnotation("ANSI_CHARSET")] - ANSI = 0, - [EnumAnnotation("DEFAULT_CHARSET")] - Default = 0x01, - [EnumAnnotation("SYMBOL_CHARSET")] - Symbol = 0x02, - [EnumAnnotation("MAC_CHARSET")] - Mac = 0x4D, - [EnumAnnotation("SHIFTJIS_CHARSET")] - ShiftJis = 0x80, - [EnumAnnotation("HANGUL_CHARSET")] - Hangul = 0x81, - [EnumAnnotation("JOHAB_CHARSET")] - Johab = 0x82, - [EnumAnnotation("GB2312_CHARSET")] - GB2312 = 0x86, - [EnumAnnotation("CHINESEBIG5_CHARSET")] - ChineseBig5 = 0x88, - [EnumAnnotation("GREEK_CHARSET")] - Greek = 0xA1, - [EnumAnnotation("TURKISH_CHARSET")] - Turkish = 0xA2, - [EnumAnnotation("VIETNAMESE_CHARSET")] - Vietnamese = 0xA3, - [EnumAnnotation("HEBREW_CHARSET")] - Hebrew = 0xB1, - [EnumAnnotation("ARABIC_CHARSET")] - Arabic = 0xB2, - [EnumAnnotation("BALTIC_CHARSET")] - Baltic = 0xBA, - [EnumAnnotation("RUSSIAN_CHARSET")] - Russian = 0xCC, - [EnumAnnotation("THAI_CHARSET")] - Thai = 0xDE, - [EnumAnnotation("EASTEUROPE_CHARSET")] - EastEurope = 0xEE, - [EnumAnnotation("OEM_CHARSET")] - OEM = 0xFF - } - -} diff --git a/Src/Workshell.PE.Resources/Dialogs/Dialog.cs b/Src/Workshell.PE.Resources/Dialogs/Dialog.cs deleted file mode 100644 index 4dec89c..0000000 --- a/Src/Workshell.PE.Resources/Dialogs/Dialog.cs +++ /dev/null @@ -1,64 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - public sealed class Dialog - { - - internal Dialog(DialogResource dialogResource, uint languageId) - { - Resource = dialogResource; - Language = languageId; - } - - #region Properties - - public DialogResource Resource - { - get; - private set; - } - - public uint Language - { - get; - private set; - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Dialogs/DialogEx.cs b/Src/Workshell.PE.Resources/Dialogs/DialogEx.cs deleted file mode 100644 index 951879d..0000000 --- a/Src/Workshell.PE.Resources/Dialogs/DialogEx.cs +++ /dev/null @@ -1,484 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - public sealed class DialogItemEx - { - - public const ushort BUTTON = 0x0080; - public const ushort EDIT = 0x0081; - public const ushort STATIC = 0x0082; - public const ushort LISTBOX = 0x0083; - public const ushort SCROLLBAR = 0x0084; - public const ushort COMBOBOX = 0x0085; - - private uint help_id; - private uint ex_styles; - private uint styles; - private Point position; - private Size size; - private int id; - private ResourceId cls; - private ResourceId title; - private byte[] extra_data; - - internal DialogItemEx(Stream stream) - { - help_id = Utils.ReadUInt32(stream); - ex_styles = Utils.ReadUInt32(stream); - styles = Utils.ReadUInt32(stream); - - short x = Utils.ReadInt16(stream); - short y = Utils.ReadInt16(stream); - - position = new Point(x, y); - - short cx = Utils.ReadInt16(stream); - short cy = Utils.ReadInt16(stream); - - size = new Size(cx, cy); - id = Utils.ReadInt32(stream); - - string class_name = String.Empty; - ushort class_id = ResourceUtils.OrdOrSz(stream, out class_name); - - if (class_id > 0) - { - switch (class_id) - { - case BUTTON: - class_name = "BUTTON"; - break; - case EDIT: - class_name = "EDIT"; - break; - case STATIC: - class_name = "STATIC"; - break; - case LISTBOX: - class_name = "LISTBOX"; - break; - case SCROLLBAR: - class_name = "SCROLLBAR"; - break; - case COMBOBOX: - class_name = "COMBOBOX"; - break; - } - - cls = new ResourceId(class_id, class_name); - } - else - { - cls = new ResourceId(class_name); - } - - string title_name = String.Empty; - ushort title_id = ResourceUtils.OrdOrSz(stream, out title_name); - - if (title_id > 0) - { - title = new ResourceId(title_id); - } - else - { - title = new ResourceId(title_name); - } - - ushort extra_count = Utils.ReadUInt16(stream); - - if (stream.Position % 2 != 0) - Utils.ReadByte(stream); - - extra_data = new byte[extra_count]; - - if (extra_data.Length > 0) - extra_data = Utils.ReadBytes(stream, extra_count); - } - - #region Methods - - public override string ToString() - { - return String.Format("{0}, {1}, {2}", title, id, cls); - } - - public T GetControlStyle() - { - Type type = typeof(T); - - if (!type.IsEnum) - throw new Exception("Not an enum type."); - - return (T)Enum.Parse(typeof(T), styles.ToString(), true); - } - - #endregion - - #region Properties - - public uint HelpId - { - get - { - return help_id; - } - } - - public uint ExtendedStyles - { - get - { - return ex_styles; - } - } - - public uint Styles - { - get - { - return styles; - } - } - - public Point Position - { - get - { - return position; - } - } - - public Size Size - { - get - { - return size; - } - } - - public int Id - { - get - { - return id; - } - } - - public ResourceId Class - { - get - { - return cls; - } - } - - public ResourceId Title - { - get - { - return title; - } - } - - public byte[] ExtraData - { - get - { - return extra_data; - } - } - - #endregion - - } - - public sealed class DialogEx : IEnumerable - { - - private DialogResource resource; - private uint language_id; - - private uint help_id; - private uint ex_styles; - private uint styles; - private Point position; - private Size size; - private ResourceId menu; - private ResourceId cls; - private string title; - private Font font; - private CharacterSet char_set; - private DialogItemEx[] items; - - internal DialogEx(DialogResource dialogResource, uint languageId, Stream stream) - { - resource = dialogResource; - language_id = languageId; - - ushort ver = Utils.ReadUInt16(stream); - ushort sig = Utils.ReadUInt16(stream); - - help_id = Utils.ReadUInt32(stream); - ex_styles = Utils.ReadUInt32(stream); - styles = Utils.ReadUInt32(stream); - - ushort item_count = Utils.ReadUInt16(stream); - - short x = Utils.ReadInt16(stream); - short y = Utils.ReadInt16(stream); - - position = new Point(x, y); - - short cx = Utils.ReadInt16(stream); - short cy = Utils.ReadInt16(stream); - - size = new Size(cx, cy); - - string menu_name = String.Empty; - ushort menu_id = ResourceUtils.OrdOrSz(stream, out menu_name); - - if (menu_id > 0) - { - menu = menu_id; - } - else - { - menu = menu_name; - } - - string class_name = String.Empty; - ushort class_id = ResourceUtils.OrdOrSz(stream, out menu_name); - - if (class_id > 0) - { - cls = class_id; - } - else - { - cls = class_name; - } - - title = Utils.ReadUnicodeString(stream); - - DialogStyle dialog_styles = GetDialogStyles(); - - if ((dialog_styles & DialogStyle.DS_SETFONT) == DialogStyle.DS_SETFONT) - { - ushort point_size = Utils.ReadUInt16(stream); - ushort weight = Utils.ReadUInt16(stream); - byte italic = Utils.ReadByte(stream); - - char_set = (CharacterSet)Utils.ReadByte(stream); - - string type_face = Utils.ReadUnicodeString(stream); - - font = new Font(type_face, point_size); - } - else - { - font = null; - } - - items = new DialogItemEx[item_count]; - - for (var i = 0; i < item_count; i++) - { - while (stream.Position % 4 != 0) - Utils.ReadByte(stream); - - DialogItemEx item = new Resources.DialogItemEx(stream); - - items[i] = item; - } - } - - #region Methods - - public override string ToString() - { - return title; - } - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < items.Length; i++) - yield return items[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public WindowStyleEx GetExtendedWindowStyles() - { - return (WindowStyleEx)ex_styles; - } - - public WindowStyle GetWindowStyles() - { - return (WindowStyle)styles; - } - - public DialogStyle GetDialogStyles() - { - return (DialogStyle)styles; - } - - #endregion - - #region Properties - - public DialogResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public uint HelpId - { - get - { - return help_id; - } - } - - public uint ExtendedStyles - { - get - { - return ex_styles; - } - } - - public uint Styles - { - get - { - return styles; - } - } - - public Point Position - { - get - { - return position; - } - } - - public Size Size - { - get - { - return size; - } - } - - public ResourceId Menu - { - get - { - return menu; - } - } - - public ResourceId Class - { - get - { - return cls; - } - } - - public string Title - { - get - { - return title; - } - } - - public Font Font - { - get - { - return font; - } - } - - public CharacterSet CharSet - { - get - { - return char_set; - } - } - - public int ItemCount - { - get - { - return items.Length; - } - } - - public DialogItemEx this[int index] - { - get - { - return items[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Dialogs/DialogResource.cs b/Src/Workshell.PE.Resources/Dialogs/DialogResource.cs deleted file mode 100644 index ddfb1ed..0000000 --- a/Src/Workshell.PE.Resources/Dialogs/DialogResource.cs +++ /dev/null @@ -1,121 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class DialogResource : Resource - { - - public DialogResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_DIALOG); - - return ResourceType.Register(resource_type, typeof(DialogResource)); - } - - #endregion - - #region Methods - - public Dialog GetDialog(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - ushort ver = Utils.ReadUInt16(mem); - ushort sig = Utils.ReadUInt16(mem); - - bool is_extended = (ver == 1 && sig == 0xFFFF); - - mem.Seek(0, SeekOrigin.Begin); - - if (!is_extended) - { - Dialog dialog = new Dialog(this, languageId); - - return dialog; - } - else - { - return null; - } - } - } - - public DialogEx GetDialogEx(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - ushort ver = Utils.ReadUInt16(mem); - ushort sig = Utils.ReadUInt16(mem); - - bool is_extended = (ver == 1 && sig == 0xFFFF); - - mem.Seek(0, SeekOrigin.Begin); - - if (!is_extended) - { - return null; - } - else - { - DialogEx dialog = new DialogEx(this, languageId, mem); - - return dialog; - } - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Graphics/BitmapResource.cs b/Src/Workshell.PE.Resources/Graphics/BitmapResource.cs deleted file mode 100644 index 815ed18..0000000 --- a/Src/Workshell.PE.Resources/Graphics/BitmapResource.cs +++ /dev/null @@ -1,138 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Extensions; -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - public enum BitmapSaveFormat - { - Raw, - Bitmap - } - - public sealed class BitmapResource : Resource - { - - public BitmapResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_BITMAP); - - return ResourceType.Register(resource_type, typeof(BitmapResource)); - } - - #endregion - - #region Methods - - public Bitmap ToBitmap() - { - return ToBitmap(DEFAULT_LANGUAGE); - } - - public Bitmap ToBitmap(uint languageId) - { - MemoryStream mem = new MemoryStream(); - - using (mem) - { - byte[] dib = GetBytes(languageId); - MemoryStream dib_mem = new MemoryStream(dib); - - using (dib_mem) - { - BITMAPINFOHEADER header = Utils.Read(dib_mem); - BITMAPFILEHEADER file_header = new BITMAPFILEHEADER(); - - file_header.Tag = 19778; - file_header.Size = (Utils.SizeOf() + dib.Length).ToUInt32(); - file_header.Reserved1 = 0; - file_header.Reserved2 = 0; - file_header.BitmapOffset = Utils.SizeOf().ToUInt32() + header.biSize; - - Utils.Write(file_header, mem); - Utils.Write(dib, mem); - } - - mem.Seek(0, SeekOrigin.Begin); - - using (Bitmap bitmap = (Bitmap)Image.FromStream(mem)) - { - Bitmap result = new Bitmap(bitmap); // Create a copy of the image so we can release the stream - - return result; - } - } - } - - public void Save(string fileName, uint languageId, BitmapSaveFormat format) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, languageId, format); - file.Flush(); - } - } - - public void Save(Stream stream, uint languageId, BitmapSaveFormat format) - { - if (format == BitmapSaveFormat.Raw) - { - Save(stream, languageId); - } - else - { - using (Bitmap bitmap = ToBitmap(languageId)) - { - bitmap.Save(stream, ImageFormat.Bmp); - } - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Graphics/CursorGroupResource.cs b/Src/Workshell.PE.Resources/Graphics/CursorGroupResource.cs deleted file mode 100644 index 8b48056..0000000 --- a/Src/Workshell.PE.Resources/Graphics/CursorGroupResource.cs +++ /dev/null @@ -1,327 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class CursorGroupEntry - { - - internal CursorGroupEntry(CURSOR_RESDIR resDir) - { - Width = resDir.Cursor.Width; - Height = resDir.Cursor.Height; - Planes = resDir.Planes; - BitCount = resDir.BitCount; - BytesInRes = resDir.BytesInRes; - CursorId = resDir.CursorId; - } - - #region Methods - - public override string ToString() - { - return String.Format("{0}x{1} {2}-bit, ID: {3}", Width, Height, BitCount, CursorId); - } - - #endregion - - #region Properties - - public ushort Width - { - get; - private set; - } - - public ushort Height - { - get; - private set; - } - - public ushort Planes - { - get; - private set; - } - - public ushort BitCount - { - get; - private set; - } - - public uint BytesInRes - { - get; - private set; - } - - public ushort CursorId - { - get; - private set; - } - - #endregion - - } - - public sealed class CursorGroup : IEnumerable - { - - private CursorGroupResource resource; - private uint language_id; - private CursorGroupEntry[] entries; - - internal CursorGroup(CursorGroupResource cursorResource, uint languageId, CursorGroupEntry[] groupEntries) - { - resource = cursorResource; - language_id = languageId; - entries = groupEntries; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < entries.Length; i++) - yield return entries[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public CursorGroupResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public int Count - { - get - { - return entries.Length; - } - } - - public CursorGroupEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - - public enum CursorGroupSaveFormat - { - Raw, - Cursor - } - - public sealed class CursorGroupResource : Resource - { - - public CursorGroupResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_GROUP_CURSOR); - - return ResourceType.Register(resource_type, typeof(CursorGroupResource)); - } - - #endregion - - #region Methods - - public CursorGroup ToGroup() - { - return ToGroup(DEFAULT_LANGUAGE); - } - - public CursorGroup ToGroup(uint languageId) - { - byte[] data = GetBytes(languageId); - MemoryStream mem = new MemoryStream(data); - - using (mem) - { - NEWHEADER header = Utils.Read(mem); - - if (header.ResType != 2) - throw new Exception("Not a cursor group resource."); - - CursorGroupEntry[] entries = new CursorGroupEntry[header.ResCount]; - - for (var i = 0; i < header.ResCount; i++) - { - CURSOR_RESDIR cursor = Utils.Read(mem); - CursorGroupEntry entry = new CursorGroupEntry(cursor); - - entries[i] = entry; - } - - CursorGroup group = new CursorGroup(this, languageId, entries); - - return group; - } - } - - public void Save(string fileName, uint languageId, CursorGroupSaveFormat format) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, languageId, format); - file.Flush(); - } - } - - public void Save(Stream stream, uint languageId, CursorGroupSaveFormat format) - { - if (format == CursorGroupSaveFormat.Raw) - { - Save(stream, languageId); - } - else - { - CursorGroup group = ToGroup(languageId); - List> cursors = new List>(group.Count); - - for (var i = 0; i < group.Count; i++) - { - CursorGroupEntry entry = group[i]; - ResourceType res_type = Type.Resources.First(t => t.Id == ResourceType.RT_CURSOR); - Resource res = res_type.First(c => c.Id == entry.CursorId); - byte[] data = res.GetBytes(languageId); - - ushort hotspot_x = 0; - ushort hotspot_y = 0; - byte[] dib = new byte[0]; - - using (MemoryStream mem = new MemoryStream(data)) - { - hotspot_x = Utils.ReadUInt16(mem); - hotspot_y = Utils.ReadUInt16(mem); - - using (MemoryStream dib_mem = new MemoryStream()) - { - mem.CopyTo(dib_mem, 4096); - - dib = dib_mem.ToArray(); - } - } - - Tuple tuple = new Tuple(entry.CursorId, hotspot_x, hotspot_y, dib); - - cursors.Add(tuple); - } - - uint[] offsets = new uint[group.Count]; - uint offset = Convert.ToUInt32(6 + (16 * offsets.Length)); - - for (var i = 0; i < group.Count; i++) - { - CursorGroupEntry entry = group[i]; - Tuple tuple = cursors[i]; - - offsets[i] = offset; - offset += tuple.Item4.Length.ToUInt32(); - } - - Utils.Write(Convert.ToUInt16(0), stream); - Utils.Write(Convert.ToUInt16(2), stream); - Utils.Write(Convert.ToUInt16(group.Count), stream); - - for (var i = 0; i < group.Count; i++) - { - CursorGroupEntry entry = group[i]; - Tuple tuple = cursors[i]; - - Utils.Write(Convert.ToByte(entry.Width), stream); - Utils.Write(Convert.ToByte(entry.Height), stream); - Utils.Write(Convert.ToByte(entry.BitCount), stream); - Utils.Write(Convert.ToByte(0), stream); - Utils.Write(tuple.Item2, stream); - Utils.Write(tuple.Item3, stream); - Utils.Write(tuple.Item4.Length, stream); - Utils.Write(offsets[i], stream); - } - - for (var i = 0; i < group.Count; i++) - { - CursorGroupEntry entry = group[i]; - Tuple tuple = cursors[i]; - - stream.Write(tuple.Item4, 0, tuple.Item4.Length); - } - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Graphics/CursorResource.cs b/Src/Workshell.PE.Resources/Graphics/CursorResource.cs deleted file mode 100644 index 6a3e859..0000000 --- a/Src/Workshell.PE.Resources/Graphics/CursorResource.cs +++ /dev/null @@ -1,476 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class CursorInfo - { - - internal CursorInfo(CursorResource cursor, uint languageId, ushort hotspotX, ushort hotspotY, ushort width, ushort height, byte colors, byte[] dib, bool isPNG) - { - Cursor = cursor; - Language = languageId; - Hotspot = new Point(hotspotX, hotspotY); - Size = new Size(width, height); - Colors = colors; - DIB = dib; - IsPNG = isPNG; - } - - #region Properties - - public CursorResource Cursor - { - get; - private set; - } - - public uint Language - { - get; - private set; - } - - public Point Hotspot - { - get; - private set; - } - - public Size Size - { - get; - private set; - } - - public byte Colors - { - get; - private set; - } - - public byte[] DIB - { - get; - private set; - } - - public bool IsPNG - { - get; - private set; - } - - #endregion - - } - - public enum CursorSaveFormat - { - Raw, - Cursor, - Icon, - Bitmap, - PNG - } - - public class CursorResource : Resource - { - - public CursorResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_CURSOR); - - return ResourceType.Register(resource_type, typeof(CursorResource)); - } - - #endregion - - #region Methods - - public CursorInfo GetInfo() - { - return GetInfo(DEFAULT_LANGUAGE); - } - - public CursorInfo GetInfo(uint languageId) - { - Tuple tuple = Load(languageId); - CursorInfo result = new CursorInfo(this, languageId, tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5, tuple.Item6, tuple.Item7); - - return result; - } - - public Icon ToIcon() - { - return ToIcon(DEFAULT_LANGUAGE); - } - - public Icon ToIcon(uint languageId) - { - /* - Tuple tuple = Load(languageId); - - using (MemoryStream dib_mem = new MemoryStream(tuple.Item3)) - { - BITMAPINFOHEADER header = Utils.Read(dib_mem); - - ushort width = Convert.ToUInt16(header.biWidth); - ushort height = Convert.ToUInt16(header.biHeight / 2); - byte color_count = Convert.ToByte(header.biBitCount); - - MemoryStream mem = new MemoryStream(); - - using (mem) - { - Utils.Write(Convert.ToUInt16(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(1), mem); - - uint colors = 0; - - if (color_count != 0 && color_count < 8) - colors = Convert.ToUInt32(Math.Pow(2, color_count)); - - Utils.Write(Convert.ToByte(width >= 256 ? 0 : width), mem); - Utils.Write(Convert.ToByte(height >= 256 ? 0 : height), mem); - Utils.Write(Convert.ToByte(colors), mem); - Utils.Write(Convert.ToByte(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(color_count), mem); - Utils.Write(tuple.Item3.Length, mem); - Utils.Write(22, mem); - - Utils.Write(tuple.Item3, mem); - - mem.Seek(0, SeekOrigin.Begin); - - Icon icon = new Icon(mem); - - return icon; - } - } - */ - - Tuple tuple = Load(languageId); - - if (!tuple.Item7) - { - using (MemoryStream dib_mem = new MemoryStream(tuple.Item6)) - { - BITMAPINFOHEADER header = Utils.Read(dib_mem); - - ushort width = Convert.ToUInt16(header.biWidth); - ushort height = Convert.ToUInt16(header.biHeight / 2); - byte color_count = Convert.ToByte(header.biBitCount); - - MemoryStream mem = new MemoryStream(); - - using (mem) - { - Utils.Write(Convert.ToUInt16(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(1), mem); - - ulong colors = Convert.ToUInt64(Math.Pow(2, color_count)); - - if (colors >= 256) - colors = 0; - - Utils.Write(Convert.ToByte(width >= 256 ? 0 : width), mem); - Utils.Write(Convert.ToByte(height >= 256 ? 0 : height), mem); - Utils.Write(Convert.ToByte(colors), mem); - Utils.Write(Convert.ToByte(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(color_count), mem); - Utils.Write(tuple.Item6.Length, mem); - Utils.Write(22, mem); - - Utils.Write(tuple.Item6, mem); - - mem.Seek(0, SeekOrigin.Begin); - - Icon icon = new Icon(mem); - - return icon; - } - } - } - else - { - using (MemoryStream dib_mem = new MemoryStream(tuple.Item6)) - { - using (Image png = Image.FromStream(dib_mem)) - { - ushort width = Convert.ToUInt16(png.Width); - ushort height = Convert.ToUInt16(png.Height); - byte color_count = 32; - - MemoryStream mem = new MemoryStream(); - - using (mem) - { - Utils.Write(Convert.ToUInt16(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(1), mem); - - Utils.Write(Convert.ToByte(width >= 256 ? 0 : width), mem); - Utils.Write(Convert.ToByte(height >= 256 ? 0 : height), mem); - Utils.Write(Convert.ToByte(0), mem); // 32-bit (16m colors) so 0 - Utils.Write(Convert.ToByte(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(color_count), mem); - Utils.Write(tuple.Item6.Length, mem); - Utils.Write(22, mem); - - Utils.Write(tuple.Item6, mem); - - mem.Seek(0, SeekOrigin.Begin); - - Icon icon = new Icon(mem); - - return icon; - } - } - } - } - } - - public Bitmap ToBitmap() - { - return ToBitmap(Color.Transparent); - } - - public Bitmap ToBitmap(Color backgroundColor) - { - return ToBitmap(DEFAULT_LANGUAGE, Color.Transparent); - } - - public Bitmap ToBitmap(uint languageId) - { - return ToBitmap(languageId, Color.Transparent); - } - - public Bitmap ToBitmap(uint languageId, Color backgroundColor) - { - using (Icon icon = ToIcon(languageId)) - { - Rectangle rect = new Rectangle(0, 0, icon.Width, icon.Height); - Bitmap bitmap = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); - - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - using (SolidBrush brush = new SolidBrush(backgroundColor)) - graphics.FillRectangle(brush, rect); - - graphics.DrawIcon(icon, rect); - } - - bitmap.MakeTransparent(backgroundColor); - - return bitmap; - } - } - - public void Save(string fileName, uint languageId, CursorSaveFormat format) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, languageId, format); - file.Flush(); - } - } - - public void Save(Stream stream, uint languageId, CursorSaveFormat format) - { - switch (format) - { - case CursorSaveFormat.Raw: - Save(stream, languageId); - break; - case CursorSaveFormat.Icon: - { - using (Icon icon = ToIcon(languageId)) - { - icon.Save(stream); - } - - break; - } - case CursorSaveFormat.Bitmap: - { - using (Bitmap bitmap = ToBitmap(languageId)) - { - bitmap.Save(stream, ImageFormat.Bmp); - } - - break; - } - case CursorSaveFormat.PNG: - { - Tuple tuple = Load(languageId); - - if (!tuple.Item7) - { - using (Bitmap bitmap = ToBitmap(languageId)) - { - bitmap.Save(stream, ImageFormat.Png); - } - } - else - { - stream.Write(tuple.Item6, 0, tuple.Item6.Length); - } - - break; - } - case CursorSaveFormat.Cursor: - default: - { - Tuple tuple = Load(languageId); - MemoryStream mem = new MemoryStream(tuple.Item6); - - using (mem) - { - BITMAPINFOHEADER header = Utils.Read(mem); - - Utils.Write(Convert.ToUInt16(0), stream); - Utils.Write(Convert.ToUInt16(2), stream); - Utils.Write(Convert.ToUInt16(1), stream); - - Utils.Write(Convert.ToByte(header.biWidth), stream); - Utils.Write(Convert.ToByte(header.biHeight), stream); - Utils.Write(Convert.ToByte(0), stream); - Utils.Write(Convert.ToByte(0), stream); - Utils.Write(tuple.Item1, stream); - Utils.Write(tuple.Item2, stream); - Utils.Write(tuple.Item6.Length, stream); - Utils.Write(22, stream); - - Utils.Write(tuple.Item6, stream); - } - - break; - } - } - } - - private Tuple Load(uint languageId) - { - /* - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - ushort hotspot_x = Utils.ReadUInt16(mem); - ushort hotspot_y = Utils.ReadUInt16(mem); - byte[] dib; - - using (MemoryStream dib_mem = new MemoryStream(data.Length - (sizeof(ushort) * 2))) - { - mem.CopyTo(dib_mem, 4096); - - dib = dib_mem.ToArray(); - } - - Tuple tuple = new Tuple(hotspot_x, hotspot_y, dib); - - return tuple; - } - */ - - byte[] data = GetBytes(languageId); - ushort hotspot_x; - ushort hotspot_y; - ushort width; - ushort height; - byte color_count; - byte[] dib; - bool is_png; - - using (MemoryStream mem = new MemoryStream(data)) - { - hotspot_x = Utils.ReadUInt16(mem); - hotspot_y = Utils.ReadUInt16(mem); - - using (MemoryStream dib_mem = new MemoryStream(data.Length)) - { - mem.CopyTo(dib_mem, 4096); - dib_mem.Seek(0, SeekOrigin.Begin); - - dib = dib_mem.ToArray(); - - if (!GraphicResources.IsPNG(dib)) - { - BITMAPINFOHEADER header = Utils.Read(dib_mem); - - width = Convert.ToUInt16(header.biWidth); - height = Convert.ToUInt16(header.biHeight / 2); - color_count = Convert.ToByte(header.biBitCount); - is_png = false; - } - else - { - using (Image png = Image.FromStream(dib_mem)) - { - width = Convert.ToUInt16(png.Width); - height = Convert.ToUInt16(png.Height); - color_count = 32; - is_png = true; - } - } - } - } - - Tuple tuple = new Tuple(hotspot_x, hotspot_y, width, height, color_count, dib, is_png); - - return tuple; - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Graphics/GraphicResources.cs b/Src/Workshell.PE.Resources/Graphics/GraphicResources.cs deleted file mode 100644 index 5d757cc..0000000 --- a/Src/Workshell.PE.Resources/Graphics/GraphicResources.cs +++ /dev/null @@ -1,114 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - [Serializable] - public class GraphicResourcesException : Exception - { - - public GraphicResourcesException() : base() - { - } - - public GraphicResourcesException(string message) : base(message) - { - } - - public GraphicResourcesException(string message, Exception innerException) : base(message, innerException) - { - } - - protected GraphicResourcesException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - } - - public static class GraphicResources - { - - #region Methods - - public static void Register() - { - Register(false); - } - - public static void Register(bool throwOnFail) - { - if (!BitmapResource.Register() && throwOnFail) - throw new GraphicResourcesException("Could not register BitmapResource, already registered."); - - if (!CursorGroupResource.Register() && throwOnFail) - throw new GraphicResourcesException("Could not register CursorGroupResource, already registered."); - - if (!CursorResource.Register() && throwOnFail) - throw new GraphicResourcesException("Could not register CursorResource, already registered."); - - if (!IconGroupResource.Register() && throwOnFail) - throw new GraphicResourcesException("Could not register IconGroupResource, already registered."); - - if (!IconResource.Register() && throwOnFail) - throw new GraphicResourcesException("Could not register IconResource, already registered."); - } - - public static bool IsPNG(byte[] data) - { - if (data.Length < 8) - return false; - - ulong signature = BitConverter.ToUInt64(data, 0); - - return (signature == 727905341920923785L); - } - - public static bool IsPNG(Stream stream) - { - byte[] buffer = new byte[sizeof(ulong)]; - int num_read = stream.Read(buffer, 0, buffer.Length); - - if (num_read < sizeof(ulong)) - return false; - - return IsPNG(buffer); - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Graphics/IconGroupResource.cs b/Src/Workshell.PE.Resources/Graphics/IconGroupResource.cs deleted file mode 100644 index 96fa1a8..0000000 --- a/Src/Workshell.PE.Resources/Graphics/IconGroupResource.cs +++ /dev/null @@ -1,313 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class IconGroupEntry - { - - internal IconGroupEntry(ICON_RESDIR resDir) - { - Width = resDir.Icon.Width; - Height = resDir.Icon.Height; - ColorCount = resDir.Icon.ColorCount; - Planes = resDir.Planes; - BitCount = resDir.BitCount; - BytesInRes = resDir.BytesInRes; - IconId = resDir.IconId; - - if (Width == 0) - Width = 256; - - if (Height == 0) - Height = 256; - } - - #region Methods - - public override string ToString() - { - return String.Format("{0}x{1} {2}-bit, ID: {3}", Width, Height, BitCount, IconId); - } - - #endregion - - #region Properties - - public ushort Width - { - get; - private set; - } - - public ushort Height - { - get; - private set; - } - - public byte ColorCount - { - get; - private set; - } - - public ushort Planes - { - get; - private set; - } - - public ushort BitCount - { - get; - private set; - } - - public uint BytesInRes - { - get; - private set; - } - - public ushort IconId - { - get; - private set; - } - - #endregion - - } - - public sealed class IconGroup : IEnumerable - { - - private IconGroupResource resource; - private uint language_id; - private IconGroupEntry[] entries; - - internal IconGroup(IconGroupResource groupResource, uint languageId, IconGroupEntry[] groupEntries) - { - resource = groupResource; - language_id = languageId; - entries = groupEntries; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < entries.Length; i++) - yield return entries[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public IconGroupResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public int Count - { - get - { - return entries.Length; - } - } - - public IconGroupEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - - public enum IconGroupSaveFormat - { - Raw, - Icon - } - - public sealed class IconGroupResource : Resource - { - - public IconGroupResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_GROUP_ICON); - - return ResourceType.Register(resource_type, typeof(IconGroupResource)); - } - - #endregion - - #region Methods - - public IconGroup ToGroup() - { - return ToGroup(DEFAULT_LANGUAGE); - } - - public IconGroup ToGroup(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - NEWHEADER header = Utils.Read(mem); - - if (header.ResType != 1) - throw new Exception("Not an icon group resource."); - - IconGroupEntry[] entries = new IconGroupEntry[header.ResCount]; - - for (var i = 0; i < header.ResCount; i++) - { - ICON_RESDIR icon = Utils.Read(mem); - IconGroupEntry entry = new IconGroupEntry(icon); - - entries[i] = entry; - } - - IconGroup group = new IconGroup(this, languageId, entries); - - return group; - } - } - - public void Save(string fileName, uint languageId, IconGroupSaveFormat format) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, languageId, format); - file.Flush(); - } - } - - public void Save(Stream stream, uint languageId, IconGroupSaveFormat format) - { - if (format == IconGroupSaveFormat.Raw) - { - Save(stream, languageId); - } - else - { - IconGroup group = ToGroup(languageId); - uint[] offsets = new uint[group.Count]; - uint offset = Convert.ToUInt32(6 + (16 * offsets.Length)); - - for (var i = 0; i < group.Count; i++) - { - IconGroupEntry entry = group[i]; - offsets[i] = offset; - - offset += entry.BytesInRes; - } - - Utils.Write(Convert.ToUInt16(0), stream); - Utils.Write(Convert.ToUInt16(1), stream); - Utils.Write(Convert.ToUInt16(group.Count), stream); - - for (var i = 0; i < group.Count; i++) - { - IconGroupEntry entry = group[i]; - - ulong color_count = Convert.ToUInt64(Math.Pow(2, entry.BitCount)); - - if (color_count >= 256) - color_count = 0; - - Utils.Write(Convert.ToByte(entry.Width >= 256 ? 0 : entry.Width), stream); - Utils.Write(Convert.ToByte(entry.Height >= 256 ? 0 : entry.Height), stream); - Utils.Write(Convert.ToByte(color_count), stream); - Utils.Write(Convert.ToByte(0), stream); - Utils.Write(Convert.ToUInt16(1), stream); - Utils.Write(entry.BitCount, stream); - Utils.Write(entry.BytesInRes, stream); - Utils.Write(offsets[i], stream); - } - - ResourceType icon_type = Type.Resources.First(t => t.Id == ResourceType.RT_ICON); - - for (var i = 0; i < group.Count; i++) - { - IconGroupEntry entry = group[i]; - Resource resource = icon_type.First(r => r.Id == entry.IconId); - byte[] data = resource.GetBytes(languageId); - - Utils.Write(data, stream); - } - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Graphics/IconResource.cs b/Src/Workshell.PE.Resources/Graphics/IconResource.cs deleted file mode 100644 index cf253a1..0000000 --- a/Src/Workshell.PE.Resources/Graphics/IconResource.cs +++ /dev/null @@ -1,383 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class IconInfo - { - - internal IconInfo(IconResource resource, uint languageId, ushort width, ushort height, byte colors, byte[] dib, bool isPNG) - { - Icon = resource; - Language = languageId; - Size = new Size(width, height); - Colors = colors; - DIB = dib; - IsPNG = isPNG; - } - - #region Properties - - public IconResource Icon - { - get; - private set; - } - - public uint Language - { - get; - private set; - } - - public Size Size - { - get; - private set; - } - - public byte Colors - { - get; - private set; - } - - public byte[] DIB - { - get; - private set; - } - - public bool IsPNG - { - get; - private set; - } - - #endregion - - } - - public enum IconSaveFormat - { - Raw, - Icon, - Bitmap, - PNG - } - - public class IconResource : Resource - { - - public IconResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_ICON); - - return ResourceType.Register(resource_type, typeof(IconResource)); - } - - #endregion - - #region Methods - - public IconInfo GetInfo() - { - return GetInfo(DEFAULT_LANGUAGE); - } - - public IconInfo GetInfo(uint languageId) - { - Tuple tuple = Load(languageId); - IconInfo result = new IconInfo(this, languageId, tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5); - - return result; - } - - public Icon ToIcon() - { - return ToIcon(DEFAULT_LANGUAGE); - } - - public Icon ToIcon(uint languageId) - { - Tuple tuple = Load(languageId); - - if (!tuple.Item5) - { - using (MemoryStream dib_mem = new MemoryStream(tuple.Item4)) - { - BITMAPINFOHEADER header = Utils.Read(dib_mem); - - ushort width = Convert.ToUInt16(header.biWidth); - ushort height = Convert.ToUInt16(header.biHeight / 2); - byte color_count = Convert.ToByte(header.biBitCount); - - MemoryStream mem = new MemoryStream(); - - using (mem) - { - Utils.Write(Convert.ToUInt16(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(1), mem); - - ulong colors = Convert.ToUInt64(Math.Pow(2, color_count)); - - if (colors >= 256) - colors = 0; - - Utils.Write(Convert.ToByte(width >= 256 ? 0 : width), mem); - Utils.Write(Convert.ToByte(height >= 256 ? 0 : height), mem); - Utils.Write(Convert.ToByte(colors), mem); - Utils.Write(Convert.ToByte(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(color_count), mem); - Utils.Write(tuple.Item4.Length, mem); - Utils.Write(22, mem); - - Utils.Write(tuple.Item4, mem); - - mem.Seek(0, SeekOrigin.Begin); - - Icon icon = new Icon(mem); - - return icon; - } - } - } - else - { - using (MemoryStream dib_mem = new MemoryStream(tuple.Item4)) - { - using (Image png = Image.FromStream(dib_mem)) - { - ushort width = Convert.ToUInt16(png.Width); - ushort height = Convert.ToUInt16(png.Height); - byte color_count = 32; - - MemoryStream mem = new MemoryStream(); - - using (mem) - { - Utils.Write(Convert.ToUInt16(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(1), mem); - - Utils.Write(Convert.ToByte(width >= 256 ? 0 : width), mem); - Utils.Write(Convert.ToByte(height >= 256 ? 0 : height), mem); - Utils.Write(Convert.ToByte(0), mem); // 32-bit (16m colors) so 0 - Utils.Write(Convert.ToByte(0), mem); - Utils.Write(Convert.ToUInt16(1), mem); - Utils.Write(Convert.ToUInt16(color_count), mem); - Utils.Write(tuple.Item4.Length, mem); - Utils.Write(22, mem); - - Utils.Write(tuple.Item4, mem); - - mem.Seek(0, SeekOrigin.Begin); - - Icon icon = new Icon(mem); - - return icon; - } - } - } - } - } - - public Bitmap ToBitmap() - { - return ToBitmap(Color.Transparent); - } - - public Bitmap ToBitmap(Color backgroundColor) - { - return ToBitmap(DEFAULT_LANGUAGE, Color.Transparent); - } - - public Bitmap ToBitmap(uint languageId) - { - return ToBitmap(languageId, Color.Transparent); - } - - public Bitmap ToBitmap(uint languageId, Color backgroundColor) - { - Tuple tuple = Load(languageId); - - if (!tuple.Item5) - { - using (Icon icon = ToIcon(languageId)) - { - Rectangle rect = new Rectangle(0, 0, icon.Width, icon.Height); - Bitmap bitmap = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); - - using (Graphics graphics = Graphics.FromImage(bitmap)) - { - - using (SolidBrush brush = new SolidBrush(backgroundColor)) - graphics.FillRectangle(brush, rect); - - graphics.DrawIcon(icon, rect); - } - - bitmap.MakeTransparent(backgroundColor); - - return bitmap; - } - } - else - { - using (MemoryStream dib_mem = new MemoryStream(tuple.Item4)) - { - using (Image png = Image.FromStream(dib_mem)) - { - Bitmap bitmap = new Bitmap(png); - - return bitmap; - } - } - } - } - - public void Save(string fileName, uint languageId, IconSaveFormat format) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, languageId, format); - file.Flush(); - } - } - - public void Save(Stream stream, uint languageId, IconSaveFormat format) - { - switch (format) - { - case IconSaveFormat.Raw: - Save(stream, languageId); - break; - case IconSaveFormat.Icon: - default: - { - using (Icon icon = ToIcon(languageId)) - { - icon.Save(stream); - } - - break; - } - case IconSaveFormat.Bitmap: - { - using (Bitmap bitmap = ToBitmap(languageId)) - { - bitmap.Save(stream, ImageFormat.Bmp); - } - - break; - } - case IconSaveFormat.PNG: - { - Tuple tuple = Load(languageId); - - if (!tuple.Item5) - { - using (Bitmap bitmap = ToBitmap(languageId)) - { - bitmap.Save(stream, ImageFormat.Png); - } - } - else - { - stream.Write(tuple.Item4, 0, tuple.Item4.Length); - } - - break; - } - } - } - - private Tuple Load(uint languageId) - { - byte[] data = GetBytes(languageId); - ushort width; - ushort height; - byte color_count; - byte[] dib; - bool is_png; - - using (MemoryStream mem = new MemoryStream(data)) - { - if (!GraphicResources.IsPNG(data)) - { - BITMAPINFOHEADER header = Utils.Read(mem); - - width = Convert.ToUInt16(header.biWidth); - height = Convert.ToUInt16(header.biHeight / 2); - color_count = Convert.ToByte(header.biBitCount); - dib = mem.ToArray(); - is_png = false; - } - else - { - using (Image png = Image.FromStream(mem)) - { - width = Convert.ToUInt16(png.Width); - height = Convert.ToUInt16(png.Height); - color_count = 32; - dib = mem.ToArray(); - is_png = true; - } - } - } - - Tuple tuple = new Tuple(width, height, color_count, dib, is_png); - - return tuple; - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/LanguageIdentifiers.cs b/Src/Workshell.PE.Resources/LanguageIdentifiers.cs deleted file mode 100644 index 20d1268..0000000 --- a/Src/Workshell.PE.Resources/LanguageIdentifiers.cs +++ /dev/null @@ -1,182 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - public sealed class LanguageIdentifiers - { - - public const byte LANG_NEUTRAL = 0x00; - public const byte LANG_INVARIANT = 0x7f; - public const byte LANG_AFRIKAANS = 0x36; - public const byte LANG_ALBANIAN = 0x1c; - public const byte LANG_ARABIC = 0x01; - public const byte LANG_BASQUE = 0x2d; - public const byte LANG_BELARUSIAN = 0x23; - public const byte LANG_BULGARIAN = 0x02; - public const byte LANG_CATALAN = 0x03; - public const byte LANG_CHINESE = 0x04; - public const byte LANG_CROATIAN = 0x1a; - public const byte LANG_CZECH = 0x05; - public const byte LANG_DANISH = 0x06; - public const byte LANG_DUTCH = 0x13; - public const byte LANG_ENGLISH = 0x09; - public const byte LANG_ESTONIAN = 0x25; - public const byte LANG_FAEROESE = 0x38; - public const byte LANG_FARSI = 0x29; - public const byte LANG_FINNISH = 0x0b; - public const byte LANG_FRENCH = 0x0c; - public const byte LANG_GERMAN = 0x07; - public const byte LANG_GREEK = 0x08; - public const byte LANG_HEBREW = 0x0d; - public const byte LANG_HUNGARIAN = 0x0e; - public const byte LANG_ICELANDIC = 0x0f; - public const byte LANG_INDONESIAN = 0x21; - public const byte LANG_ITALIAN = 0x10; - public const byte LANG_JAPANESE = 0x11; - public const byte LANG_KOREAN = 0x12; - public const byte LANG_LATVIAN = 0x26; - public const byte LANG_LITHUANIAN = 0x27; - public const byte LANG_NORWEGIAN = 0x14; - public const byte LANG_POLISH = 0x15; - public const byte LANG_PORTUGUESE = 0x16; - public const byte LANG_ROMANIAN = 0x18; - public const byte LANG_RUSSIAN = 0x19; - public const byte LANG_SERBIAN = 0x1a; - public const byte LANG_SLOVAK = 0x1b; - public const byte LANG_SLOVENIAN = 0x24; - public const byte LANG_SPANISH = 0x0a; - public const byte LANG_SWEDISH = 0x1d; - public const byte LANG_THAI = 0x1e; - public const byte LANG_TURKISH = 0x1f; - public const byte LANG_UKRAINIAN = 0x22; - public const byte LANG_VIETNAMESE = 0x2a; - - public const byte SUBLANG_NEUTRAL = 0x00; // language neutral - public const byte SUBLANG_DEFAULT = 0x01; // user default - public const byte SUBLANG_SYS_DEFAULT = 0x02; // system default - public const byte SUBLANG_CUSTOM_UNSPECIFIED = 0x04; // custom language/locale - public const byte SUBLANG_UI_CUSTOM_DEFAULT = 0x05; // Default custom MUI language/locale - - public const byte SUBLANG_ARABIC_SAUDI_ARABIA = 0x01; // Arabic (Saudi Arabia) - public const byte SUBLANG_ARABIC_IRAQ = 0x02; // Arabic (Iraq) - public const byte SUBLANG_ARABIC_EGYPT = 0x03; // Arabic (Egypt) - public const byte SUBLANG_ARABIC_LIBYA = 0x04; // Arabic (Libya) - public const byte SUBLANG_ARABIC_ALGERIA = 0x05; // Arabic (Algeria) - public const byte SUBLANG_ARABIC_MOROCCO = 0x06; // Arabic (Morocco) - public const byte SUBLANG_ARABIC_TUNISIA = 0x07; // Arabic (Tunisia) - public const byte SUBLANG_ARABIC_OMAN = 0x08; // Arabic (Oman) - public const byte SUBLANG_ARABIC_YEMEN = 0x09; // Arabic (Yemen) - public const byte SUBLANG_ARABIC_SYRIA = 0x0a; // Arabic (Syria) - public const byte SUBLANG_ARABIC_JORDAN = 0x0b; // Arabic (Jordan) - public const byte SUBLANG_ARABIC_LEBANON = 0x0c; // Arabic (Lebanon) - public const byte SUBLANG_ARABIC_KUWAIT = 0x0d; // Arabic (Kuwait) - public const byte SUBLANG_ARABIC_UAE = 0x0e; // Arabic (U.A.E) - public const byte SUBLANG_ARABIC_BAHRAIN = 0x0f; // Arabic (Bahrain) - public const byte SUBLANG_ARABIC_QATAR = 0x10; // Arabic (Qatar) - - public const byte SUBLANG_CHINESE_TRADITIONAL = 0x01; // Chinese (Taiwan) - public const byte SUBLANG_CHINESE_SIMPLIFIED = 0x02; // Chinese (PR China) - public const byte SUBLANG_CHINESE_HONGKONG = 0x03; // Chinese (Hong Kong) - public const byte SUBLANG_CHINESE_SINGAPORE = 0x04; // Chinese (Singapore) - - public const byte SUBLANG_DUTCH = 0x01; // Dutch - public const byte SUBLANG_DUTCH_BELGIAN = 0x02; // Dutch (Belgian) - - public const byte SUBLANG_ENGLISH_US = 0x01; // English (USA) - public const byte SUBLANG_ENGLISH_UK = 0x02; // English (UK) - public const byte SUBLANG_ENGLISH_AUS = 0x03; // English (Australian) - public const byte SUBLANG_ENGLISH_CAN = 0x04; // English (Canadian) - public const byte SUBLANG_ENGLISH_NZ = 0x05; // English (New Zealand) - public const byte SUBLANG_ENGLISH_EIRE = 0x06; // English (Irish) - public const byte SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07; // English (South Africa) - public const byte SUBLANG_ENGLISH_JAMAICA = 0x08; // English (Jamaica) - public const byte SUBLANG_ENGLISH_CARIBBEAN = 0x09; // English (Caribbean) - public const byte SUBLANG_ENGLISH_BELIZE = 0x0a; // English (Belize) - public const byte SUBLANG_ENGLISH_TRINIDAD = 0x0b; // English (Trinidad) - - public const byte SUBLANG_FRENCH = 0x01; // French - public const byte SUBLANG_FRENCH_BELGIAN = 0x02; // French (Belgian) - public const byte SUBLANG_FRENCH_CANADIAN = 0x03; // French (Canadian) - public const byte SUBLANG_FRENCH_SWISS = 0x04; // French (Swiss) - public const byte SUBLANG_FRENCH_LUXEMBOURG = 0x05; // French (Luxembourg) - - public const byte SUBLANG_GERMAN = 0x01; // German - public const byte SUBLANG_GERMAN_SWISS = 0x02; // German (Swiss) - public const byte SUBLANG_GERMAN_AUSTRIAN = 0x03; // German (Austrian) - public const byte SUBLANG_GERMAN_LUXEMBOURG = 0x04; // German (Luxembourg) - public const byte SUBLANG_GERMAN_LIECHTENSTEIN = 0x05; // German (Liechtenstein) - - public const byte SUBLANG_ITALIAN = 0x01; // Italian - public const byte SUBLANG_ITALIAN_SWISS = 0x02; // Italian (Swiss) - - public const byte SUBLANG_KOREAN = 0x01; // Korean (Extended Wansung) - public const byte SUBLANG_KOREAN_JOHAB = 0x02; // Korean (Johab) - - public const byte SUBLANG_NORWEGIAN_BOKMAL = 0x01; // Norwegian (Bokmal) - public const byte SUBLANG_NORWEGIAN_NYNORSK = 0x02; // Norwegian (Nynorsk) - - public const byte SUBLANG_PORTUGUESE = 0x02; // Portuguese - public const byte SUBLANG_PORTUGUESE_BRAZILIAN = 0x01; // Portuguese (Brazilian) - - public const byte SUBLANG_SERBIAN_LATIN = 0x02; // Serbian (Latin) - public const byte SUBLANG_SERBIAN_CYRILLIC = 0x03; // Serbian (Cyrillic) - - public const byte SUBLANG_SPANISH = 0x01; // Spanish (Castilian) - public const byte SUBLANG_SPANISH_MEXICAN = 0x02; // Spanish (Mexican) - public const byte SUBLANG_SPANISH_MODERN = 0x03; // Spanish (Modern) - public const byte SUBLANG_SPANISH_GUATEMALA = 0x04; // Spanish (Guatemala) - public const byte SUBLANG_SPANISH_COSTA_RICA = 0x05; // Spanish (Costa Rica) - public const byte SUBLANG_SPANISH_PANAMA = 0x06; // Spanish (Panama) - public const byte SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07; // Spanish (Dominican Republic) - public const byte SUBLANG_SPANISH_VENEZUELA = 0x08; // Spanish (Venezuela) - public const byte SUBLANG_SPANISH_COLOMBIA = 0x09; // Spanish (Colombia) - public const byte SUBLANG_SPANISH_PERU = 0x0a; // Spanish (Peru) - public const byte SUBLANG_SPANISH_ARGENTINA = 0x0b; // Spanish (Argentina) - public const byte SUBLANG_SPANISH_ECUADOR = 0x0c; // Spanish (Ecuador) - public const byte SUBLANG_SPANISH_CHILE = 0x0d; // Spanish (Chile) - public const byte SUBLANG_SPANISH_URUGUAY = 0x0e; // Spanish (Uruguay) - public const byte SUBLANG_SPANISH_PARAGUAY = 0x0f; // Spanish (Paraguay) - public const byte SUBLANG_SPANISH_BOLIVIA = 0x10; // Spanish (Bolivia) - public const byte SUBLANG_SPANISH_EL_SALVADOR = 0x11; // Spanish (El Salvador) - public const byte SUBLANG_SPANISH_HONDURAS = 0x12; // Spanish (Honduras) - public const byte SUBLANG_SPANISH_NICARAGUA = 0x13; // Spanish (Nicaragua) - public const byte SUBLANG_SPANISH_PUERTO_RICO = 0x14; // Spanish (Puerto Rico) - - public const byte SUBLANG_SWEDISH = 0x01; // Swedish - public const byte SUBLANG_SWEDISH_FINLAND = 0x02; // Swedish (Finland) - - } - -} diff --git a/Src/Workshell.PE.Resources/LocaleIdentifiers.cs b/Src/Workshell.PE.Resources/LocaleIdentifiers.cs deleted file mode 100644 index cc3fe85..0000000 --- a/Src/Workshell.PE.Resources/LocaleIdentifiers.cs +++ /dev/null @@ -1,272 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - public sealed class LocaleIdentifiers - { - - public const ushort SUBLANG_CUSTOM_DEFAULT = 0x0C00; - public const ushort SUBLANG_UI_CUSTOM_DEFAULT = 0x1400; - public const ushort SUBLANG_NEUTRAL_INVARIANT = 0x007F; - public const ushort SUBLANG_NEUTRAL = 0x0000; - public const ushort SUBLANG_SYS_DEFAULT = 0x0800; - public const ushort SUBLANG_CUSTOM_UNSPECIFIED = 0x1000; - public const ushort SUBLANG_DEFAULT = 0x0400; - - public const ushort SUBLANG_AFRIKAANS_SOUTH_AFRICA = 0x0436; - public const ushort SUBLANG_ALBANIAN_ALBANIA = 0x041C; - public const ushort SUBLANG_ALSATIAN_FRANCE = 0x0484; - public const ushort SUBLANG_AMHARIC_ETHIOPIA = 0x045E; - public const ushort SUBLANG_ARABIC_ALGERIA = 0x1401; - public const ushort SUBLANG_ARABIC_BAHRAIN = 0x3C01; - public const ushort SUBLANG_ARABIC_EGYPT = 0x0C01; - public const ushort SUBLANG_ARABIC_IRAQ = 0x0801; - public const ushort SUBLANG_ARABIC_JORDAN = 0x2C01; - public const ushort SUBLANG_ARABIC_KUWAIT = 0x3401; - public const ushort SUBLANG_ARABIC_LEBANON = 0x3001; - public const ushort SUBLANG_ARABIC_LIBYA = 0x1001; - public const ushort SUBLANG_ARABIC_MOROCCO = 0x1801; - public const ushort SUBLANG_ARABIC_OMAN = 0x2001; - public const ushort SUBLANG_ARABIC_QATAR = 0x4001; - public const ushort SUBLANG_ARABIC_SAUDI_ARABIA = 0x0401; - public const ushort SUBLANG_ARABIC_SYRIA = 0x2801; - public const ushort SUBLANG_ARABIC_TUNISIA = 0x1C01; - public const ushort SUBLANG_ARABIC_UAE = 0x3801; - public const ushort SUBLANG_ARABIC_YEMEN = 0x2401; - public const ushort SUBLANG_ARMENIAN_ARMENIA = 0x042B; - public const ushort SUBLANG_ASSAMESE_INDIA = 0x044D; - public const ushort SUBLANG_AZERI_CYRILLIC = 0x082C; - public const ushort SUBLANG_AZERI_LATIN = 0x042C; - public const ushort SUBLANG_BANGLA_BANGLADESH = 0x0445; - public const ushort SUBLANG_BASHKIR_RUSSIA = 0x046D; - public const ushort SUBLANG_BASQUE_BASQUE = 0x042D; - public const ushort SUBLANG_BELARUSIAN_BELARUS = 0x0423; - public const ushort SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x201A; - public const ushort SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN = 0x141A; - public const ushort SUBLANG_BRETON_FRANCE = 0x047E; - public const ushort SUBLANG_BULGARIAN_BULGARIA = 0x0402; - public const ushort SUBLANG_CENTRAL_KURDISH_IRAQ = 0x0492; - public const ushort SUBLANG_CHEROKEE_CHEROKEE = 0x045C; - public const ushort SUBLANG_CATALAN_CATALAN = 0x0403; - public const ushort SUBLANG_CHINESE_HONGKONG = 0x0C04; - public const ushort SUBLANG_CHINESE_MACAU = 0x1404; - public const ushort SUBLANG_CHINESE_SINGAPORE = 0x1004; - public const ushort SUBLANG_CHINESE_SIMPLIFIED = 0x0004; - public const ushort SUBLANG_CHINESE_TRADITIONAL = 0x7C04; - public const ushort SUBLANG_CORSICAN_FRANCE = 0x0483; - public const ushort SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN = 0x101A; - public const ushort SUBLANG_CROATIAN_CROATIA = 0x041A; - public const ushort SUBLANG_CZECH_CZECH_REPUBLIC = 0x0405; - public const ushort SUBLANG_DANISH_DENMARK = 0x0406; - public const ushort SUBLANG_DARI_AFGHANISTAN = 0x048C; - public const ushort SUBLANG_DIVEHI_MALDIVES = 0x0465; - public const ushort SUBLANG_DUTCH_BELGIAN = 0x0813; - public const ushort SUBLANG_DUTCH = 0x0413; - public const ushort SUBLANG_ENGLISH_AUS = 0x0C09; - public const ushort SUBLANG_ENGLISH_BELIZE = 0x2809; - public const ushort SUBLANG_ENGLISH_CAN = 0x1009; - public const ushort SUBLANG_ENGLISH_CARIBBEAN = 0x2409; - public const ushort SUBLANG_ENGLISH_INDIA = 0x4009; - public const ushort SUBLANG_ENGLISH_EIRE = 0x1809; - public const ushort SUBLANG_ENGLISH_IRELAND = 0x1809; - public const ushort SUBLANG_ENGLISH_JAMAICA = 0x2009; - public const ushort SUBLANG_ENGLISH_MALAYSIA = 0x4409; - public const ushort SUBLANG_ENGLISH_NZ = 0x1409; - public const ushort SUBLANG_ENGLISH_PHILIPPINES = 0x3409; - public const ushort SUBLANG_ENGLISH_SINGAPORE = 0x4809; - public const ushort SUBLANG_ENGLISH_SOUTH_AFRICA = 0x1C09; - public const ushort SUBLANG_ENGLISH_TRINIDAD = 0x2C09; - public const ushort SUBLANG_ENGLISH_UK = 0x0809; - public const ushort SUBLANG_ENGLISH_US = 0x0409; - public const ushort SUBLANG_ENGLISH_ZIMBABWE = 0x3009; - public const ushort SUBLANG_ESTONIAN_ESTONIA = 0x0425; - public const ushort SUBLANG_FAEROESE_FAROE_ISLANDS = 0x0438; - public const ushort SUBLANG_FILIPINO_PHILIPPINES = 0x0464; - public const ushort SUBLANG_FINNISH_FINLAND = 0x040B; - public const ushort SUBLANG_FRENCH_BELGIAN = 0x080C; - public const ushort SUBLANG_FRENCH_CANADIAN = 0x0C0C; - public const ushort SUBLANG_FRENCH = 0x040C; - public const ushort SUBLANG_FRENCH_LUXEMBOURG = 0x140C; - public const ushort SUBLANG_FRENCH_MONACO = 0x180C; - public const ushort SUBLANG_FRENCH_SWISS = 0x100C; - public const ushort SUBLANG_FRISIAN_NETHERLANDS = 0x0462; - public const ushort SUBLANG_GALICIAN_GALICIAN = 0x0456; - public const ushort SUBLANG_GEORGIAN_GEORGIA = 0x0437; - public const ushort SUBLANG_GERMAN_AUSTRIAN = 0x0C07; - public const ushort SUBLANG_GERMAN = 0x0407; - public const ushort SUBLANG_GERMAN_LIECHTENSTEIN = 0x1407; - public const ushort SUBLANG_GERMAN_LUXEMBOURG = 0x1007; - public const ushort SUBLANG_GERMAN_SWISS = 0x0807; - public const ushort SUBLANG_GREEK_GREECE = 0x0408; - public const ushort SUBLANG_GREENLANDIC_GREENLAND = 0x046F; - public const ushort SUBLANG_GUJARATI_INDIA = 0x0447; - public const ushort SUBLANG_HAUSA_NIGERIA_LATIN = 0x0468; - public const ushort SUBLANG_HAWAIIAN_US = 0x0475; - public const ushort SUBLANG_HEBREW_ISRAEL = 0x040D; - public const ushort SUBLANG_HINDI_INDIA = 0x0439; - public const ushort SUBLANG_HUNGARIAN_HUNGARY = 0x040E; - public const ushort SUBLANG_ICELANDIC_ICELAND = 0x040F; - public const ushort SUBLANG_IGBO_NIGERIA = 0x0470; - public const ushort SUBLANG_INDONESIAN_INDONESIA = 0x0421; - public const ushort SUBLANG_INUKTITUT_CANADA_LATIN = 0x085D; - public const ushort SUBLANG_INUKTITUT_CANADA = 0x045D; - public const ushort SUBLANG_IRISH_IRELAND = 0x083C; - public const ushort SUBLANG_XHOSA_SOUTH_AFRICA = 0x0434; - public const ushort SUBLANG_ZULU_SOUTH_AFRICA = 0x0435; - public const ushort SUBLANG_ITALIAN = 0x0410; - public const ushort SUBLANG_ITALIAN_SWISS = 0x0810; - public const ushort SUBLANG_JAPANESE_JAPAN = 0x0411; - public const ushort SUBLANG_KANNADA_INDIA = 0x044B; - public const ushort SUBLANG_KAZAK_KAZAKHSTAN = 0x043F; - public const ushort SUBLANG_KHMER_CAMBODIA = 0x0453; - public const ushort SUBLANG_KICHE_GUATEMALA = 0x0486; - public const ushort SUBLANG_KINYARWANDA_RWANDA = 0x0487; - public const ushort SUBLANG_KONKANI_INDIA = 0x0457; - public const ushort SUBLANG_KOREAN = 0x0412; - public const ushort SUBLANG_KYRGYZ_KYRGYZSTAN = 0x0440; - public const ushort SUBLANG_LAO_LAO = 0x0454; - public const ushort SUBLANG_LATVIAN_LATVIA = 0x0426; - public const ushort SUBLANG_LITHUANIAN_LITHUANIA = 0x0427; - public const ushort SUBLANG_LOWER_SORBIAN_GERMANY = 0x082E; - public const ushort SUBLANG_LUXEMBOURGISH_LUXEMBOURG = 0x046E; - public const ushort SUBLANG_MACEDONIAN_MACEDONIA = 0x042F; - public const ushort SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x083E; - public const ushort SUBLANG_MALAY_MALAYSIA = 0x043E; - public const ushort SUBLANG_MALAYALAM_INDIA = 0x044C; - public const ushort SUBLANG_MALTESE_MALTA = 0x043A; - public const ushort SUBLANG_MAORI_NEW_ZEALAND = 0x0481; - public const ushort SUBLANG_MAPUDUNGUN_CHILE = 0x047A; - public const ushort SUBLANG_MARATHI_INDIA = 0x044E; - public const ushort SUBLANG_MOHAWK_MOHAWK = 0x047C; - public const ushort SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA = 0x0450; - public const ushort SUBLANG_MONGOLIAN_PRC = 0x0850; - public const ushort SUBLANG_NEPALI_NEPAL = 0x0461; - public const ushort SUBLANG_NORWEGIAN_BOKMAL = 0x0414; - public const ushort SUBLANG_NORWEGIAN_NYNORSK = 0x0814; - public const ushort SUBLANG_OCCITAN_FRANCE = 0x0482; - public const ushort SUBLANG_ORIYA_INDIA = 0x0448; - public const ushort SUBLANG_PASHTO_AFGHANISTAN = 0x0463; - public const ushort SUBLANG_PERSIAN_IRAN = 0x0429; - public const ushort SUBLANG_POLISH_POLAND = 0x0415; - public const ushort SUBLANG_PORTUGUESE_BRAZILIAN = 0x0416; - public const ushort SUBLANG_PORTUGUESE = 0x0816; - public const ushort SUBLANG_PULAR_SENEGAL = 0x0867; - public const ushort SUBLANG_PUNJABI_INDIA = 0x0446; - public const ushort SUBLANG_PUNJABI_PAKISTAN = 0x0846; - public const ushort SUBLANG_QUECHUA_BOLIVIA = 0x046B; - public const ushort SUBLANG_QUECHUA_ECUADOR = 0x086B; - public const ushort SUBLANG_QUECHUA_PERU = 0x0C6B; - public const ushort SUBLANG_ROMANIAN_ROMANIA = 0x0418; - public const ushort SUBLANG_ROMANSH_SWITZERLAND = 0x0417; - public const ushort SUBLANG_RUSSIAN_RUSSIA = 0x0419; - public const ushort SUBLANG_SAKHA_RUSSIA = 0x0485; - public const ushort SUBLANG_SAMI_INARI_FINLAND = 0x243B; - public const ushort SUBLANG_SAMI_LULE_NORWAY = 0x103B; - public const ushort SUBLANG_SAMI_LULE_SWEDEN = 0x143B; - public const ushort SUBLANG_SAMI_NORTHERN_FINLAND = 0x0C3B; - public const ushort SUBLANG_SAMI_NORTHERN_NORWAY = 0x043B; - public const ushort SUBLANG_SAMI_NORTHERN_SWEDEN = 0x083B; - public const ushort SUBLANG_SAMI_SKOLT_FINLAND = 0x203B; - public const ushort SUBLANG_SAMI_SOUTHERN_NORWAY = 0x183B; - public const ushort SUBLANG_SAMI_SOUTHERN_SWEDEN = 0x1C3B; - public const ushort SUBLANG_SANSKRIT_INDIA = 0x044F; - public const ushort SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x1C1A; - public const ushort SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN = 0x181A; - public const ushort SUBLANG_SERBIAN_CYRILLIC = 0x0C1A; - public const ushort SUBLANG_SERBIAN_LATIN = 0x081A; - public const ushort SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA = 0x046C; - public const ushort SUBLANG_TSWANA_BOTSWANA = 0x0832; - public const ushort SUBLANG_TSWANA_SOUTH_AFRICA = 0x0432; - public const ushort SUBLANG_SINDHI_INDIA = 0x0459; - public const ushort SUBLANG_SINDHI_PAKISTAN = 0x0859; - public const ushort SUBLANG_SINHALESE_SRI_LANKA = 0x045B; - public const ushort SUBLANG_SLOVAK_SLOVAKIA = 0x041B; - public const ushort SUBLANG_SLOVENIAN_SLOVENIA = 0x0424; - public const ushort SUBLANG_SPANISH_ARGENTINA = 0x2C0A; - public const ushort SUBLANG_SPANISH_BOLIVIA = 0x400A; - public const ushort SUBLANG_SPANISH_CHILE = 0x340A; - public const ushort SUBLANG_SPANISH_COLOMBIA = 0x240A; - public const ushort SUBLANG_SPANISH_COSTA_RICA = 0x140A; - public const ushort SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x1C0A; - public const ushort SUBLANG_SPANISH_ECUADOR = 0x300A; - public const ushort SUBLANG_SPANISH_EL_SALVADOR = 0x440A; - public const ushort SUBLANG_SPANISH_GUATEMALA = 0x100A; - public const ushort SUBLANG_SPANISH_HONDURAS = 0x480A; - public const ushort SUBLANG_SPANISH_MEXICAN = 0x080A; - public const ushort SUBLANG_SPANISH_NICARAGUA = 0x4C0A; - public const ushort SUBLANG_SPANISH_PANAMA = 0x180A; - public const ushort SUBLANG_SPANISH_PARAGUAY = 0x3C0A; - public const ushort SUBLANG_SPANISH_PERU = 0x280A; - public const ushort SUBLANG_SPANISH_PUERTO_RICO = 0x500A; - public const ushort SUBLANG_SPANISH_MODERN = 0x0C0A; - public const ushort SUBLANG_SPANISH = 0x040A; - public const ushort SUBLANG_SPANISH_US = 0x540A; - public const ushort SUBLANG_SPANISH_URUGUAY = 0x380A; - public const ushort SUBLANG_SPANISH_VENEZUELA = 0x200A; - public const ushort SUBLANG_SWAHILI = 0x0441; - public const ushort SUBLANG_SWEDISH_FINLAND = 0x081D; - public const ushort SUBLANG_SWEDISH = 0x041D; - public const ushort SUBLANG_SWEDISH_SWEDEN = 0x041D; - public const ushort SUBLANG_SYRIAC = 0x045A; - public const ushort SUBLANG_TAJIK_TAJIKISTAN = 0x0428; - public const ushort SUBLANG_TAMAZIGHT_ALGERIA_LATIN = 0x085F; - public const ushort SUBLANG_TAMIL_INDIA = 0x0449; - public const ushort SUBLANG_TAMIL_SRI_LANKA = 0x0849; - public const ushort SUBLANG_TATAR_RUSSIA = 0x0444; - public const ushort SUBLANG_TELUGU_INDIA = 0x044A; - public const ushort SUBLANG_THAI_THAILAND = 0x041E; - public const ushort SUBLANG_TIBETAN_PRC = 0x0451; - public const ushort SUBLANG_TIGRINYA_ERITREA = 0x0873; - public const ushort SUBLANG_TIGRINYA_ETHIOPIA = 0x0473; - public const ushort SUBLANG_TIGRIGNA_ERITREA = 0x0873; - public const ushort SUBLANG_TURKISH_TURKEY = 0x041F; - public const ushort SUBLANG_TURKMEN_TURKMENISTAN = 0x0442; - public const ushort SUBLANG_UKRAINIAN_UKRAINE = 0x0422; - public const ushort SUBLANG_UPPER_SORBIAN_GERMANY = 0x042E; - public const ushort SUBLANG_URDU_INDIA = 0x0820; - public const ushort SUBLANG_URDU_PAKISTAN = 0x0420; - public const ushort SUBLANG_UIGHUR_PRC = 0x0480; - public const ushort SUBLANG_UZBEK_CYRILLIC = 0x0843; - public const ushort SUBLANG_UZBEK_LATIN = 0x0443; - public const ushort SUBLANG_VALENCIAN_VALENCIA = 0x0803; - public const ushort SUBLANG_VIETNAMESE_VIETNAM = 0x042A; - public const ushort SUBLANG_WELSH_UNITED_KINGDOM = 0x0452; - public const ushort SUBLANG_WOLOF_SENEGAL = 0x0488; - public const ushort SUBLANG_YI_PRC = 0x0478; - public const ushort SUBLANG_YORUBA_NIGERIA = 0x046A; - - } - -} diff --git a/Src/Workshell.PE.Resources/Menus/MenuItem.cs b/Src/Workshell.PE.Resources/Menus/MenuItem.cs deleted file mode 100644 index 3a73817..0000000 --- a/Src/Workshell.PE.Resources/Menus/MenuItem.cs +++ /dev/null @@ -1,210 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; - -namespace Workshell.PE.Resources -{ - - [Flags] - public enum MenuItemFlags : ushort - { - Enabled = 0, - Grayed = 0x0001, - Disabled = 0x0002, - Bitmap = 0x0004, - OwnerDraw = 0x0100, - Checked = 0x0008, - Popup = 0x0010, - MenubarBreak = 0x0020, - MenuBreak = 0x0040, - EndMenu = 0x0080, - Seperator = 0x0800 - } - - public class MenuItem - { - - private ushort id; - private string text; - private string shortcut; - private ushort flags; - - internal MenuItem(ushort itemId, string itemText, ushort itemFlags) - { - id = itemId; - - string[] parts = itemText.Split(new char[] { '\t' }, 2); - - text = parts[0]; - - if (parts.Length > 1) - { - shortcut = parts[1]; - } - else - { - shortcut = String.Empty; - } - - flags = itemFlags; - } - - #region Methods - - public override string ToString() - { - if (!IsSeperator) - { - string result = text; - - if (IsPopup) - result = "+" + result; - - if (shortcut != String.Empty) - result += " | " + shortcut; - - return result; - } - else - { - return "-"; - } - } - - #endregion - - #region Properties - - public ushort Id - { - get - { - return id; - } - } - - public string Text - { - get - { - return text; - } - } - - public string Shortcut - { - get - { - return shortcut; - } - } - - public MenuItemFlags Flags - { - get - { - return (MenuItemFlags)flags; - } - } - - public bool IsPopup - { - get - { - return (id == 0); - } - } - - public bool IsSeperator - { - get - { - return (id == 0 && flags == 0 && shortcut == String.Empty); - } - } - - #endregion - - } - - public sealed class PopupMenuItem : MenuItem, IEnumerable - { - - private MenuItem[] items; - - internal PopupMenuItem(ushort itemId, string itemText, ushort itemFlags, MenuItem[] subItems) : base(itemId, itemText, itemFlags) - { - items = subItems; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < items.Length; i++) - yield return items[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public int Count - { - get - { - return items.Length; - } - } - - public MenuItem this[int index] - { - get - { - return items[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Menus/MenuResource.cs b/Src/Workshell.PE.Resources/Menus/MenuResource.cs deleted file mode 100644 index d7c9343..0000000 --- a/Src/Workshell.PE.Resources/Menus/MenuResource.cs +++ /dev/null @@ -1,214 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class Menu : IEnumerable - { - - private MenuResource resource; - private uint language_id; - private MenuItem[] items; - - internal Menu(MenuResource menuResource, uint languageId, MenuItem[] menuItems) - { - resource = menuResource; - language_id = languageId; - items = menuItems; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < items.Length; i++) - yield return items[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public MenuResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public int Count - { - get - { - return items.Length; - } - } - - public MenuItem this[int index] - { - get - { - return items[index]; - } - } - - #endregion - - } - - public sealed class MenuResource : Resource - { - - public MenuResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_MENU); - - return ResourceType.Register(resource_type, typeof(MenuResource)); - } - - #endregion - - #region Methods - - public Menu ToMenu() - { - return ToMenu(DEFAULT_LANGUAGE); - } - - public Menu ToMenu(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - ushort version = Utils.ReadUInt16(mem); - ushort header_size = Utils.ReadUInt16(mem); - List menu_items = new List(); - - LoadMenu(mem, menu_items); - - MenuItem[] items = menu_items.ToArray(); - Menu menu = new Resources.Menu(this, languageId, items); - - return menu; - } - } - - private void LoadMenu(Stream stream, List items) - { - while (true) - { - ushort flags = Utils.ReadUInt16(stream); - MenuItemFlags menu_item_flags = (MenuItemFlags)flags; - - if ((menu_item_flags & MenuItemFlags.Popup) == MenuItemFlags.Popup) - { - StringBuilder builder = new StringBuilder(); - - while (true) - { - ushort value = Utils.ReadUInt16(stream); - - if (value == 0) - break; - - builder.Append((char)value); - } - - List sub_menu_items = new List(); - - LoadMenu(stream, sub_menu_items); - - PopupMenuItem popup_menu_item = new PopupMenuItem(0, builder.ToString(), flags, sub_menu_items.ToArray()); - - items.Add(popup_menu_item); - } - else - { - ushort id = Utils.ReadUInt16(stream); - StringBuilder builder = new StringBuilder(); - - while (true) - { - ushort value = Utils.ReadUInt16(stream); - - if (value == 0) - break; - - builder.Append((char)value); - } - - MenuItem menu_item = new MenuItem(id, builder.ToString(), flags); - - items.Add(menu_item); - } - - if ((menu_item_flags & MenuItemFlags.EndMenu) == MenuItemFlags.EndMenu) - break; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/ACCELTABLEENTRY.cs b/Src/Workshell.PE.Resources/Native/ACCELTABLEENTRY.cs deleted file mode 100644 index 82f903f..0000000 --- a/Src/Workshell.PE.Resources/Native/ACCELTABLEENTRY.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct ACCELTABLEENTRY - { - - public ushort fFlags; - public ushort wAnsi; - public ushort wId; - public ushort padding; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/BITMAPFILEHEADER.cs b/Src/Workshell.PE.Resources/Native/BITMAPFILEHEADER.cs deleted file mode 100644 index d42dbca..0000000 --- a/Src/Workshell.PE.Resources/Native/BITMAPFILEHEADER.cs +++ /dev/null @@ -1,50 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct BITMAPFILEHEADER - { - - public ushort Tag; - public uint Size; - public ushort Reserved1; - public ushort Reserved2; - public uint BitmapOffset; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/BITMAPINFOHEADER.cs b/Src/Workshell.PE.Resources/Native/BITMAPINFOHEADER.cs deleted file mode 100644 index 5d9c5b6..0000000 --- a/Src/Workshell.PE.Resources/Native/BITMAPINFOHEADER.cs +++ /dev/null @@ -1,71 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - public enum BitmapCompressionMode : uint - { - BI_RGB = 0, - BI_RLE8 = 1, - BI_RLE4 = 2, - BI_BITFIELDS = 3, - BI_JPEG = 4, - BI_PNG = 5 - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct BITMAPINFOHEADER - { - - public uint biSize; - public int biWidth; - public int biHeight; - public ushort biPlanes; - public ushort biBitCount; - public BitmapCompressionMode biCompression; - public uint biSizeImage; - public int biXPelsPerMeter; - public int biYPelsPerMeter; - public uint biClrUsed; - public uint biClrImportant; - - public void Init() - { - biSize = (uint)Marshal.SizeOf(this); - } - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/CURSORDIR.cs b/Src/Workshell.PE.Resources/Native/CURSORDIR.cs deleted file mode 100644 index 0050ada..0000000 --- a/Src/Workshell.PE.Resources/Native/CURSORDIR.cs +++ /dev/null @@ -1,48 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct CURSORDIR - { - - public ushort Width; - public ushort Height; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/ICONDIR.cs b/Src/Workshell.PE.Resources/Native/ICONDIR.cs deleted file mode 100644 index 030ad96..0000000 --- a/Src/Workshell.PE.Resources/Native/ICONDIR.cs +++ /dev/null @@ -1,50 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct ICONDIR - { - - public byte Width; - public byte Height; - public byte ColorCount; - public byte Reserved; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/MESSAGETABLE.cs b/Src/Workshell.PE.Resources/Native/MESSAGETABLE.cs deleted file mode 100644 index f0ab166..0000000 --- a/Src/Workshell.PE.Resources/Native/MESSAGETABLE.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct MESSAGE_RESOURCE_DATA - { - - public uint NumberOfBlocks; - - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct MESSAGE_RESOURCE_BLOCK - { - - public uint LowId; - public uint HighId; - public uint OffsetToEntries; - - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct MESSAGE_RESOURCE_ENTRY - { - - public ushort Length; - public ushort Flags; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/NEWHEADER.cs b/Src/Workshell.PE.Resources/Native/NEWHEADER.cs deleted file mode 100644 index 3d3b1bf..0000000 --- a/Src/Workshell.PE.Resources/Native/NEWHEADER.cs +++ /dev/null @@ -1,52 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct NEWHEADER - { - - public const ushort RES_ICON = 1; - public const ushort RES_CURSOR = 2; - - public ushort Reserved; - public ushort ResType; - public ushort ResCount; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/RESDIR.cs b/Src/Workshell.PE.Resources/Native/RESDIR.cs deleted file mode 100644 index 3456599..0000000 --- a/Src/Workshell.PE.Resources/Native/RESDIR.cs +++ /dev/null @@ -1,63 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct ICON_RESDIR - { - - public ICONDIR Icon; - public ushort Planes; - public ushort BitCount; - public uint BytesInRes; - public ushort IconId; - - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct CURSOR_RESDIR - { - - public CURSORDIR Cursor; - public ushort Planes; - public ushort BitCount; - public uint BytesInRes; - public ushort CursorId; - - } - -} diff --git a/Src/Workshell.PE.Resources/Native/VS_FIXEDFILEINFO.cs b/Src/Workshell.PE.Resources/Native/VS_FIXEDFILEINFO.cs deleted file mode 100644 index 776bedd..0000000 --- a/Src/Workshell.PE.Resources/Native/VS_FIXEDFILEINFO.cs +++ /dev/null @@ -1,58 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources.Native -{ - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct VS_FIXEDFILEINFO - { - - public uint dwSignature; - public uint dwStrucVersion; - public uint dwFileVersionMS; - public uint dwFileVersionLS; - public uint dwProductVersionMS; - public uint dwProductVersionLS; - public uint dwFileFlagsMask; - public uint dwFileFlags; - public uint dwFileOS; - public uint dwFileType; - public uint dwFileSubtype; - public uint dwFileDateMS; - public uint dwFileDateLS; - - } - -} diff --git a/Src/Workshell.PE.Resources/Properties/AssemblyInfo.cs b/Src/Workshell.PE.Resources/Properties/AssemblyInfo.cs deleted file mode 100644 index 516afa5..0000000 --- a/Src/Workshell.PE.Resources/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Workshell.PE.Resources")] -[assembly: AssemblyDescription("A set of classes for dealing with resources within a PE file.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Workshell Ltd")] -[assembly: AssemblyProduct(".NET PE Resources Class Library")] -[assembly: AssemblyCopyright("Copyright ©2016 Workshell Ltd")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2b06cbf8-136a-4bec-8624-861992139489")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.*")] -[assembly: AssemblyInformationalVersion("1.7.0")] diff --git a/Src/Workshell.PE.Resources/ResourceUtils.cs b/Src/Workshell.PE.Resources/ResourceUtils.cs deleted file mode 100644 index 6379e0a..0000000 --- a/Src/Workshell.PE.Resources/ResourceUtils.cs +++ /dev/null @@ -1,85 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - internal static class ResourceUtils - { - - #region Methods - - public static ushort OrdOrSz(Stream stream, out string str) - { - ushort value = Utils.ReadUInt16(stream); - - if (value == 0) - { - str = String.Empty; - - return 0; - } - else if (value == 0xFFFF) - { - value = Utils.ReadUInt16(stream); - - str = String.Empty; - - return value; - } - else - { - StringBuilder builder = new StringBuilder(256); - - while (true) - { - if (value == 0) - break; - - builder.Append((char)value); - - value = Utils.ReadUInt16(stream); - } - - str = builder.ToString(); - - return value; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Strings/MessageTableResource.cs b/Src/Workshell.PE.Resources/Strings/MessageTableResource.cs deleted file mode 100644 index 091f1fd..0000000 --- a/Src/Workshell.PE.Resources/Strings/MessageTableResource.cs +++ /dev/null @@ -1,315 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class MessageTableEntry - { - - internal MessageTableEntry(uint messageId, string message, bool isUnicode) - { - Id = messageId; - Message = message; - IsUnicode = isUnicode; - } - - #region Methods - - public override string ToString() - { - return String.Format("0x{0:X8}: {1}", Id, Message); - } - - #endregion - - #region Properties - - public uint Id - { - get; - private set; - } - - public string Message - { - get; - private set; - } - - public bool IsUnicode - { - get; - private set; - } - - #endregion - - } - - public sealed class MessageTableBlock : IEnumerable - { - - private uint low_id; - private uint high_id; - private uint offset; - private MessageTableEntry[] entries; - - internal MessageTableBlock(uint lowId, uint highId, uint offsetToEntries, MessageTableEntry[] tableEntries) - { - low_id = lowId; - high_id = highId; - offset = offsetToEntries; - entries = tableEntries; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < entries.Length; i++) - yield return entries[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public uint LowId - { - get - { - return low_id; - } - } - - public uint HighId - { - get - { - return high_id; - } - } - - public uint OffsetToEntries - { - get - { - return offset; - } - } - - public int Count - { - get - { - return entries.Length; - } - } - - public MessageTableEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - - public sealed class MessageTable : IEnumerable - { - - private MessageTableResource resource; - private uint language_id; - private MessageTableBlock[] blocks; - - internal MessageTable(MessageTableResource tableResource, uint languageId, MessageTableBlock[] tableBlocks) - { - resource = tableResource; - language_id = languageId; - blocks = tableBlocks; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < blocks.Length; i++) - yield return blocks[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public MessageTableResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public int Count - { - get - { - return blocks.Length; - } - } - - public MessageTableBlock this[int index] - { - get - { - return blocks[index]; - } - } - - #endregion - - } - - public sealed class MessageTableResource : Resource - { - - public MessageTableResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_MESSAGETABLE); - - return ResourceType.Register(resource_type, typeof(MessageTableResource)); - } - - #endregion - - #region Methods - - public MessageTable ToTable() - { - return ToTable(DEFAULT_LANGUAGE); - } - - public MessageTable ToTable(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - List> tuples = new List>(); - MESSAGE_RESOURCE_DATA resource_data = Utils.Read(mem); - - for(var i = 0; i < resource_data.NumberOfBlocks; i++) - { - MESSAGE_RESOURCE_BLOCK block = Utils.Read(mem); - Tuple tuple = new Tuple(block.OffsetToEntries, block.LowId, block.HighId); - - tuples.Add(tuple); - } - - MessageTableBlock[] blocks = new MessageTableBlock[resource_data.NumberOfBlocks]; - - for(var i = 0; i < tuples.Count; i++) - { - Tuple tuple = tuples[i]; - - mem.Seek(tuple.Item1, SeekOrigin.Begin); - - int count = (tuple.Item3 - tuple.Item2).ToInt32() + 1; - MessageTableEntry[] entries = new MessageTableEntry[count]; - - uint id = tuple.Item2; - - for (var j = 0; j < count; j++) - { - MESSAGE_RESOURCE_ENTRY resource_entry = Utils.Read(mem); - byte[] buffer = Utils.ReadBytes(mem, resource_entry.Length - sizeof(uint)); - string message = (resource_entry.Flags == 0 ? Encoding.ASCII.GetString(buffer) : Encoding.Unicode.GetString(buffer)); - MessageTableEntry entry = new MessageTableEntry(id, message, resource_entry.Flags != 0); - - entries[j] = entry; - id++; - } - - MessageTableBlock block = new MessageTableBlock(tuple.Item2, tuple.Item3, tuple.Item1, entries); - - blocks[i] = block; - } - - MessageTable table = new MessageTable(this, languageId, blocks); - - return table; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Strings/StringTableResource.cs b/Src/Workshell.PE.Resources/Strings/StringTableResource.cs deleted file mode 100644 index 97aafeb..0000000 --- a/Src/Workshell.PE.Resources/Strings/StringTableResource.cs +++ /dev/null @@ -1,258 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class StringTableEntry - { - - private ushort id; - private string value; - - internal StringTableEntry(ushort stringId, string stringValue) - { - id = stringId; - value = stringValue; - } - - #region Methods - - public override string ToString() - { - if (id == 0) - { - return "(Empty)"; - } - else - { - return String.Format("{0} = {1}", id, value); - } - } - - #endregion - - #region Properties - - public ushort Id - { - get - { - return id; - } - } - - public string Value - { - get - { - return value; - } - } - - public bool IsEmpty - { - get - { - return (id == 0); - } - } - - #endregion - - } - - public sealed class StringTable : IEnumerable - { - - private StringTableResource resource; - private uint language_id; - private StringTableEntry[] strings; - - internal StringTable(StringTableResource tableResource, uint languageId, StringTableEntry[] tableEntries) - { - resource = tableResource; - language_id = languageId; - strings = tableEntries; - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < strings.Length; i++) - yield return strings[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public StringTableResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public int Count - { - get - { - return strings.Length; - } - } - - public StringTableEntry this[int index] - { - get - { - return strings[index]; - } - } - - #endregion - - } - - public sealed class StringTableResource : Resource - { - - public StringTableResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_STRING); - - return ResourceType.Register(resource_type, typeof(StringTableResource)); - } - - #endregion - - #region Methods - - public StringTable ToTable() - { - return ToTable(DEFAULT_LANGUAGE); - } - - public StringTable ToTable(uint languageId) - { - byte[] data = GetBytes(languageId); - - List list = new List(); - - using (MemoryStream mem = new MemoryStream(data)) - { - while (mem.Position < mem.Length) - { - ushort count = Utils.ReadUInt16(mem); - - if (count == 0) - { - list.Add(null); - } - else - { - StringBuilder builder = new StringBuilder(count); - - for (var i = 0; i < count; i++) - { - ushort value = Utils.ReadUInt16(mem); - - builder.Append((char)value); - } - - list.Add(builder.ToString()); - } - } - } - - StringTableEntry[] strings = new StringTableEntry[list.Count]; - ushort base_id = Convert.ToUInt16((Id - 1) << 4); - - for (var i = 0; i < list.Count; i++) - { - StringTableEntry entry; - string value = list[i]; - - if (value == null) - { - entry = new StringTableEntry(0, value); - } - else - { - ushort id = Convert.ToUInt16(base_id + i); - - entry = new StringTableEntry(id, value); - } - - strings[i] = entry; - } - - StringTable table = new StringTable(this, languageId, strings); - - return table; - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Styles.cs b/Src/Workshell.PE.Resources/Styles.cs deleted file mode 100644 index 0ab603e..0000000 --- a/Src/Workshell.PE.Resources/Styles.cs +++ /dev/null @@ -1,270 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Resources -{ - - [Flags] - public enum WindowStyle : uint - { - WS_OVERLAPPED = 0x00000000, - WS_POPUP = 0x80000000, - WS_CHILD = 0x40000000, - WS_MINIMIZE = 0x20000000, - WS_VISIBLE = 0x10000000, - WS_DISABLED = 0x08000000, - WS_CLIPSIBLINGS = 0x04000000, - WS_CLIPCHILDREN = 0x02000000, - WS_MAXIMIZE = 0x01000000, - WS_CAPTION = 0x00C00000, // WS_BORDER | WS_DLGFRAME - WS_BORDER = 0x00800000, - WS_DLGFRAME = 0x00400000, - WS_VSCROLL = 0x00200000, - WS_HSCROLL = 0x00100000, - WS_SYSMENU = 0x00080000, - WS_THICKFRAME = 0x00040000, - WS_GROUP = 0x00020000, - WS_TABSTOP = 0x00010000, - - WS_MINIMIZEBOX = 0x00020000, - WS_MAXIMIZEBOX = 0x00010000, - - WS_TILED = WS_OVERLAPPED, - WS_ICONIC = WS_MINIMIZE, - WS_SIZEBOX = WS_THICKFRAME, - WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW, - - WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX), - WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU), - WS_CHILDWINDOW = WS_CHILD - } - - [Flags] - public enum DialogStyle : uint - { - DS_ABSALIGN = 0x01, - DS_SYSMODAL = 0x02, - DS_LOCALEDIT = 0x20, - DS_SETFONT = 0x40, - DS_MODALFRAME = 0x80, - DS_NOIDLEMSG = 0x100, - DS_SETFOREGROUND = 0x200, - - DS_3DLOOK = 0x0004, - DS_FIXEDSYS = 0x0008, - DS_NOFAILCREATE = 0x0010, - DS_CONTROL = 0x0400, - DS_CENTER = 0x0800, - DS_CENTERMOUSE = 0x1000, - DS_CONTEXTHELP = 0x2000, - - DS_SHELLFONT = (DS_SETFONT | DS_FIXEDSYS), - DS_USEPIXELS = 0x8000 - } - - [Flags] - public enum ButtonStyle : uint - { - BS_PUSHBUTTON = 0x00000000, - BS_DEFPUSHBUTTON = 0x00000001, - BS_CHECKBOX = 0x00000002, - BS_AUTOCHECKBOX = 0x00000003, - BS_RADIOBUTTON = 0x00000004, - BS_3STATE = 0x00000005, - BS_AUTO3STATE = 0x00000006, - BS_GROUPBOX = 0x00000007, - BS_USERBUTTON = 0x00000008, - BS_AUTORADIOBUTTON = 0x00000009, - BS_PUSHBOX = 0x0000000A, - BS_OWNERDRAW = 0x0000000B, - BS_TYPEMASK = 0x0000000F, - BS_LEFTTEXT = 0x00000020, - BS_TEXT = 0x00000000, - BS_ICON = 0x00000040, - BS_BITMAP = 0x00000080, - BS_LEFT = 0x00000100, - BS_RIGHT = 0x00000200, - BS_CENTER = 0x00000300, - BS_TOP = 0x00000400, - BS_BOTTOM = 0x00000800, - BS_VCENTER = 0x00000C00, - BS_PUSHLIKE = 0x00001000, - BS_MULTILINE = 0x00002000, - BS_NOTIFY = 0x00004000, - BS_FLAT = 0x00008000, - BS_RIGHTBUTTON = BS_LEFTTEXT - } - - [Flags] - public enum StaticStyle - { - SS_LEFT = 0x00000000, - SS_CENTER = 0x00000001, - SS_RIGHT = 0x00000002, - SS_ICON = 0x00000003, - SS_BLACKRECT = 0x00000004, - SS_GRAYRECT = 0x00000005, - SS_WHITERECT = 0x00000006, - SS_BLACKFRAME = 0x00000007, - SS_GRAYFRAME = 0x00000008, - SS_WHITEFRAME = 0x00000009, - SS_USERITEM = 0x0000000A, - SS_SIMPLE = 0x0000000B, - SS_LEFTNOWORDWRAP = 0x0000000C, - SS_OWNERDRAW = 0x0000000D, - SS_BITMAP = 0x0000000E, - SS_ENHMETAFILE = 0x0000000F, - SS_ETCHEDHORZ = 0x00000010, - SS_ETCHEDVERT = 0x00000011, - SS_ETCHEDFRAME = 0x00000012, - SS_TYPEMASK = 0x0000001F, - SS_REALSIZECONTROL = 0x00000040, - SS_NOPREFIX = 0x00000080, - SS_NOTIFY = 0x00000100, - SS_CENTERIMAGE = 0x00000200, - SS_RIGHTJUST = 0x00000400, - SS_REALSIZEIMAGE = 0x00000800, - SS_SUNKEN = 0x00001000, - SS_EDITCONTROL = 0x00002000, - SS_ENDELLIPSIS = 0x00004000, - SS_PATHELLIPSIS = 0x00008000, - SS_WORDELLIPSIS = 0x0000C000, - SS_ELLIPSISMASK = 0x0000C000, - } - - [Flags] - public enum EditStyle : uint - { - ES_LEFT = 0x0000, - ES_CENTER = 0x0001, - ES_RIGHT = 0x0002, - ES_MULTILINE = 0x0004, - ES_UPPERCASE = 0x0008, - ES_LOWERCASE = 0x0010, - ES_PASSWORD = 0x0020, - ES_AUTOVSCROLL = 0x0040, - ES_AUTOHSCROLL = 0x0080, - ES_NOHIDESEL = 0x0100, - ES_OEMCONVERT = 0x0400, - ES_READONLY = 0x0800, - ES_WANTRETURN = 0x1000, - ES_NUMBER = 0x2000, - } - - [Flags] - public enum ListBoxStyle : uint - { - LBS_NOTIFY = 0x0001, - LBS_SORT = 0x0002, - LBS_NOREDRAW = 0x0004, - LBS_MULTIPLESEL = 0x0008, - LBS_OWNERDRAWFIXED = 0x0010, - LBS_OWNERDRAWVARIABLE = 0x0020, - LBS_HASSTRINGS = 0x0040, - LBS_USETABSTOPS = 0x0080, - LBS_NOINTEGRALHEIGHT = 0x0100, - LBS_MULTICOLUMN = 0x0200, - LBS_WANTKEYBOARDINPUT = 0x0400, - LBS_EXTENDEDSEL = 0x0800, - LBS_DISABLENOSCROLL = 0x1000, - LBS_NODATA = 0x2000, - LBS_NOSEL = 0x4000, - LBS_COMBOBOX = 0x8000, - LBS_STANDARD = (LBS_NOTIFY | LBS_SORT | WindowStyle.WS_VSCROLL | WindowStyle.WS_BORDER), - } - - [Flags] - public enum ComboBoxStyle : uint - { - CBS_SIMPLE = 0x0001, - CBS_DROPDOWN = 0x0002, - CBS_DROPDOWNLIST = 0x0003, - CBS_OWNERDRAWFIXED = 0x0010, - CBS_OWNERDRAWVARIABLE = 0x0020, - CBS_AUTOHSCROLL = 0x0040, - CBS_OEMCONVERT = 0x0080, - CBS_SORT = 0x0100, - CBS_HASSTRINGS = 0x0200, - CBS_NOINTEGRALHEIGHT = 0x0400, - CBS_DISABLENOSCROLL = 0x0800, - CBS_UPPERCASE = 0x2000, - CBS_LOWERCASE = 0x4000, - } - - [Flags] - public enum ScrollBarStyle : uint - { - SBS_HORZ = 0x0000, - SBS_VERT = 0x0001, - SBS_TOPALIGN = 0x0002, - SBS_LEFTALIGN = 0x0002, - SBS_BOTTOMALIGN = 0x0004, - SBS_RIGHTALIGN = 0x0004, - SBS_SIZEBOXTOPLEFTALIGN = 0x0002, - SBS_SIZEBOXBOTTOMRIGHTALIGN = 0x0004, - SBS_SIZEBOX = 0x0008, - SBS_SIZEGRIP = 0x0010 - } - - [Flags] - public enum WindowStyleEx : uint - { - WS_EX_DLGMODALFRAME = 0x00000001, - WS_EX_NOPARENTNOTIFY = 0x00000004, - WS_EX_TOPMOST = 0x00000008, - WS_EX_ACCEPTFILES = 0x00000010, - WS_EX_TRANSPARENT = 0x00000020, - WS_EX_MDICHILD = 0x00000040, - WS_EX_TOOLWINDOW = 0x00000080, - WS_EX_WINDOWEDGE = 0x00000100, - WS_EX_CLIENTEDGE = 0x00000200, - WS_EX_CONTEXTHELP = 0x00000400, - WS_EX_RIGHT = 0x00001000, - WS_EX_LEFT = 0x00000000, - WS_EX_RTLREADING = 0x00002000, - WS_EX_LTRREADING = 0x00000000, - WS_EX_LEFTSCROLLBAR = 0x00004000, - WS_EX_RIGHTSCROLLBAR = 0x00000000, - WS_EX_CONTROLPARENT = 0x00010000, - WS_EX_STATICEDGE = 0x00020000, - WS_EX_APPWINDOW = 0x00040000, - WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE), - WS_EX_PALETTEWINDOW = (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST), - WS_EX_LAYERED = 0x00080000, - WS_EX_NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children - WS_EX_LAYOUTRTL = 0x00400000, // Right to left mirroring - WS_EX_COMPOSITED = 0x02000000, - WS_EX_NOACTIVATE = 0x08000000 - } - -} diff --git a/Src/Workshell.PE.Resources/Version/FixedFileInfo.cs b/Src/Workshell.PE.Resources/Version/FixedFileInfo.cs deleted file mode 100644 index 4ddfe9f..0000000 --- a/Src/Workshell.PE.Resources/Version/FixedFileInfo.cs +++ /dev/null @@ -1,245 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Resources.Native; - -namespace Workshell.PE.Resources -{ - - [Flags] - public enum FileFlags : int - { - [EnumAnnotation("VS_FF_DEBUG")] - Debug = 0x00000001, - [EnumAnnotation("VS_FF_INFOINFERRED")] - InfoInferred = 0x00000010, - [EnumAnnotation("VS_FF_PATCHED")] - Patched = 0x00000004, - [EnumAnnotation("VS_FF_PRERELEASE")] - PreRelease = 0x00000002, - [EnumAnnotation("VS_FF_PRIVATEBUILD")] - PrivateBuild = 0x00000008, - [EnumAnnotation("VS_FF_SPECIALBUILD")] - SpecialBuild = 0x00000020 - } - - [Flags] - public enum FileOS : int - { - [EnumAnnotation("VOS_DOS")] - DOS = 0x00010000, - [EnumAnnotation("VOS_NT")] - NT = 0x00040000, - [EnumAnnotation("VOS__WINDOWS16")] - Win16 = 0x00000001, - [EnumAnnotation("VOS__WINDOWS32")] - Win32 = 0x00000004, - [EnumAnnotation("VOS_OS216")] - OS2_16 = 0x00020000, - [EnumAnnotation("VOS_OS232")] - OS2_32 = 0x00030000, - [EnumAnnotation("VOS__PM16")] - PM16 = 0x00000002, - [EnumAnnotation("VOS__PM32")] - PM32 = 0x00000003, - [EnumAnnotation("VOS_UNKNOWN")] - Unknown = 0x00000000, - - [EnumAnnotation("VOS_DOS_WINDOWS16")] - DOS_Win16 = 0x00010001, - [EnumAnnotation("VOS_DOS_WINDOWS32")] - DOS_Win32 = 0x00010004, - [EnumAnnotation("VOS_NT_WINDOWS32")] - NT_Win32 = 0x00040004, - [EnumAnnotation("VOS_OS216_PM16")] - OS2_PM16 = 0x00020002, - [EnumAnnotation("VOS_OS232_PM32")] - OS2_PM32 = 0x00030003 - } - - public enum FileType : int - { - [EnumAnnotation("VFT_APP")] - Application = 0x00000001, - [EnumAnnotation("VFT_DLL")] - Library = 0x00000002, - [EnumAnnotation("VFT_DRV")] - Driver = 0x00000003, - [EnumAnnotation("VFT_FONT")] - Font = 0x00000004, - [EnumAnnotation("VFT_STATIC_LIB")] - StaticLibrary = 0x00000007, - [EnumAnnotation("VFT_UNKNOWN")] - Unknown = 0x00000000, - [EnumAnnotation("VFT_VXD")] - VxD = 0x00000005 - } - - public enum DriverFileSubType : int - { - [EnumAnnotation("VFT2_DRV_COMM")] - Communications = 0x0000000A, - [EnumAnnotation("VFT2_DRV_DISPLAY")] - Display = 0x00000004, - [EnumAnnotation("VFT2_DRV_INSTALLABLE")] - Installable = 0x00000008, - [EnumAnnotation("VFT2_DRV_KEYBOARD")] - Keyboard = 0x00000002, - [EnumAnnotation("VFT2_DRV_LANGUAGE")] - Language = 0x00000003, - [EnumAnnotation("VFT2_DRV_MOUSE")] - Mouse = 0x00000005, - [EnumAnnotation("VFT2_DRV_NETWORK")] - Network = 0x00000006, - [EnumAnnotation("VFT2_DRV_PRINTER")] - Printer = 0x00000001, - [EnumAnnotation("VFT2_DRV_SOUND")] - Sound = 0x00000009, - [EnumAnnotation("VFT2_DRV_SYSTEM")] - System = 0x00000007, - [EnumAnnotation("VFT2_DRV_VERSIONED_PRINTER")] - VersionedPrinter = 0x0000000C, - [EnumAnnotation("VFT2_UNKNOWN")] - Unknown = 0x00000000 - } - - public enum FontSubType : int - { - [EnumAnnotation("VFT2_FONT_RASTER")] - Raster = 0x00000001, - [EnumAnnotation("VFT2_FONT_TRUETYPE")] - TrueType = 0x00000003, - [EnumAnnotation("VFT2_FONT_VECTOR")] - Vector = 0x00000002, - [EnumAnnotation("VFT2_UNKNOWN")] - Unknown = 0x00000000 - } - - public sealed class FixedFileInfo - { - - private VS_FIXEDFILEINFO fixed_file_info; - private Lazy file_version; - private Lazy product_version; - private Lazy file_date; - - internal FixedFileInfo(Stream stream) - { - fixed_file_info = Utils.Read(stream); - file_version = new Lazy(() => GetFileVersion()); - product_version = new Lazy(() => GetProductVersion()); - file_date = new Lazy(() => GetFileDate()); - } - - #region Methods - - private Version GetFileVersion() - { - ushort major = Utils.HiWord(fixed_file_info.dwFileVersionMS); - ushort minor = Utils.LoWord(fixed_file_info.dwFileVersionMS); - ushort build = Utils.HiWord(fixed_file_info.dwFileVersionLS); - ushort priv = Utils.LoWord(fixed_file_info.dwFileVersionLS); - - return new Version(major, minor, build, priv); - } - - private Version GetProductVersion() - { - ushort major = Utils.HiWord(fixed_file_info.dwProductVersionMS); - ushort minor = Utils.LoWord(fixed_file_info.dwProductVersionMS); - ushort build = Utils.HiWord(fixed_file_info.dwProductVersionLS); - ushort priv = Utils.LoWord(fixed_file_info.dwProductVersionLS); - - return new Version(major, minor, build, priv); - } - - private DateTime GetFileDate() - { - ulong value = Utils.MakeUInt64(fixed_file_info.dwFileDateMS, fixed_file_info.dwFileDateLS); - DateTime result = DateTime.FromFileTime(Convert.ToInt64(value)); - - return result; - } - - #endregion - - #region Properties - - public Version FileVersion - { - get - { - return file_version.Value; - } - } - - public Version ProductVersion - { - get - { - return product_version.Value; - } - } - - public DateTime FileDate - { - get - { - return file_date.Value; - } - } - - public FileOS FileOS - { - get - { - return (FileOS)fixed_file_info.dwFileOS; - } - } - - public FileType FileType - { - get - { - return (FileType)fixed_file_info.dwFileType; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Version/StringFileInfo.cs b/Src/Workshell.PE.Resources/Version/StringFileInfo.cs deleted file mode 100644 index cc4523f..0000000 --- a/Src/Workshell.PE.Resources/Version/StringFileInfo.cs +++ /dev/null @@ -1,149 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Resources -{ - - public sealed class StringFileInfo : IEnumerable - { - - private VersionResource resource; - private ushort len; - private ushort val_len; - private ushort type; - private string key; - private List tables; - - internal StringFileInfo(VersionResource versionResource, Stream stream) - { - resource = versionResource; - - int count = 0; - - len = Utils.ReadUInt16(stream); - val_len = Utils.ReadUInt16(stream); - type = Utils.ReadUInt16(stream); - - count += 3 * sizeof(ushort); - - key = Utils.ReadUnicodeString(stream); - - count += (key.Length + 1) * sizeof(ushort); - - if (stream.Position % 4 != 0) - { - Utils.ReadUInt16(stream); - - count += sizeof(ushort); - } - - tables = new List(); - - byte[] data = Utils.ReadBytes(stream, len - count); - - using (MemoryStream mem = new MemoryStream(data)) - { - while (mem.Position < mem.Length) - { - VerStringTable table = new VerStringTable(mem); - - tables.Add(table); - } - } - } - - #region Methods - - public override string ToString() - { - return String.Format("Key: {0}, Tables: {1:n0}", key, tables.Count); - } - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < tables.Count; i++) - yield return tables[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public string Key - { - get - { - return key; - } - } - - public int Count - { - get - { - return tables.Count; - } - } - - public VerStringTable this[int index] - { - get - { - return tables[index]; - } - } - - public VerStringTable this[string key] - { - get - { - VerStringTable table = tables.FirstOrDefault(t => String.Compare(key, t.Key, true) == 0); - - return table; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Version/VarFileInfo.cs b/Src/Workshell.PE.Resources/Version/VarFileInfo.cs deleted file mode 100644 index b6436bd..0000000 --- a/Src/Workshell.PE.Resources/Version/VarFileInfo.cs +++ /dev/null @@ -1,149 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Resources -{ - - public sealed class VarFileInfo : IEnumerable - { - - private VersionResource resource; - private ushort len; - private ushort val_len; - private ushort type; - private string key; - private List vars; - - internal VarFileInfo(VersionResource versionResource, Stream stream) - { - resource = versionResource; - - int count = 0; - - len = Utils.ReadUInt16(stream); - val_len = Utils.ReadUInt16(stream); - type = Utils.ReadUInt16(stream); - - count += 3 * sizeof(ushort); - - key = Utils.ReadUnicodeString(stream); - - count += (key.Length + 1) * sizeof(ushort); - - if (stream.Position % 4 != 0) - { - Utils.ReadUInt16(stream); - - count += sizeof(ushort); - } - - vars = new List(); - - byte[] data = Utils.ReadBytes(stream, len - count); - - using (MemoryStream mem = new MemoryStream(data)) - { - while (mem.Position < mem.Length) - { - VerVar v = new VerVar(mem); - - vars.Add(v); - } - } - } - - #region Methods - - public override string ToString() - { - return String.Format("Key: {0}, Vars: {1:n0}", key, vars.Count); - } - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < vars.Count; i++) - yield return vars[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public string Key - { - get - { - return key; - } - } - - public int Count - { - get - { - return vars.Count; - } - } - - public VerVar this[int index] - { - get - { - return vars[index]; - } - } - - public VerVar this[string key] - { - get - { - VerVar result = vars.FirstOrDefault(v => String.Compare(key, v.Key, true) == 0); - - return result; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Version/VerString.cs b/Src/Workshell.PE.Resources/Version/VerString.cs deleted file mode 100644 index 8fdd3c5..0000000 --- a/Src/Workshell.PE.Resources/Version/VerString.cs +++ /dev/null @@ -1,93 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Resources -{ - - public sealed class VerString - { - - private ushort len; - private ushort val_len; - private ushort type; - private string key; - private string value; - - internal VerString(Stream stream) - { - len = Utils.ReadUInt16(stream); - val_len = Utils.ReadUInt16(stream); - type = Utils.ReadUInt16(stream); - key = Utils.ReadUnicodeString(stream); - - if (stream.Position % 4 != 0) - Utils.ReadUInt16(stream); - - value = Utils.ReadUnicodeString(stream, val_len); - } - - #region Methods - - public override string ToString() - { - return String.Format("{0} = {1}", key, value); - } - - #endregion - - #region Properties - - public string Key - { - get - { - return key; - } - } - - public string Value - { - get - { - return value; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Version/VerStringTable.cs b/Src/Workshell.PE.Resources/Version/VerStringTable.cs deleted file mode 100644 index 4cb7302..0000000 --- a/Src/Workshell.PE.Resources/Version/VerStringTable.cs +++ /dev/null @@ -1,149 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Resources -{ - - public sealed class VerStringTable : IEnumerable - { - - private ushort len; - private ushort val_len; - private ushort type; - private string key; - private List strings; - - internal VerStringTable(Stream stream) - { - int count = 0; - - len = Utils.ReadUInt16(stream); - val_len = Utils.ReadUInt16(stream); - type = Utils.ReadUInt16(stream); - - count += 3 * sizeof(ushort); - - key = Utils.ReadUnicodeString(stream); - - count += (key.Length + 1) * sizeof(ushort); - - if (stream.Position % 4 != 0) - { - Utils.ReadUInt16(stream); - - count += sizeof(ushort); - } - - strings = new List(); - - byte[] buffer = Utils.ReadBytes(stream, len - count); - - using (MemoryStream mem = new MemoryStream(buffer)) - { - while (mem.Position < mem.Length) - { - VerString str = new VerString(mem); - - strings.Add(str); - - if (mem.Position % 4 != 0) - Utils.ReadUInt16(mem); - } - } - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < strings.Count; i++) - yield return strings[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Count: {0:n0}", strings.Count); - } - - #endregion - - #region Properties - - public string Key - { - get - { - return key; - } - } - - public int Count - { - get - { - return strings.Count; - } - } - - public VerString this[int index] - { - get - { - return strings[index]; - } - } - - public VerString this[string key] - { - get - { - VerString str = strings.FirstOrDefault(s => String.Compare(key, s.Key, true) == 0); - - return str; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Version/VerVar.cs b/Src/Workshell.PE.Resources/Version/VerVar.cs deleted file mode 100644 index 4eae55b..0000000 --- a/Src/Workshell.PE.Resources/Version/VerVar.cs +++ /dev/null @@ -1,93 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Resources -{ - - public sealed class VerVar - { - - private ushort len; - private ushort val_len; - private ushort type; - private string key; - private uint value; - - internal VerVar(Stream stream) - { - len = Utils.ReadUInt16(stream); - val_len = Utils.ReadUInt16(stream); - type = Utils.ReadUInt16(stream); - key = Utils.ReadUnicodeString(stream); - - if (stream.Position % 4 != 0) - Utils.ReadUInt16(stream); - - value = Utils.ReadUInt32(stream); - } - - #region Methods - - public override string ToString() - { - return String.Format("{0} = 0x{1:X8}", key, value); - } - - #endregion - - #region Properties - - public string Key - { - get - { - return key; - } - } - - public uint Value - { - get - { - return value; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Version/VersionResource.cs b/Src/Workshell.PE.Resources/Version/VersionResource.cs deleted file mode 100644 index b5172f4..0000000 --- a/Src/Workshell.PE.Resources/Version/VersionResource.cs +++ /dev/null @@ -1,169 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class VersionInfo - { - - private VersionResource resource; - private uint language_id; - private FixedFileInfo fixed_file_info; - private StringFileInfo string_file_info; - private VarFileInfo var_file_info; - - internal VersionInfo(VersionResource versionResource, uint languageId, FixedFileInfo fixedInfo, StringFileInfo stringInfo, VarFileInfo varInfo) - { - resource = versionResource; - language_id = languageId; - fixed_file_info = fixedInfo; - string_file_info = stringInfo; - var_file_info = varInfo; - } - - #region Properties - - public VersionResource Resource - { - get - { - return resource; - } - } - - public uint Language - { - get - { - return language_id; - } - } - - public FixedFileInfo Fixed - { - get - { - return fixed_file_info; - } - } - - public StringFileInfo Strings - { - get - { - return string_file_info; - } - } - - public VarFileInfo Var - { - get - { - return var_file_info; - } - } - - #endregion - - } - - public sealed class VersionResource : Resource - { - - public VersionResource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) : base(owningType, directoryEntry) - { - } - - #region Static Methods - - public static bool Register() - { - ResourceId resource_type = new ResourceId(ResourceType.RT_VERSION); - - return ResourceType.Register(resource_type, typeof(VersionResource)); - } - - #endregion - - #region Methods - - public VersionInfo GetInfo() - { - return GetInfo(DEFAULT_LANGUAGE); - } - - public VersionInfo GetInfo(uint languageId) - { - byte[] data = GetBytes(languageId); - - using (MemoryStream mem = new MemoryStream(data)) - { - ushort len = Utils.ReadUInt16(mem); - ushort val_len = Utils.ReadUInt16(mem); - ushort type = Utils.ReadUInt16(mem); - string key = Utils.ReadUnicodeString(mem); - - if (mem.Position % 4 != 0) - Utils.ReadUInt16(mem); - - FixedFileInfo fixed_file_info = new FixedFileInfo(mem); - - if (mem.Position % 4 != 0) - Utils.ReadUInt16(mem); - - StringFileInfo string_file_info = new StringFileInfo(this, mem); - - if (mem.Position % 4 != 0) - Utils.ReadUInt16(mem); - - VarFileInfo var_file_info = new VarFileInfo(this, mem); - - VersionInfo info = new VersionInfo(this, languageId, fixed_file_info, string_file_info, var_file_info); - - return info; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE.Resources/Workshell.PE.Resources.csproj b/Src/Workshell.PE.Resources/Workshell.PE.Resources.csproj deleted file mode 100644 index e94f945..0000000 --- a/Src/Workshell.PE.Resources/Workshell.PE.Resources.csproj +++ /dev/null @@ -1,106 +0,0 @@ - - - - - Debug - AnyCPU - {2B06CBF8-136A-4BEC-8624-861992139489} - Library - Properties - Workshell.PE.Resources - peres - v4.5 - 512 - - - true - full - false - ..\..\Bin\Debug\ - TRACE;DEBUG;SIGNED - prompt - 4 - - - pdbonly - true - ..\..\Bin\Release\ - TRACE;SIGNED - prompt - 4 - - - true - - - Workshell.PE.snk - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {2e173d25-1c2e-4a7b-8b37-d231324d372d} - Workshell.PE - - - - - - - - - \ No newline at end of file diff --git a/Src/Workshell.PE.Resources/Workshell.PE.Resources.nuspec b/Src/Workshell.PE.Resources/Workshell.PE.Resources.nuspec deleted file mode 100644 index 5a7e054..0000000 --- a/Src/Workshell.PE.Resources/Workshell.PE.Resources.nuspec +++ /dev/null @@ -1,25 +0,0 @@ - - - - Workshell.PE.Resources - $version$ - Workshell.PE.Resources - A set of classes for Workshell.PE to help deal with resources. - A set of classes that extends the Workshell.PE class library to help deal with the standard resource types within an executable such as bitmaps, icons, cursors etc. - Workshell Ltd - Workshell Ltd - en-US - https://github.com/Workshell/pe - https://raw.githubusercontent.com/Workshell/pe/master/license.txt - http://img.workshell.co.uk/logo_128.png - pe executable native resources - - - - - - - - - - \ No newline at end of file diff --git a/Src/Workshell.PE/Annotations/EnumAnnotationAttribute.cs b/Src/Workshell.PE/Annotations/EnumAnnotationAttribute.cs index 5abfa81..d56a3f2 100644 --- a/Src/Workshell.PE/Annotations/EnumAnnotationAttribute.cs +++ b/Src/Workshell.PE/Annotations/EnumAnnotationAttribute.cs @@ -1,43 +1,12 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace Workshell.PE.Annotations { - [AttributeUsage(AttributeTargets.Field)] public sealed class EnumAnnotationAttribute : Attribute { - public EnumAnnotationAttribute(string name) { Name = name; @@ -45,14 +14,9 @@ public EnumAnnotationAttribute(string name) #region Properties - public string Name - { - get; - private set; - } + public string Name { get; } + public string Description { get; set; } #endregion - } - } diff --git a/Src/Workshell.PE/Annotations/EnumAnnotations.cs b/Src/Workshell.PE/Annotations/EnumAnnotations.cs index 6c20765..15a0945 100644 --- a/Src/Workshell.PE/Annotations/EnumAnnotations.cs +++ b/Src/Workshell.PE/Annotations/EnumAnnotations.cs @@ -1,47 +1,14 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; namespace Workshell.PE.Annotations { - public sealed class EnumAnnotation { - internal EnumAnnotation(string headerName, Type type, T value, bool isFlags) { HeaderName = headerName; @@ -52,74 +19,52 @@ internal EnumAnnotation(string headerName, Type type, T value, bool isFlags) #region Properties - public string HeaderName - { - get; - private set; - } - - public Type Type - { - get; - private set; - } - - public T Value - { - get; - private set; - } - - public bool IsFlags - { - get; - private set; - } + public string HeaderName { get; } + public Type Type { get; } + public T Value { get; } + public bool IsFlags { get; } #endregion - } public sealed class EnumAnnotations : IEnumerable> { - - private List> list; - private int type_size; + private readonly List> _list; public EnumAnnotations() { - list = new List>(); + _list = new List>(); - Type type = typeof(T); + var type = typeof(T); - if (!type.IsEnum) + if (!type.GetTypeInfo().IsEnum) throw new InvalidOperationException(); - FlagsAttribute flags_attr = type.GetCustomAttribute(); - FieldInfo[] fields = type.GetFields(); + var flagsAttr = type.GetTypeInfo().GetCustomAttribute(); + var fields = type.GetFields(); - foreach(FieldInfo field in fields) + foreach(var field in fields) { - EnumAnnotationAttribute attr = field.GetCustomAttribute(); + var attr = field.GetCustomAttribute(); if (attr == null) continue; - EnumAnnotation annotation = new EnumAnnotation(attr.Name,type,(T)field.GetValue(null),flags_attr != null); + var annotation = new EnumAnnotation(attr.Name,type,(T)field.GetValue(null),flagsAttr != null); - list.Add(annotation); + _list.Add(annotation); } - Type underlaying_type = Enum.GetUnderlyingType(typeof(T)); + var underlayingType = Enum.GetUnderlyingType(typeof(T)); - type_size = Marshal.SizeOf(underlaying_type); + TypeSize = Marshal.SizeOf(underlayingType); } #region Methods public IEnumerator> GetEnumerator() { - return list.GetEnumerator(); + return _list.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() @@ -131,42 +76,21 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() #region Properties - public int Count - { - get - { - return list.Count; - } - } - - public EnumAnnotation this[int index] - { - get - { - return list[index]; - } - } + public int Count => _list.Count; + public EnumAnnotation this[int index] => _list[index]; public EnumAnnotation this[T value] { get { - EnumAnnotation annotation = list.FirstOrDefault(a => value.Equals(a.Value)); + var annotation = _list.FirstOrDefault(a => value.Equals(a.Value)); return annotation; } } - public int TypeSize - { - get - { - return type_size; - } - } + public int TypeSize { get; } #endregion - } - } diff --git a/Src/Workshell.PE/Annotations/FieldAnnotation.cs b/Src/Workshell.PE/Annotations/FieldAnnotation.cs deleted file mode 100644 index f266753..0000000 --- a/Src/Workshell.PE/Annotations/FieldAnnotation.cs +++ /dev/null @@ -1,258 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; - -namespace Workshell.PE.Annotations -{ - - public sealed class FieldAnnotation - { - - internal FieldAnnotation(string desc, int arrayLen, bool flags, string name, Type type, object value, int size) - { - Description = desc; - ArrayLength = arrayLen; - Flags = flags; - Name = name; - Type = type; - Value = value; - Size = size; - } - - #region Methods - - public override string ToString() - { - string desc = Description ?? String.Empty; - string value; - - if (Value == null) - { - value = "(null)"; - } - else - { - value = Utils.IntToHex(Value); - } - - string result; - - if (Type.IsArray) - { - result = String.Format("{0} [{1}]",desc,ArrayLength); - } - else - { - result = String.Format("{0} - {1}",desc,value); - } - - return result; - } - - #endregion - - #region Properties - - public string Description - { - get; - private set; - } - - public int ArrayLength - { - get; - private set; - } - - public bool Flags - { - get; - private set; - } - - public string Name - { - get; - private set; - } - - public Type Type - { - get; - private set; - } - - public object Value - { - get; - private set; - } - - public int Size - { - get; - private set; - } - - public bool IsArray - { - get - { - return Type.IsArray; - } - } - - public int ArraySize - { - get - { - if (IsArray) - { - return ArrayLength * Size; - } - else - { - return 0; - } - } - } - - #endregion - - } - - public sealed class FieldAnnotations : IEnumerable - { - - private List annotations; - - internal FieldAnnotations(object annotatedObject) - { - annotations = new List(); - - if (annotatedObject != null) - { - int offset = 0; - - foreach(PropertyInfo prop in annotatedObject.GetType().GetProperties()) - { - FieldAnnotationAttribute attr = prop.GetCustomAttribute(); - - if (attr == null) - continue; - - string desc = attr.Description; - string name = prop.Name; - Type type = prop.PropertyType; - int size = 0; - - if (type.IsArray) - { - size = Marshal.SizeOf(type.GetElementType()); - } - else - { - size = Marshal.SizeOf(type); - } - - object value = prop.GetValue(annotatedObject,null); - FieldAnnotation annotation = new FieldAnnotation(desc,attr.ArrayLength,attr.Flags,name,type,value,size); - - annotations.Add(annotation); - - offset += size; - } - } - } - - #region Static Methods - - public static FieldAnnotations Get(object annotatedObj) - { - return Get(annotatedObj,false); - } - - public static FieldAnnotations Get(object annotatedObj, bool nullEmpty) - { - FieldAnnotations annotations = new FieldAnnotations(annotatedObj); - - if (nullEmpty && annotations.Count == 0) - return null; - - return annotations; - } - - #endregion - - #region Method - - public IEnumerator GetEnumerator() - { - return annotations.GetEnumerator(); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public int Count - { - get - { - return annotations.Count; - } - } - - public FieldAnnotation this[int index] - { - get - { - return annotations[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Annotations/FieldAnnotationAttribute.cs b/Src/Workshell.PE/Annotations/FieldAnnotationAttribute.cs index ac002fa..0d9765b 100644 --- a/Src/Workshell.PE/Annotations/FieldAnnotationAttribute.cs +++ b/Src/Workshell.PE/Annotations/FieldAnnotationAttribute.cs @@ -1,43 +1,12 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace Workshell.PE.Annotations { - [AttributeUsage(AttributeTargets.Property)] public sealed class FieldAnnotationAttribute : Attribute { - public FieldAnnotationAttribute(string desc) { Description = desc; @@ -48,32 +17,11 @@ public FieldAnnotationAttribute(string desc) #region Properties - public string Description - { - get; - set; - } - - public int ArrayLength - { - get; - set; - } - - public bool Flags - { - get; - set; - } - - public Type FlagType - { - get; - set; - } + public string Description { get; set; } + public int ArrayLength { get; set; } + public bool Flags { get; set; } + public Type FlagType { get; set; } #endregion - } - } diff --git a/Src/Workshell.PE/Content/CLR/CLR.cs b/Src/Workshell.PE/Content/CLR/CLR.cs index 9cc0e36..fbda28e 100644 --- a/Src/Workshell.PE/Content/CLR/CLR.cs +++ b/Src/Workshell.PE/Content/CLR/CLR.cs @@ -1,102 +1,48 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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.CLR +namespace Workshell.PE.Content { - - public sealed class CLRContent : ExecutableImageContent + public sealed class CLR : DataContent { - - private CLRHeader header; - private CLRMetaData meta_data; - - internal CLRContent(DataDirectory dataDirectory, Location dataLocation) : base(dataDirectory,dataLocation) + internal CLR(PortableExecutableImage image, DataDirectory directory, Location location, CLRHeader header, CLRMetaData metaData) : base(image, directory, location) { + Header = header; + MetaData = metaData; } #region Static Methods - public static CLRContent Get(ExecutableImage image) + internal static async Task LoadAsync(PortableExecutableImage image) { if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.CLRRuntimeHeader)) return null; - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.CLRRuntimeHeader]; + var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.CLRRuntimeHeader]; - if (DataDirectory.IsNullOrEmpty(directory)) + if (DataDirectory.IsNullOrEmpty(dataDirectory)) return null; - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section); - CLRContent result = new CLRContent(directory, location); + var calc = image.GetCalculator(); + var section = calc.RVAToSection(dataDirectory.VirtualAddress); + var fileOffset = calc.RVAToOffset(section, dataDirectory.VirtualAddress); + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var location = new Location(fileOffset, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, dataDirectory.Size, dataDirectory.Size, section); + var header = await CLRHeader.LoadAsync(image, location).ConfigureAwait(false); + var metaData = await CLRMetaData.LoadAsync(image, header).ConfigureAwait(false); - return result; + return new CLR(image, dataDirectory, location, header, metaData); } #endregion #region Properties - public CLRHeader Header - { - get - { - if (header == null) - header = CLRHeader.Get(this); - - return header; - } - } - - public CLRMetaData MetaData - { - get - { - if (meta_data == null) - meta_data = CLRMetaData.Get(Header); - - return meta_data; - } - } + public CLRHeader Header { get; } + public CLRMetaData MetaData { get; } #endregion - } - } diff --git a/Src/Workshell.PE/Content/CLR/CLRDataDirectory.cs b/Src/Workshell.PE/Content/CLR/CLRDataDirectory.cs index 51a7e99..460854d 100644 --- a/Src/Workshell.PE/Content/CLR/CLRDataDirectory.cs +++ b/Src/Workshell.PE/Content/CLR/CLRDataDirectory.cs @@ -1,49 +1,16 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; - using Workshell.PE.Native; -namespace Workshell.PE.CLR +namespace Workshell.PE.Content { - public sealed class CLRDataDirectory { - - private IMAGE_DATA_DIRECTORY data_dir; - - internal CLRDataDirectory(IMAGE_DATA_DIRECTORY dataDirectory) + internal CLRDataDirectory(uint virtualAddress, uint size) { - data_dir = dataDirectory; + VirtualAddress = virtualAddress; + Size = size; } #region Static Methods @@ -68,31 +35,16 @@ public static bool IsNullOrEmpty(DataDirectory dataDirectory) public override string ToString() { - return String.Format("0x{0:X8}+{1}",data_dir.VirtualAddress,data_dir.Size); + return $"0x{VirtualAddress:X8}+{Size}"; } #endregion #region Properties - public uint VirtualAddress - { - get - { - return data_dir.VirtualAddress; - } - } - - public uint Size - { - get - { - return data_dir.Size; - } - } + public uint VirtualAddress { get; } + public uint Size { get; } #endregion - } - } diff --git a/Src/Workshell.PE/Content/CLR/CLRHeader.cs b/Src/Workshell.PE/Content/CLR/CLRHeader.cs index b967e96..7040e3e 100644 --- a/Src/Workshell.PE/Content/CLR/CLRHeader.cs +++ b/Src/Workshell.PE/Content/CLR/CLRHeader.cs @@ -1,44 +1,15 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Annotations; using Workshell.PE.Extensions; using Workshell.PE.Native; -namespace Workshell.PE.CLR +namespace Workshell.PE.Content { - [Flags] public enum COMImageFlags : int { @@ -58,330 +29,211 @@ public enum COMImageFlags : int Prefer32Bit = 0x20000 } - public sealed class CLRHeader : ISupportsLocation, ISupportsBytes + public sealed class CLRHeader { - - private CLRContent clr; - private Location location; - private IMAGE_COR20_HEADER header; - private Version runtime_version; - private CLRDataDirectory meta_data; - private CLRDataDirectory resources; - private CLRDataDirectory sn_sig; - private CLRDataDirectory code_man_table; - private CLRDataDirectory vtable_fixups; - private CLRDataDirectory export_address_table; - private CLRDataDirectory native_header; - - internal CLRHeader(CLRContent clrContent, Location clrLocation, IMAGE_COR20_HEADER clrHeader) - { - clr = clrContent; - location = clrLocation; - header = clrHeader; - runtime_version = null; - meta_data = null; - resources = null; - sn_sig = null; - code_man_table = null; - vtable_fixups = null; - export_address_table = null; - native_header = null; + private Version _runtimeVersion; + private CLRDataDirectory _metaData; + private CLRDataDirectory _resources; + private CLRDataDirectory _snSig; + private CLRDataDirectory _codeManTable; + private CLRDataDirectory _vtableFixups; + private CLRDataDirectory _exportAddressTable; + private CLRDataDirectory _nativeHeader; + + internal CLRHeader(Location location, IMAGE_COR20_HEADER header) + { + _runtimeVersion = null; + _metaData = null; + _resources = null; + _snSig = null; + _codeManTable = null; + _vtableFixups = null; + _exportAddressTable = null; + _nativeHeader = null; + + Location = location; + HeaderSize = header.cb; + MajorRuntimeVersion = header.MajorRuntimeVersion; + MinorRuntimeVersion = header.MinorRuntimeVersion; + MetaDataAddress = header.MetaData.VirtualAddress; + MetaDataSize = header.MetaData.Size; + Flags = header.Flags; + EntryPointTokenOrVirtualAddress = header.EntryPointTokenOrRVA; + ResourcesAddress = header.Resources.VirtualAddress; + ResourcesSize = header.Resources.Size; + StrongNameSignatureAddress = header.StrongNameSignature.VirtualAddress; + StrongNameSignatureSize = header.StrongNameSignature.Size; + CodeManagerTableAddress = header.CodeManagerTable.VirtualAddress; + CodeManagerTableSize = header.CodeManagerTable.Size; + VTableFixupsAddress = header.VTableFixups.VirtualAddress; + VTableFixupsSize = header.VTableFixups.Size; + ExportAddressTableJumpsAddress = header.ExportAddressTableJumps.VirtualAddress; + ExportAddressTableJumpsSize = header.ExportAddressTableJumps.Size; + ManagedNativeHeaderAddress = header.ManagedNativeHeader.VirtualAddress; + ManagedNativeHeaderSize = header.ManagedNativeHeader.Size; } #region Static Methods - public static CLRHeader Get(CLRContent clr) + internal static async Task LoadAsync(PortableExecutableImage image, Location clrLocation) { - LocationCalculator calc = clr.DataDirectory.Directories.Image.GetCalculator(); - ulong offset = calc.RVAToOffset(clr.DataDirectory.VirtualAddress); - uint size = Utils.SizeOf().ToUInt32(); - ulong image_base = clr.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Section section = calc.RVAToSection(clr.DataDirectory.VirtualAddress); - Location location = new Location(offset, clr.DataDirectory.VirtualAddress, image_base + clr.DataDirectory.VirtualAddress, size, size, section); - Stream stream = clr.DataDirectory.Directories.Image.GetStream(); + var size = Marshal.SizeOf(); + var location = new Location(clrLocation.FileOffset, clrLocation.RelativeVirtualAddress, clrLocation.VirtualAddress, size.ToUInt32(), size.ToUInt32(), clrLocation.Section); + var stream = image.GetStream(); - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); + stream.Seek(clrLocation.FileOffset.ToInt64(), SeekOrigin.Begin); - IMAGE_COR20_HEADER clr_header = Utils.Read(stream, Convert.ToInt32(size)); - CLRHeader result = new CLRHeader(clr, location, clr_header); + IMAGE_COR20_HEADER header; - return result; + try + { + header = await stream.ReadStructAsync(size).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not read CLR header from stream.", ex); + } + + return new CLRHeader(location, header); } #endregion #region Methods - public byte[] GetBytes() - { - Stream stream = clr.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } - public Version GetRuntimeVersion() { - if (runtime_version == null) - runtime_version = new Version(header.MajorRuntimeVersion, header.MinorRuntimeVersion); + if (_runtimeVersion == null) + _runtimeVersion = new Version(MajorRuntimeVersion, MinorRuntimeVersion); - return runtime_version; + return _runtimeVersion; } public CLRDataDirectory GetMetaData() { - if (meta_data == null) - meta_data = new CLRDataDirectory(header.MetaData); + if (_metaData == null) + _metaData = new CLRDataDirectory(MetaDataAddress, MetaDataSize); - return meta_data; + return _metaData; } public COMImageFlags GetFlags() { - return (COMImageFlags)header.Flags; + return (COMImageFlags)Flags; } public CLRDataDirectory GetResources() { - if (resources == null) - resources = new CLRDataDirectory(header.Resources); + if (_resources == null) + _resources = new CLRDataDirectory(ResourcesAddress, ResourcesSize); - return resources; + return _resources; } public CLRDataDirectory GetStrongNameSignature() { - if (sn_sig == null) - sn_sig = new CLRDataDirectory(header.StrongNameSignature); + if (_snSig == null) + _snSig = new CLRDataDirectory(StrongNameSignatureAddress, StrongNameSignatureSize); - return sn_sig; + return _snSig; } public CLRDataDirectory GetCodeManagerTable() { - if (code_man_table == null) - code_man_table = new CLRDataDirectory(header.CodeManagerTable); + if (_codeManTable == null) + _codeManTable = new CLRDataDirectory(CodeManagerTableAddress, CodeManagerTableSize); - return code_man_table; + return _codeManTable; } public CLRDataDirectory GetVTableFixups() { - if (vtable_fixups == null) - vtable_fixups = new CLRDataDirectory(header.VTableFixups); + if (_vtableFixups == null) + _vtableFixups = new CLRDataDirectory(VTableFixupsAddress, VTableFixupsSize); - return vtable_fixups; + return _vtableFixups; } public CLRDataDirectory GetExportAddressTableJumps() { - if (export_address_table == null) - export_address_table = new CLRDataDirectory(header.ExportAddressTableJumps); + if (_exportAddressTable == null) + _exportAddressTable = new CLRDataDirectory(ExportAddressTableJumpsAddress, ExportAddressTableJumpsSize); - return export_address_table; + return _exportAddressTable; } public CLRDataDirectory GetManagedNativeHeader() { - if (native_header == null) - native_header = new CLRDataDirectory(header.ManagedNativeHeader); + if (_nativeHeader == null) + _nativeHeader = new CLRDataDirectory(ManagedNativeHeaderAddress, ManagedNativeHeaderSize); - return native_header; + return _nativeHeader; } #endregion #region Properties - public CLRContent CLR - { - get - { - return clr; - } - } - - public Location Location - { - get - { - return location; - } - } + public Location Location { get; } [FieldAnnotation("Header Size")] - public uint HeaderSize - { - get - { - return header.cb; - } - } + public uint HeaderSize { get; } [FieldAnnotation("Major Runtime Version")] - public ushort MajorRuntimeVersion - { - get - { - return header.MajorRuntimeVersion; - } - } + public ushort MajorRuntimeVersion { get; } [FieldAnnotation("Minor Runtime Version")] - public ushort MinorRuntimeVersion - { - get - { - return header.MinorRuntimeVersion; - } - } + public ushort MinorRuntimeVersion { get; } [FieldAnnotation("MetaData Virtual Address")] - public uint MetaDataAddress - { - get - { - return header.MetaData.VirtualAddress; - } - } + public uint MetaDataAddress { get; } [FieldAnnotation("MetaData Size")] - public uint MetaDataSize - { - get - { - return header.MetaData.Size; - } - } + public uint MetaDataSize { get; } [FieldAnnotation("Flags")] - public uint Flags - { - get - { - return header.Flags; - } - } + public uint Flags { get; } [FieldAnnotation("EntryPoint Token/Virtual Address")] - public uint EntryPointTokenOrVirtualAddress - { - get - { - return header.EntryPointTokenOrRVA; - } - } + public uint EntryPointTokenOrVirtualAddress { get; } [FieldAnnotation("Resources Virtual Address")] - public uint ResourcesAddress - { - get - { - return header.Resources.VirtualAddress; - } - } + public uint ResourcesAddress { get; } [FieldAnnotation("Resources Size")] - public uint ResourcesSize - { - get - { - return header.Resources.Size; - } - } + public uint ResourcesSize { get; } [FieldAnnotation("Strongname Signature Virtual Address")] - public uint StrongNameSignatureAddress - { - get - { - return header.StrongNameSignature.VirtualAddress; - } - } + public uint StrongNameSignatureAddress { get; } [FieldAnnotation("Strongname Signature Size")] - public uint StrongNameSignatureSize - { - get - { - return header.StrongNameSignature.Size; - } - } + public uint StrongNameSignatureSize { get; } [FieldAnnotation("Code Manager Table Virtual Address")] - public uint CodeManagerTableAddress - { - get - { - return header.CodeManagerTable.VirtualAddress; - } - } + public uint CodeManagerTableAddress { get; } [FieldAnnotation("Code Manager Table Size")] - public uint CodeManagerTableSize - { - get - { - return header.CodeManagerTable.Size; - } - } + public uint CodeManagerTableSize { get; } [FieldAnnotation("VTable Fixups Virtual Address")] - public uint VTableFixupsAddress - { - get - { - return header.VTableFixups.VirtualAddress; - } - } + public uint VTableFixupsAddress { get; } [FieldAnnotation("VTable Fixups Size")] - public uint VTableFixupsSize - { - get - { - return header.VTableFixups.Size; - } - } + public uint VTableFixupsSize { get; } [FieldAnnotation("Export Address Table Jumps Virtual Address")] - public uint ExportAddressTableJumpsAddress - { - get - { - return header.ExportAddressTableJumps.VirtualAddress; - } - } + public uint ExportAddressTableJumpsAddress { get; } [FieldAnnotation("Export Address Table Jumps Size")] - public uint ExportAddressTableJumpsSize - { - get - { - return header.CodeManagerTable.Size; - } - } + public uint ExportAddressTableJumpsSize { get; } [FieldAnnotation("Managed Native Header Virtual Address")] - public uint ManagedNativeHeaderAddress - { - get - { - return header.ManagedNativeHeader.VirtualAddress; - } - } + public uint ManagedNativeHeaderAddress { get; } [FieldAnnotation("Managed Native Header Size")] - public uint ManagedNativeHeaderSize - { - get - { - return header.ManagedNativeHeader.Size; - } - } + public uint ManagedNativeHeaderSize { get; } #endregion - } - } + diff --git a/Src/Workshell.PE/Content/CLR/CLRMetaData.cs b/Src/Workshell.PE/Content/CLR/CLRMetaData.cs index 80efb2f..79e89ac 100644 --- a/Src/Workshell.PE/Content/CLR/CLRMetaData.cs +++ b/Src/Workshell.PE/Content/CLR/CLRMetaData.cs @@ -1,67 +1,44 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; +using Workshell.PE.Extensions; -namespace Workshell.PE.CLR +namespace Workshell.PE.Content { - public sealed class CLRMetaData : ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; - internal CLRMetaData(CLRContent clr, Location location, CLRHeader header) + internal CLRMetaData(PortableExecutableImage image, Location location, CLRMetaDataHeader header, CLRMetaDataStreamTable streamTable, + CLRMetaDataStreams streams) { - CLR = clr; + _image = image; + Location = location; - Header = new CLRMetaDataHeader(this); - StreamTable = new CLRMetaDataStreamTable(this); - Streams = new CLRMetaDataStreams(this); + Header = header; + StreamTable = streamTable; + Streams = streams; } #region Static Methods - public static CLRMetaData Get(CLRHeader header) + internal static async Task LoadAsync(PortableExecutableImage image, CLRHeader header) { - LocationCalculator calc = header.CLR.DataDirectory.Directories.Image.GetCalculator(); - ulong image_base = header.CLR.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint rva = header.MetaDataAddress; - ulong va = image_base + rva; - ulong offset = calc.RVAToOffset(rva); - uint size = header.MetaDataSize; - Section section = calc.RVAToSection(rva); - Location location = new Location(offset, rva, va, size, size, section); - CLRMetaData meta_data = new CLRMetaData(header.CLR, location, header); - - return meta_data; + var calc = image.GetCalculator(); + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var rva = header.MetaDataAddress; + var va = imageBase + rva; + var offset = calc.RVAToOffset(rva); + var size = header.MetaDataSize; + var section = calc.RVAToSection(rva); + var location = new Location(offset, rva, va, size, size, section); + var metaDataHeader = await CLRMetaDataHeader.LoadAsync(image, location).ConfigureAwait(false); + var metaDataStreamTable = await CLRMetaDataStreamTable.LoadAsync(image, metaDataHeader).ConfigureAwait(false); + var metaDataStreams = await CLRMetaDataStreams.LoadAsync(image, location, metaDataStreamTable).ConfigureAwait(false); + var metaData = new CLRMetaData(image, location, metaDataHeader, metaDataStreamTable, metaDataStreams); + + return metaData; } #endregion @@ -70,48 +47,26 @@ public static CLRMetaData Get(CLRHeader header) public byte[] GetBytes() { - Stream stream = CLR.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; + return GetBytesAsync().GetAwaiter().GetResult(); } - #endregion - - #region Properties - - public CLRContent CLR + public async Task GetBytesAsync() { - get; - private set; - } + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); - public Location Location - { - get; - private set; + return buffer; } - public CLRMetaDataHeader Header - { - get; - private set; - } + #endregion - public CLRMetaDataStreamTable StreamTable - { - get; - private set; - } + #region Properties - public CLRMetaDataStreams Streams - { - get; - private set; - } + public Location Location { get; } + public CLRMetaDataHeader Header { get; } + public CLRMetaDataStreamTable StreamTable { get; } + public CLRMetaDataStreams Streams { get; } #endregion - } - } diff --git a/Src/Workshell.PE/Content/CLR/CLRMetaDataHeader.cs b/Src/Workshell.PE/Content/CLR/CLRMetaDataHeader.cs index 0c09df9..848f19b 100644 --- a/Src/Workshell.PE/Content/CLR/CLRMetaDataHeader.cs +++ b/Src/Workshell.PE/Content/CLR/CLRMetaDataHeader.cs @@ -1,164 +1,124 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Annotations; using Workshell.PE.Extensions; -namespace Workshell.PE.CLR +namespace Workshell.PE.Content { - public sealed class CLRMetaDataHeader : ISupportsLocation, ISupportsBytes { + public const uint CLR_METADATA_SIGNATURE = 0x424A5342; - private const uint CLR_METADATA_SIGNATURE = 0x424A5342; + private readonly PortableExecutableImage _image; - internal CLRMetaDataHeader(CLRMetaData metaData) + internal CLRMetaDataHeader(PortableExecutableImage image, Location location) { - LocationCalculator calc = metaData.CLR.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = metaData.CLR.DataDirectory.Directories.Image.GetStream(); - ulong image_base = metaData.CLR.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint rva = metaData.Location.RelativeVirtualAddress; - ulong va = metaData.Location.VirtualAddress; - ulong offset = metaData.Location.FileOffset; - uint size = 0; - Section section = metaData.Location.Section; - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - MetaData = metaData; - Signature = Utils.ReadUInt32(stream); - - if (Signature != CLR_METADATA_SIGNATURE) - throw new ExecutableImageException("Incorrect signature found in CLR meta-data header."); - - MajorVersion = Utils.ReadUInt16(stream); - MinorVersion = Utils.ReadUInt16(stream); - Reserved = Utils.ReadUInt32(stream); - VersionLength = Utils.ReadUInt32(stream); - Version = Utils.ReadString(stream, VersionLength); - Flags = Utils.ReadUInt16(stream); - Streams = Utils.ReadUInt16(stream); - - size = sizeof(uint) + sizeof(ushort) + sizeof(ushort) + sizeof(uint) + sizeof(uint) + VersionLength + sizeof(ushort) + sizeof(ushort); - - Location = new Location(offset, rva, va, size, size, section); + _image = image; + + Location = location; } - #region Methods + #region Static Methods - public byte[] GetBytes() + public static async Task LoadAsync(PortableExecutableImage image, Location mdLocation) { - Stream stream = MetaData.CLR.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; + try + { + var stream = image.GetStream(); + var rva = mdLocation.RelativeVirtualAddress; + var va = mdLocation.VirtualAddress; + var offset = mdLocation.FileOffset; + var section = mdLocation.Section; + + stream.Seek(offset.ToInt64(), SeekOrigin.Begin); + + var signature = await stream.ReadUInt32Async().ConfigureAwait(false); + + if (signature != CLR_METADATA_SIGNATURE) + throw new PortableExecutableImageException(image, "Incorrect signature found in CLR meta-data header."); + + var majorVersion = await stream.ReadUInt16Async().ConfigureAwait(false); + var minorVersion = await stream.ReadUInt16Async().ConfigureAwait(false); + var reserved = await stream.ReadUInt32Async().ConfigureAwait(false); + var versionLength = await stream.ReadInt32Async().ConfigureAwait(false); + var version = await stream.ReadStringAsync(versionLength).ConfigureAwait(false); + var flags = await stream.ReadUInt16Async().ConfigureAwait(false); + var streams = await stream.ReadUInt16Async().ConfigureAwait(false); + var size = sizeof(uint) + sizeof(ushort) + sizeof(ushort) + sizeof(uint) + sizeof(uint) + versionLength + sizeof(ushort) + sizeof(ushort); + var location = new Location(offset, rva, va, size.ToUInt32(), size.ToUInt32(), section); + var header = new CLRMetaDataHeader(image, location) + { + Signature = signature, + MajorVersion = majorVersion, + MinorVersion = minorVersion, + Reserved = reserved, + VersionLength = versionLength, + Version = version, + Flags = flags, + Streams = streams + }; + + return header; + } + catch (Exception ex) + { + if (ex is PortableExecutableImageException) + throw; + + throw new PortableExecutableImageException(image, "Could not read CLR meta-data header from stream.", ex); + } } #endregion - #region Properties + #region Methods - public CLRMetaData MetaData + public byte[] GetBytes() { - get; - private set; + return GetBytesAsync().GetAwaiter().GetResult(); } - public Location Location + public async Task GetBytesAsync() { - get; - private set; + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); + + return buffer; } + #endregion + + #region Properties + + public Location Location { get; } + [FieldAnnotation("Signature")] - public uint Signature - { - get; - private set; - } + public uint Signature { get; private set; } [FieldAnnotation("Major Version")] - public ushort MajorVersion - { - get; - private set; - } + public ushort MajorVersion { get; private set; } [FieldAnnotation("Minor Version")] - public ushort MinorVersion - { - get; - private set; - } + public ushort MinorVersion { get; private set; } [FieldAnnotation("Reserved")] - public uint Reserved - { - get; - private set; - } + public uint Reserved { get; private set; } [FieldAnnotation("Version String Length")] - public uint VersionLength - { - get; - private set; - } + public int VersionLength { get; private set; } [FieldAnnotation("Version String")] - public string Version - { - get; - private set; - } + public string Version { get; private set; } [FieldAnnotation("Flags")] - public ushort Flags - { - get; - private set; - } + public ushort Flags { get; private set; } [FieldAnnotation("Number of Streams")] - public ushort Streams - { - get; - private set; - } + public ushort Streams { get; private set; } #endregion - } - } diff --git a/Src/Workshell.PE/Content/CLR/CLRMetaDataStream.cs b/Src/Workshell.PE/Content/CLR/CLRMetaDataStream.cs index 2220782..22c9599 100644 --- a/Src/Workshell.PE/Content/CLR/CLRMetaDataStream.cs +++ b/Src/Workshell.PE/Content/CLR/CLRMetaDataStream.cs @@ -1,56 +1,29 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; -using Workshell.MoreLinq; +using Workshell.PE.Extensions; -namespace Workshell.PE.CLR +namespace Workshell.PE.Content { - public sealed class CLRMetaDataStream : ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; - internal CLRMetaDataStream(CLRMetaDataStreams streams, CLRMetaDataStreamTableEntry tableEntry, ulong imageBase) + internal CLRMetaDataStream(PortableExecutableImage image, Location mdLocation, ulong imageBase, CLRMetaDataStreamTableEntry tableEntry) { - Streams = streams; - TableEntry = tableEntry; + _image = image; - LocationCalculator calc = streams.MetaData.CLR.DataDirectory.Directories.Image.GetCalculator(); - ulong offset = streams.MetaData.Location.FileOffset + tableEntry.Offset; - uint rva = calc.OffsetToRVA(offset); - ulong va = imageBase + rva; + var calc = image.GetCalculator(); + var offset = mdLocation.FileOffset + tableEntry.Offset; + var rva = calc.OffsetToRVA(offset); + var va = imageBase + rva; - Location = new Location(offset,rva,va,tableEntry.Size,tableEntry.Size); + Location = new Location(calc, offset, rva, va, tableEntry.Size, tableEntry.Size); + TableEntry = tableEntry; Name = tableEntry.Name; } @@ -59,168 +32,72 @@ internal CLRMetaDataStream(CLRMetaDataStreams streams, CLRMetaDataStreamTableEnt public override string ToString() { return Name; - } - - public byte[] GetBytes() - { - Stream stream = Streams.MetaData.CLR.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public CLRMetaDataStreams Streams - { - get; - private set; } - public CLRMetaDataStreamTableEntry TableEntry + public byte[] GetBytes() { - get; - private set; + return GetBytesAsync().GetAwaiter().GetResult(); } - public Location Location + public async Task GetBytesAsync() { - get; - private set; - } + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); - public string Name - { - get; - private set; + return buffer; } - #endregion - - } - - public sealed class CLRMetaDataStreams : IEnumerable, ISupportsLocation, ISupportsBytes - { - - private CLRMetaData meta_data; - private CLRMetaDataStream[] streams; - private Location location; - - internal CLRMetaDataStreams(CLRMetaData metaData) + public Stream GetStream() { - ulong image_base = metaData.CLR.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - - meta_data = metaData; - streams = new CLRMetaDataStream[metaData.StreamTable.Count]; - - for(var i = 0; i < streams.Length; i++) - { - CLRMetaDataStreamTableEntry entry = metaData.StreamTable[i]; - CLRMetaDataStream stream = new CLRMetaDataStream(this, entry, image_base); - - streams[i] = stream; - } - - Section section = null; - uint rva = 0; - ulong va = 0; - ulong offset = 0; - ulong size = 0; - - if (streams.Length > 0) - { - CLRMetaDataStream stream = streams.MinBy(s => s.Location.FileOffset); - - section = stream.Location.Section; - rva = stream.Location.RelativeVirtualAddress; - va = stream.Location.VirtualAddress; - offset = stream.Location.FileOffset; - } + var buffer = GetBytes(); - foreach (var stream in streams) - size += stream.Location.FileSize; - - location = new Location(offset, rva, va, size, size, section); + return new MemoryStream(buffer); } - #region Methods - - public IEnumerator GetEnumerator() + public async Task GetStreamAsync() { - for(var i = 0; i < streams.Length; i++) - { - yield return streams[i]; - } - } + var buffer = await GetBytesAsync().ConfigureAwait(false); - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); + return new MemoryStream(buffer); } - public override string ToString() + public long CopyTo(Stream stream, int bufferSize = 4096) { - return String.Format("Stream Count: {0}",streams.Length); + return CopyToAsync(stream, bufferSize).GetAwaiter().GetResult(); } - public byte[] GetBytes() + public async Task CopyToAsync(Stream stream, int bufferSize = 4096) { - Stream stream = meta_data.CLR.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); + if (bufferSize < 1) + bufferSize = 4096; - return buffer; - } + var count = 0L; - #endregion - - #region Properties - - public CLRMetaData MetaData - { - get + using (var mem = await GetStreamAsync().ConfigureAwait(false)) { - return meta_data; - } - } + var buffer = new byte[bufferSize]; + var numRead = await mem.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); - public Location Location - { - get - { - return location; - } - } + while (numRead > 0) + { + await stream.WriteAsync(buffer, 0, numRead).ConfigureAwait(false); - public int Count - { - get - { - return streams.Length; + count += numRead; + numRead = await mem.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + } } - } - public CLRMetaDataStream this[int index] - { - get - { - return streams[index]; - } + return count; } - public CLRMetaDataStream this[string name] - { - get - { - CLRMetaDataStream stream = streams.FirstOrDefault(s => String.Compare(name,s.Name,StringComparison.OrdinalIgnoreCase) == 0); + #endregion - return stream; - } - } + #region Properties + + public Location Location { get; } + public CLRMetaDataStreamTableEntry TableEntry { get; } + public string Name { get; } #endregion - } - } diff --git a/Src/Workshell.PE/Content/CLR/CLRMetaDataStreamTable.cs b/Src/Workshell.PE/Content/CLR/CLRMetaDataStreamTable.cs index 602ef22..a3fb20f 100644 --- a/Src/Workshell.PE/Content/CLR/CLRMetaDataStreamTable.cs +++ b/Src/Workshell.PE/Content/CLR/CLRMetaDataStreamTable.cs @@ -1,200 +1,95 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Extensions; -namespace Workshell.PE.CLR +namespace Workshell.PE.Content { - - public sealed class CLRMetaDataStreamTableEntry : ISupportsLocation, ISupportsBytes + public sealed class CLRMetaDataStreamTable : IEnumerable, ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; + private readonly CLRMetaDataStreamTableEntry[] _entries; - internal CLRMetaDataStreamTableEntry(CLRMetaDataStreamTable streamTable, Location streamLocation, uint streamOffset, uint streamSize, string streamName) - { - Table = streamTable; - Location = streamLocation; - Offset = streamOffset; - Size = streamSize; - Name = streamName; - } - - #region Methods - - public override string ToString() - { - return String.Format("Offset: 0x{0:X8}, Size: {1}, Name: {2}",Offset,Size,Name); - } - - public byte[] GetBytes() + internal CLRMetaDataStreamTable(PortableExecutableImage image, Location location, CLRMetaDataStreamTableEntry[] entries) { - Stream stream = Table.MetaData.CLR.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); + _image = image; + _entries = entries; - return buffer; + Location = location; + Count = _entries.Length; } - #endregion - - #region Properties + #region Static Methods - public CLRMetaDataStreamTable Table + public static async Task LoadAsync(PortableExecutableImage image, CLRMetaDataHeader header) { - get; - private set; - } - - public Location Location - { - get; - private set; - } - - public uint Offset - { - get; - private set; - } - - public uint Size - { - get; - private set; - } - - public string Name - { - get; - private set; - } - - #endregion - - } - - public sealed class CLRMetaDataStreamTable : IEnumerable, ISupportsLocation, ISupportsBytes - { - - private CLRMetaData meta_data; - private CLRMetaDataStreamTableEntry[] entries; - private Location location; - - internal CLRMetaDataStreamTable(CLRMetaData metaData) - { - LocationCalculator calc = metaData.CLR.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = metaData.CLR.DataDirectory.Directories.Image.GetStream(); - ulong image_base = metaData.CLR.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong offset = metaData.Header.Location.FileOffset + metaData.Header.Location.FileSize; - - meta_data = metaData; - entries = LoadTable(metaData,calc,stream,offset,image_base); - - uint rva = calc.OffsetToRVA(offset); - ulong va = image_base + rva; - ulong size = 0; - - foreach (var strm in entries) - size += strm.Location.FileSize; - - Section section = calc.RVAToSection(rva); + try + { + var calc = image.GetCalculator(); + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var offset = header.Location.FileOffset + header.Location.FileSize; + var rva = calc.OffsetToRVA(offset); + var va = imageBase + rva; + var entries = await LoadTableAsync(image, header, offset, imageBase).ConfigureAwait(false); + ulong size = 0; - location = new Location(offset,rva,va,size,size,section); - } + foreach (var strm in entries) + size += strm.Location.FileSize; - #region Methods + var section = calc.RVAToSection(rva); + var location = new Location(offset,rva,va,size,size,section); - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) + return new CLRMetaDataStreamTable(image, location, entries); + } + catch (Exception ex) { - yield return entries[i]; + throw new PortableExecutableImageException(image, "Could not read CLR meta-data streams table from stream.", ex); } } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Stream Entry Count: {0}",entries.Length); - } - - public byte[] GetBytes() + private static async Task LoadTableAsync(PortableExecutableImage image, CLRMetaDataHeader header, ulong baseOffset, ulong imageBase) { - Stream stream = meta_data.CLR.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } + var stream = image.GetStream(); - private CLRMetaDataStreamTableEntry[] LoadTable(CLRMetaData metaData, LocationCalculator calc, Stream stream, ulong baseOffset, ulong imageBase) - { stream.Seek(baseOffset.ToInt64(),SeekOrigin.Begin); - List entries = new List(); - ulong offset = baseOffset; + var entries = new List(); + var offset = baseOffset; - for(int i = 0; i < metaData.Header.Streams; i++) + for(var i = 0; i < header.Streams; i++) { - uint size = 0; - uint stream_offset = Utils.ReadUInt32(stream); + var size = 0U; + var streamOffset = await stream.ReadUInt32Async().ConfigureAwait(false); size += sizeof(uint); - uint stream_size = Utils.ReadUInt32(stream); + var streamSize = await stream.ReadUInt32Async().ConfigureAwait(false); size += sizeof(uint); - StringBuilder stream_name = new StringBuilder(256); + var streamName = new StringBuilder(256); while (true) { - int b = stream.ReadByte(); + var b = await stream.ReadByteAsync().ConfigureAwait(false); + size += 1; if (b <= 0) break; - stream_name.Append((char)b); + streamName.Append((char)b); } while (true) { if (stream.Position % 4 != 0) { - stream.ReadByte(); + await stream.ReadByteAsync().ConfigureAwait(false); size += 1; } else @@ -203,13 +98,15 @@ private CLRMetaDataStreamTableEntry[] LoadTable(CLRMetaData metaData, LocationCa } } - uint rva = calc.OffsetToRVA(offset); - ulong va = imageBase + rva; - Section section = calc.RVAToSection(rva); - Location entry_location = new Location(offset,rva,va,size,size,section); - CLRMetaDataStreamTableEntry entry = new CLRMetaDataStreamTableEntry(this,entry_location,stream_offset,stream_size,stream_name.ToString()); + var calc = image.GetCalculator(); + var rva = calc.OffsetToRVA(offset); + var va = imageBase + rva; + var section = calc.RVAToSection(rva); + var location = new Location(offset, rva, va, size, size, section); + var entry = new CLRMetaDataStreamTableEntry(image, location, streamOffset, streamSize, streamName.ToString()); entries.Add(entry); + offset += size; } @@ -218,52 +115,41 @@ private CLRMetaDataStreamTableEntry[] LoadTable(CLRMetaData metaData, LocationCa #endregion - #region Properties - - public CLRMetaData MetaData - { - get - { - return meta_data; - } - } + #region Methods - public Location Location + public IEnumerator GetEnumerator() { - get - { - return location; - } + foreach (var entry in _entries) + yield return entry; } - public int Count + IEnumerator IEnumerable.GetEnumerator() { - get - { - return entries.Length; - } + return GetEnumerator(); } - public CLRMetaDataStreamTableEntry this[int index] + public byte[] GetBytes() { - get - { - return entries[index]; - } + return GetBytesAsync().GetAwaiter().GetResult(); } - public CLRMetaDataStreamTableEntry this[string name] + public async Task GetBytesAsync() { - get - { - CLRMetaDataStreamTableEntry entry = entries.FirstOrDefault(stream => String.Compare(name,stream.Name,StringComparison.OrdinalIgnoreCase) == 0); + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); - return entry; - } + return buffer; } #endregion - } + #region Properties + + public Location Location { get; } + public int Count { get; } + public CLRMetaDataStreamTableEntry this[int index] => _entries[index]; + public CLRMetaDataStreamTableEntry this[string name] => _entries.SingleOrDefault(entry => string.Compare(name, entry.Name, StringComparison.OrdinalIgnoreCase) == 0); + #endregion + } } diff --git a/Src/Workshell.PE/Content/Certificates/Certificate.cs b/Src/Workshell.PE/Content/Certificates/Certificate.cs deleted file mode 100644 index 5cf3299..0000000 --- a/Src/Workshell.PE/Content/Certificates/Certificate.cs +++ /dev/null @@ -1,158 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Certificates -{ - - public enum CertificateType : ushort - { - X509Certificate = 0x0001, - PKCSSignedData = 0x0002, - Reserved = 0x0003, - PKCS1ModuleSign = 0x0009 - } - - public sealed class Certificate : ExecutableImageContent, ISupportsBytes - { - - private WIN_CERTIFICATE cert; - - internal Certificate(DataDirectory dataDirectory, Location certLocation, WIN_CERTIFICATE winCert) : base(dataDirectory,certLocation) - { - cert = winCert; - } - - #region Static Methods - - public static Certificate Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.CertificateTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.CertificateTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - Stream stream = directory.Directories.Image.GetStream(); - long file_offset = directory.VirtualAddress.ToInt64(); - - stream.Seek(file_offset, SeekOrigin.Begin); - - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(directory.VirtualAddress, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size); - WIN_CERTIFICATE win_cert = Utils.Read(stream); - Certificate cert = new Certificate(directory, location, win_cert); - - return cert; - } - - #endregion - - #region Methods - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - public CertificateType GetCertificateType() - { - return (CertificateType)cert.wCertificateType; - } - - public byte[] GetData() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - ulong offset = Location.FileOffset + Utils.SizeOf().ToUInt32(); - byte[] buffer = Utils.ReadBytes(stream, offset.ToInt64(), cert.dwLength); - - return buffer; - } - - public X509Certificate GetCertificate() - { - if (cert.wCertificateType == 1 || cert.wCertificateType == 2) // X.509 or PKCS#7 - { - byte[] data = GetData(); - X509Certificate2 certificate = new X509Certificate2(data); - - return certificate; - } - else - { - return null; - } - } - - #endregion - - #region Properties - - public uint Length - { - get - { - return cert.dwLength; - } - } - - public ushort Revision - { - get - { - return cert.wRevision; - } - } - - public ushort CertificateType - { - get - { - return cert.wCertificateType; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Debug/DebugData.cs b/Src/Workshell.PE/Content/Debug/DebugData.cs deleted file mode 100644 index a78033d..0000000 --- a/Src/Workshell.PE/Content/Debug/DebugData.cs +++ /dev/null @@ -1,114 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Native; - -namespace Workshell.PE.Debug -{ - - public sealed class DebugData : ISupportsLocation, ISupportsBytes - { - - private DebugDirectoryEntry entry; - private Location location; - - internal DebugData(DebugDirectoryEntry directorEntry, Location dataLocation) - { - entry = directorEntry; - location = dataLocation; - } - - #region Static Methods - - public static DebugData Get(DebugDirectoryEntry entry) - { - if (entry.PointerToRawData == 0 && entry.SizeOfData == 0) - return null; - - LocationCalculator calc = entry.Directory.DataDirectory.Directories.Image.GetCalculator(); - uint rva = entry.AddressOfRawData; - Section section = calc.RVAToSection(rva); - ulong image_base = entry.Directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(entry.PointerToRawData, rva, image_base + rva, entry.SizeOfData, entry.SizeOfData, section); - DebugData data = new DebugData(entry, location); - - return data; - } - - #endregion - - #region Methods - - public override string ToString() - { - string type = entry.GetEntryType().ToString(); - - return String.Format("Debug Type: {0}, File Offset: 0x{1:X8}, Size: 0x{2:X8}", type, location.FileOffset, location.FileSize); - } - - public byte[] GetBytes() - { - Stream stream = entry.Directory.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, location); - - return buffer; - } - - #endregion - - #region Properties - - public DebugDirectoryEntry Entry - { - get - { - return entry; - } - } - - public Location Location - { - get - { - return location; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Debug/DebugDirectory.cs b/Src/Workshell.PE/Content/Debug/DebugDirectory.cs deleted file mode 100644 index 9212a53..0000000 --- a/Src/Workshell.PE/Content/Debug/DebugDirectory.cs +++ /dev/null @@ -1,349 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Debug -{ - - public enum DebugDirectoryEntryType - { - [EnumAnnotation("IMAGE_DEBUG_TYPE_UNKNOWN")] - Unknown = 0, - [EnumAnnotation("IMAGE_DEBUG_TYPE_COFF")] - COFF = 1, - [EnumAnnotation("IMAGE_DEBUG_TYPE_CODEVIEW")] - CodeView = 2, - [EnumAnnotation("IMAGE_DEBUG_TYPE_FPO")] - FPO = 3, - [EnumAnnotation("IMAGE_DEBUG_TYPE_MISC")] - Misc = 4, - [EnumAnnotation("IMAGE_DEBUG_TYPE_EXCEPTION")] - Exception = 5, - [EnumAnnotation("IMAGE_DEBUG_TYPE_FIXUP")] - Fixup = 6, - [EnumAnnotation("IMAGE_DEBUG_TYPE_OMAP_TO_SRC")] - OMAPToSrc = 7, - [EnumAnnotation("IMAGE_DEBUG_TYPE_OMAP_FROM_SRC")] - OMAPFromSrc = 8, - [EnumAnnotation("IMAGE_DEBUG_TYPE_BORLAND")] - Bolrand = 9, - [EnumAnnotation("IMAGE_DEBUG_TYPE_RESERVED10")] - Reserved = 10, - [EnumAnnotation("IMAGE_DEBUG_TYPE_CLSID")] - CLSID = 11, - [EnumAnnotation("IMAGE_DEBUG_TYPE_VC_FEATURE")] - VCFeature = 12, - [EnumAnnotation("IMAGE_DEBUG_TYPE_POGO")] - POGO = 13, - [EnumAnnotation("IMAGE_DEBUG_TYPE_ILTCG")] - ILTCG = 14, - [EnumAnnotation("IMAGE_DEBUG_TYPE_MPX")] - MPX = 15 - } - - public sealed class DebugDirectoryEntry : ISupportsLocation, ISupportsBytes - { - - public static readonly int size = Utils.SizeOf(); - - private DebugDirectory directories; - private Location location; - private IMAGE_DEBUG_DIRECTORY directory; - private DebugData data; - - internal DebugDirectoryEntry(DebugDirectory debugDirs, Location dirLocation, IMAGE_DEBUG_DIRECTORY dir) - { - directories = debugDirs; - location = dirLocation; - directory = dir; - data = null; - } - - #region Methods - - public override string ToString() - { - return String.Format("Debug Type: {0}", GetEntryType()); - } - - public byte[] GetBytes() - { - Stream stream = directories.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, location); - - return buffer; - } - - public DateTime GetTimeDateStamp() - { - return Utils.ConvertTimeDateStamp(directory.TimeDateStamp); - } - - public DebugDirectoryEntryType GetEntryType() - { - return (DebugDirectoryEntryType)directory.Type; - } - - public DebugData GetData() - { - if (data == null) - data = DebugData.Get(this); - - return data; - } - - #endregion - - #region Properties - - public DebugDirectory Directory - { - get - { - return directories; - } - } - - public Location Location - { - get - { - return location; - } - } - - [FieldAnnotation("Characteristics")] - public uint Characteristics - { - get - { - return directory.Characteristics; - } - } - - [FieldAnnotation("Date/Time Stamp")] - public uint TimeDateStamp - { - get - { - return directory.TimeDateStamp; - } - } - - [FieldAnnotation("Major Version")] - public ushort MajorVersion - { - get - { - return directory.MajorVersion; - } - } - - [FieldAnnotation("Minor Version")] - public ushort MinorVersion - { - get - { - return directory.MinorVersion; - } - } - - [FieldAnnotation("Type")] - public uint Type - { - get - { - return directory.Type; - } - } - - [FieldAnnotation("Size of Data")] - public uint SizeOfData - { - get - { - return directory.SizeOfData; - } - } - - [FieldAnnotation("Address of Raw Data")] - public uint AddressOfRawData - { - get - { - return directory.AddressOfRawData; - } - } - - [FieldAnnotation("Pointer to Raw Data")] - public uint PointerToRawData - { - get - { - return directory.PointerToRawData; - } - } - - #endregion - - } - - public sealed class DebugDirectory : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private DebugDirectoryEntry[] entries; - - internal DebugDirectory(DataDirectory dataDirectory, Location dirLocation, Tuple[] dirs) : base(dataDirectory,dirLocation) - { - entries = LoadEntries(dirs); - } - - #region Static Methods - - public static DebugDirectory Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.Debug)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.Debug]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - int size = Utils.SizeOf(); - long count = directory.Size / size; - Tuple[] directories = new Tuple[count]; - - for (var i = 0; i < count; i++) - { - IMAGE_DEBUG_DIRECTORY entry = Utils.Read(stream, size); - - directories[i] = new Tuple(file_offset, entry); - } - - DebugDirectory debug_dir = new DebugDirectory(directory, location, directories); - - return debug_dir; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) - { - yield return entries[i]; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Debug Entry Count: {0}", entries.Length); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, Location); - - return buffer; - } - - private DebugDirectoryEntry[] LoadEntries(Tuple[] directoryEntries) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - ulong image_base = DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint size = Utils.SizeOf().ToUInt32(); - DebugDirectoryEntry[] results = new DebugDirectoryEntry[directoryEntries.Length]; - - for(var i = 0; i < directoryEntries.Length; i++) - { - Tuple tuple = directoryEntries[i]; - uint rva = calc.OffsetToRVA(tuple.Item1); - Section section = calc.RVAToSection(rva); - ulong va = image_base + rva; - Location dir_location = new Location(tuple.Item1, rva, va, size, size, section); - DebugDirectoryEntry entry = new DebugDirectoryEntry(this, dir_location, tuple.Item2); - - results[i] = entry; - } - - return results; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return entries.Length; - } - } - - public DebugDirectoryEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Delayed Imports/DelayImportAddressTable.cs b/Src/Workshell.PE/Content/Delayed Imports/DelayImportAddressTable.cs deleted file mode 100644 index 75708c4..0000000 --- a/Src/Workshell.PE/Content/Delayed Imports/DelayImportAddressTable.cs +++ /dev/null @@ -1,510 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.MoreLinq; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Imports -{ - - public sealed class DelayImportAddressTableEntry : ISupportsLocation, ISupportsBytes - { - - private DelayImportAddressTable table; - private Location location; - private ulong value; - private uint address; - private ushort ordinal; - private bool is_ordinal; - - internal DelayImportAddressTableEntry(DelayImportAddressTable addressTable, ulong entryOffset, ulong entryValue, uint entryAddress, ushort entryOrdinal, bool isOrdinal) - { - bool is_64bit = addressTable.Tables.DataDirectory.Directories.Image.Is64Bit; - LocationCalculator calc = addressTable.Tables.DataDirectory.Directories.Image.GetCalculator(); - uint rva = calc.OffsetToRVA(entryOffset); - ulong image_base = addressTable.Tables.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong size = (is_64bit ? sizeof(ulong) : sizeof(uint)).ToUInt64(); - - table = addressTable; - location = new Location(entryOffset,rva,va,size,size); - value = entryValue; - address = entryAddress; - ordinal = entryOrdinal; - is_ordinal = isOrdinal; - } - - #region Methods - - public override string ToString() - { - string result = String.Format("File Offset: 0x{0:X8}, ",location.FileOffset); - - if (!is_ordinal) - { - if (location.FileSize == sizeof(ulong)) - { - result += String.Format("Address: 0x{0:X16}",address); - } - else - { - result = String.Format("Address: 0x{0:X8}",address); - } - } - else - { - result = String.Format("Ordinal: 0x{0:D4}",ordinal); - } - - return result; - } - - public byte[] GetBytes() - { - Stream stream = table.Tables.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } - - #endregion - - #region Properties - - public DelayImportAddressTable Table - { - get - { - return table; - } - } - - public Location Location - { - get - { - return location; - } - } - - public ulong Value - { - get - { - return value; - } - } - - public uint Address - { - get - { - return address; - } - } - - public ushort Ordinal - { - get - { - return ordinal; - } - } - - public bool IsOrdinal - { - get - { - return is_ordinal; - } - } - - #endregion - - } - - public sealed class DelayImportAddressTable : IEnumerable, ISupportsLocation, ISupportsBytes - { - - private DelayImportAddressTables tables; - private DelayImportDirectoryEntry dir_entry; - private Location location; - private DelayImportAddressTableEntry[] entries; - - internal DelayImportAddressTable(DelayImportAddressTables addressTables, DelayImportDirectoryEntry directoryEntry, uint tableRVA, ulong[] tableEntries) - { - bool is_64bit = addressTables.DataDirectory.Directories.Image.Is64Bit; - LocationCalculator calc = addressTables.DataDirectory.Directories.Image.GetCalculator(); - uint rva = tableRVA; - ulong image_base = addressTables.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong offset = calc.RVAToOffset(rva); - ulong size = (tableEntries.Count() * (is_64bit ? sizeof(ulong) : sizeof(uint))).ToUInt64(); - Section section = calc.RVAToSection(rva); - - tables = addressTables; - dir_entry = directoryEntry; - location = new Location(offset, rva, va, size, size, section); - entries = LoadEntries(is_64bit, offset, tableEntries); - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) - { - yield return entries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("File Offset: 0x{0:X8}, Table Entry Count: {1}",location.FileOffset,entries.Length); - } - - public byte[] GetBytes() - { - Stream stream = tables.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } - - private DelayImportAddressTableEntry[] LoadEntries(bool is64Bit, ulong tableOffset, ulong[] tableEntries) - { - DelayImportAddressTableEntry[] results = new DelayImportAddressTableEntry[tableEntries.Length]; - ulong offset = tableOffset; - - for(var i = 0; i < tableEntries.Length; i++) - { - ulong addr_or_ord = tableEntries[i]; - ushort ordinal = 0; - bool is_ordinal = false; - - if (!is64Bit) - { - uint value = Convert.ToUInt32(addr_or_ord); - - if ((value & 0x80000000) == 0x80000000) - { - value &= 0x7fffffff; - - ordinal = Convert.ToUInt16(value); - is_ordinal = true; - } - } - else - { - ulong value = addr_or_ord; - - if ((value & 0x8000000000000000) == 0x8000000000000000) - { - value &= 0x7fffffffffffffff; - - ordinal = Convert.ToUInt16(value); - is_ordinal = true; - } - } - - uint address; - - if (is_ordinal) - { - address = 0; - } - else - { - address = Utils.LoDWord(addr_or_ord); - } - - DelayImportAddressTableEntry entry = new DelayImportAddressTableEntry(this, offset, addr_or_ord, address, ordinal, is_ordinal); - - results[i] = entry; - offset += Convert.ToUInt32(is64Bit ? sizeof(ulong) : sizeof(uint)); - } - - return results; - } - - #endregion - - #region Properties - - public DelayImportAddressTables Tables - { - get - { - return tables; - } - } - - public DelayImportDirectoryEntry DirectoryEntry - { - get - { - return dir_entry; - } - } - - public Location Location - { - get - { - return location; - } - } - - public int Count - { - get - { - return entries.Length; - } - } - - public DelayImportAddressTableEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - - public sealed class DelayImportAddressTables : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private DelayImportAddressTable[] tables; - - internal DelayImportAddressTables(DataDirectory dataDirectory, Location dataLocation, Tuple[] addressTables) : base(dataDirectory,dataLocation) - { - tables = new DelayImportAddressTable[addressTables.Length]; - - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - - for (var i = 0; i < addressTables.Length; i++) - { - Tuple tuple = addressTables[i]; - ulong offset = calc.RVAToOffset(tuple.Item1); - DelayImportAddressTable table = new DelayImportAddressTable(this, tuple.Item2, tuple.Item1, tuple.Item3); - - tables[i] = table; - } - } - - #region Static Methods - - public static DelayImportAddressTables GetLookupTable(DelayImportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - bool is_64bit = directory.DataDirectory.Directories.Image.Is64Bit; - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - List> tables = new List>(); - - foreach (DelayImportDirectoryEntry dir_entry in directory) - { - if (dir_entry.DelayNameTable == 0) - continue; - - List entries = new List(); - ulong offset = calc.RVAToOffset(dir_entry.DelayNameTable); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - while (true) - { - ulong entry = (!is_64bit ? Utils.ReadUInt32(stream) : Utils.ReadUInt64(stream)); - - if (entry == 0) - break; - - entries.Add(entry); - } - - Tuple table = new Tuple(dir_entry.DelayNameTable, dir_entry, entries.ToArray()); - - tables.Add(table); - } - - uint rva = 0; - - if (tables.Count > 0) - rva = tables.MinBy(table => table.Item1).Item1; - - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong file_offset = calc.RVAToOffset(rva); - ulong file_size = 0; - - foreach (var table in tables) - { - int size = (table.Item3.Length + 1) * (!is_64bit ? sizeof(uint) : sizeof(ulong)); - - file_size += size.ToUInt32(); - } - - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, file_size, file_size, section); - DelayImportAddressTables result = new DelayImportAddressTables(directory.DataDirectory, location, tables.ToArray()); - - return result; - } - - public static DelayImportAddressTables GetAddressTable(DelayImportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - bool is_64bit = directory.DataDirectory.Directories.Image.Is64Bit; - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - List> tables = new List>(); - - foreach (DelayImportDirectoryEntry dir_entry in directory) - { - if (dir_entry.DelayAddressTable == 0) - continue; - - List entries = new List(); - ulong offset = calc.RVAToOffset(dir_entry.DelayAddressTable); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - while (true) - { - ulong entry = (!is_64bit ? Utils.ReadUInt32(stream) : Utils.ReadUInt64(stream)); - - if (entry == 0) - break; - - entries.Add(entry); - } - - Tuple table = new Tuple(dir_entry.DelayAddressTable, dir_entry, entries.ToArray()); - - tables.Add(table); - } - - uint rva = 0; - - if (tables.Count > 0) - rva = tables.MinBy(table => table.Item1).Item1; - - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong file_offset = calc.RVAToOffset(rva); - ulong file_size = 0; - - foreach (var table in tables) - { - int size = (table.Item3.Length + 1) * (!is_64bit ? sizeof(uint) : sizeof(ulong)); - - file_size += size.ToUInt32(); - } - - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, file_size, file_size, section); - DelayImportAddressTables result = new DelayImportAddressTables(directory.DataDirectory, location, tables.ToArray()); - - return result; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < tables.Length; i++) - { - yield return tables[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("File Offset: 0x{0:X8}, Table Count: {1}",Location.FileOffset,tables.Length); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return tables.Length; - } - } - - public DelayImportAddressTable this[int index] - { - get - { - return tables[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Delayed Imports/DelayImportDirectory.cs b/Src/Workshell.PE/Content/Delayed Imports/DelayImportDirectory.cs deleted file mode 100644 index 0676677..0000000 --- a/Src/Workshell.PE/Content/Delayed Imports/DelayImportDirectory.cs +++ /dev/null @@ -1,308 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Imports -{ - - public sealed class DelayImportDirectoryEntry : ISupportsLocation, ISupportsBytes - { - - private DelayImportDirectory directory; - private IMAGE_DELAY_IMPORT_DESCRIPTOR descriptor; - private Location location; - private string name; - - internal DelayImportDirectoryEntry(DelayImportDirectory importDirectory, IMAGE_DELAY_IMPORT_DESCRIPTOR entry, Location entryLocation) - { - directory = importDirectory; - descriptor = entry; - location = entryLocation; - name = null; - } - - #region Methods - - public override string ToString() - { - return GetName(); - } - - public byte[] GetBytes() - { - int size = Utils.SizeOf(); - byte[] buffer = new byte[size]; - - Utils.Write(descriptor, buffer, 0, size); - - return buffer; - } - - public DateTime GetTimeDateStamp() - { - return Utils.ConvertTimeDateStamp(descriptor.TimeDateStamp); - } - - public string GetName() - { - if (name == null) - { - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - ulong offset = calc.RVAToOffset(descriptor.Name); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - name = Utils.ReadString(stream); - } - - return name; - } - - #endregion - - #region Properties - - public DelayImportDirectory Directory - { - get - { - return directory; - } - } - - public Location Location - { - get - { - return location; - } - } - - [FieldAnnotation("Attributes")] - public uint Attributes - { - get - { - return descriptor.Attributes; - } - } - - [FieldAnnotation("Name")] - public uint Name - { - get - { - return descriptor.Name; - } - } - - [FieldAnnotation("Module Handle")] - public uint ModuleHandle - { - get - { - return descriptor.ModuleHandle; - } - } - - [FieldAnnotation("Delay Import Address Table")] - public uint DelayAddressTable - { - get - { - return descriptor.DelayAddressTable; - } - } - - [FieldAnnotation("Delay Import Hint/Name Table")] - public uint DelayNameTable - { - get - { - return descriptor.DelayNameTable; - } - } - - [FieldAnnotation("Bound Delay Import Address Table")] - public uint BoundDelayIAT - { - get - { - return descriptor.BoundDelayIAT; - } - } - - [FieldAnnotation("Unload Delay Import Address Table")] - public uint UnloadDelayIAT - { - get - { - return descriptor.UnloadDelayIAT; - } - } - - [FieldAnnotation("Date/Time Stamp")] - public uint TimeDateStamp - { - get - { - return descriptor.TimeDateStamp; - } - } - - #endregion - - } - - public sealed class DelayImportDirectory : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private DelayImportDirectoryEntry[] entries; - - internal DelayImportDirectory(DataDirectory dataDirectory, Location dataLocation, IMAGE_DELAY_IMPORT_DESCRIPTOR[] importDescriptors) : base(dataDirectory,dataLocation) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - ulong image_base = dataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong offset = dataLocation.FileOffset; - uint size = Utils.SizeOf().ToUInt32(); - - entries = new DelayImportDirectoryEntry[importDescriptors.Length]; - - for(var i = 0; i < importDescriptors.Length; i++) - { - IMAGE_DELAY_IMPORT_DESCRIPTOR descriptor = importDescriptors[i]; - uint rva = calc.OffsetToRVA(dataLocation.Section, offset); - Section entry_section = calc.RVAToSection(rva); - Location entry_location = new Location(offset, rva, image_base + rva, size, size, entry_section); - DelayImportDirectoryEntry entry = new DelayImportDirectoryEntry(this, descriptor, entry_location); - - entries[i] = entry; - offset += size; - } - } - - #region Static Methods - - public static DelayImportDirectory Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ImportTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.DelayImportDescriptor]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - int size = Utils.SizeOf(); - List descriptors = new List(); - - while (true) - { - IMAGE_DELAY_IMPORT_DESCRIPTOR descriptor = Utils.Read(stream, size); - - if (descriptor.Name == 0 && descriptor.ModuleHandle == 0) - break; - - descriptors.Add(descriptor); - } - - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint total_size = Convert.ToUInt32((descriptors.Count + 1) * size); - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, total_size, total_size, section); - DelayImportDirectory result = new DelayImportDirectory(directory, location, descriptors.ToArray()); - - return result; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) - { - yield return entries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return entries.Length; - } - } - - public DelayImportDirectoryEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Delayed Imports/DelayImportFunction.cs b/Src/Workshell.PE/Content/Delayed Imports/DelayImportFunction.cs deleted file mode 100644 index efaa576..0000000 --- a/Src/Workshell.PE/Content/Delayed Imports/DelayImportFunction.cs +++ /dev/null @@ -1,172 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Imports -{ - - public enum DelayImportLibraryBindingType - { - Name, - Ordinal - } - - public abstract class DelayImportLibraryFunction - { - - private DelayImportLibrary library; - private DelayImportAddressTableEntry table_entry; - - internal DelayImportLibraryFunction(DelayImportLibrary importLibrary, DelayImportAddressTableEntry tableEntry) - { - library = importLibrary; - table_entry = tableEntry; - } - - #region Properties - - public DelayImportLibrary Library - { - get - { - return library; - } - } - - public DelayImportAddressTableEntry TableEntry - { - get - { - return table_entry; - } - } - - public abstract DelayImportLibraryBindingType BindingType - { - get; - } - - #endregion - - } - - public sealed class DelayImportLibraryOrdinalFunction : DelayImportLibraryFunction - { - - private int ordinal; - - internal DelayImportLibraryOrdinalFunction(DelayImportLibrary importLibrary, DelayImportAddressTableEntry tableEntry, int ordinalNo) : base(importLibrary, tableEntry) - { - ordinal = ordinalNo; - } - - #region Methods - - public override string ToString() - { - return String.Format("{0:D4} (0x{1})", ordinal, ordinal.ToString("X4")); - } - - #endregion - - #region Properties - - public override DelayImportLibraryBindingType BindingType - { - get - { - return DelayImportLibraryBindingType.Ordinal; - } - } - - public int Ordinal - { - get - { - return ordinal; - } - } - - #endregion - - } - - public sealed class DelayImportLibraryNamedFunction : DelayImportLibraryFunction - { - - private DelayImportHintNameEntry hint_entry; - - internal DelayImportLibraryNamedFunction(DelayImportLibrary importLibrary, DelayImportAddressTableEntry tableEntry, DelayImportHintNameEntry hintEntry) : base(importLibrary, tableEntry) - { - hint_entry = hintEntry; - } - - #region Methods - - public override string ToString() - { - return hint_entry.ToString(); - } - - #endregion - - #region Properties - - public override DelayImportLibraryBindingType BindingType - { - get - { - return DelayImportLibraryBindingType.Name; - } - } - - public DelayImportHintNameEntry HintEntry - { - get - { - return hint_entry; - } - } - - public string Name - { - get - { - return hint_entry.Name; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Delayed Imports/DelayImportHintNameTable.cs b/Src/Workshell.PE/Content/Delayed Imports/DelayImportHintNameTable.cs deleted file mode 100644 index de3546c..0000000 --- a/Src/Workshell.PE/Content/Delayed Imports/DelayImportHintNameTable.cs +++ /dev/null @@ -1,293 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.MoreLinq; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Imports -{ - - public sealed class DelayImportHintNameEntry : ISupportsLocation, ISupportsBytes - { - - private DelayImportHintNameTable table; - private Location location; - private ushort hint; - private string name; - private bool is_padded; - - internal DelayImportHintNameEntry(DelayImportHintNameTable parentTable, ulong offset, uint size, ushort entryHint, string entryName, bool isPadded) - { - LocationCalculator calc = parentTable.DataDirectory.Directories.Image.GetCalculator(); - - uint rva = calc.OffsetToRVA(offset); - ulong va = calc.OffsetToVA(offset); - - table = parentTable; - location = new Location(offset, rva, va, size, size); - hint = entryHint; - name = entryName; - is_padded = isPadded; - } - - #region Methods - - public override string ToString() - { - return String.Format("0x{0:X4} {1}", hint, name); - } - - public byte[] GetBytes() - { - Stream stream = table.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, location); - - return buffer; - } - - #endregion - - #region Properties - - public DelayImportHintNameTable Table - { - get - { - return table; - } - } - - public Location Location - { - get - { - return location; - } - } - - public ushort Hint - { - get - { - return hint; - } - } - - public string Name - { - get - { - return name; - } - } - - public bool IsPadded - { - get - { - return is_padded; - } - } - - #endregion - - } - - public sealed class DelayImportHintNameTable : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private DelayImportHintNameEntry[] table; - - internal DelayImportHintNameTable(DataDirectory dataDirectory, Location dataLocation, Tuple[] tableEntries) : base(dataDirectory,dataLocation) - { - table = LoadTable(tableEntries); - } - - #region Static Methods - - public static DelayImportHintNameTable Get(DelayImportDirectory directory) - { - if (directory == null) - return null; - - Dictionary> entries = new Dictionary>(); - DelayImportAddressTables tables = DelayImportAddressTables.GetLookupTable(directory); - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - - foreach (DelayImportAddressTable table in tables) - { - foreach (DelayImportAddressTableEntry entry in table) - { - if (entry.Address == 0) - continue; - - if (entries.ContainsKey(entry.Address)) - continue; - - if (!entry.IsOrdinal) - { - ulong offset = calc.RVAToOffset(entry.Address); - uint size = 0; - bool is_padded = false; - ushort hint = 0; - StringBuilder name = new StringBuilder(256); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - hint = Utils.ReadUInt16(stream); - size += sizeof(ushort); - - while (true) - { - int b = stream.ReadByte(); - - size++; - - if (b <= 0) - break; - - name.Append((char)b); - } - - if ((size % 2) != 0) - { - is_padded = true; - size++; - } - - Tuple tuple = new Tuple(offset, size, hint, name.ToString(), is_padded); - - entries.Add(entry.Address, tuple); - } - } - } - - Location location; - - if (entries.Count > 0) - { - var first_entry = entries.Values.MinBy(tuple => tuple.Item1); - var last_entry = entries.Values.MaxBy(tuple => tuple.Item1); - - ulong table_offset = first_entry.Item1; - uint table_size = ((last_entry.Item1 + last_entry.Item2) - table_offset).ToUInt32(); - - uint table_rva = calc.OffsetToRVA(table_offset); - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong table_va = image_base + table_rva; - Section table_section = calc.RVAToSection(table_rva); - - location = new Location(table_offset, table_rva, table_va, table_size, table_size, table_section); - } - else - { - location = new Location(0, 0, 0, 0, 0, null); - } - - DelayImportHintNameTable hint_name_table = new DelayImportHintNameTable(directory.DataDirectory, location, entries.Values.ToArray()); - - return hint_name_table; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < table.Length; i++) - { - yield return table[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("File Offset: 0x{0:X8}, Name Count: {1}",Location.FileOffset,table.Length); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, Location); - - return buffer; - } - - private DelayImportHintNameEntry[] LoadTable(Tuple[] tableEntries) - { - DelayImportHintNameEntry[] results = new DelayImportHintNameEntry[tableEntries.Length]; - - for(var i = 0; i < tableEntries.Length; i++) - { - DelayImportHintNameEntry entry = new DelayImportHintNameEntry(this, tableEntries[i].Item1, tableEntries[i].Item2, tableEntries[i].Item3, tableEntries[i].Item4, tableEntries[i].Item5); - - results[i] = entry; - } - - return results.OrderBy(entry => entry.Location.FileOffset).ToArray(); - } - - #endregion - - #region Properties - - public int Count - { - get - { - return table.Length; - } - } - - public DelayImportHintNameEntry this[int index] - { - get - { - return table[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Delayed Imports/DelayImportLibrary.cs b/Src/Workshell.PE/Content/Delayed Imports/DelayImportLibrary.cs deleted file mode 100644 index a8da9a4..0000000 --- a/Src/Workshell.PE/Content/Delayed Imports/DelayImportLibrary.cs +++ /dev/null @@ -1,171 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Imports -{ - - public sealed class DelayImportLibrary : IEnumerable - { - - private DelayImportCollection imports; - private DelayImportAddressTable address_table; - private DelayImportHintNameTable name_table; - private string name; - private DelayImportLibraryFunction[] functions; - - internal DelayImportLibrary(DelayImportCollection owningImports, DelayImportAddressTable addressTable, DelayImportHintNameTable nameTable, string libraryName) - { - imports = owningImports; - address_table = addressTable; - name_table = nameTable; - name = libraryName; - functions = LoadFunctions(); - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < functions.Length; i++) - { - yield return functions[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Name: {0}, Imported Function Count: {1}",name,functions.Length); - } - - public IEnumerable GetNamedFunctions() - { - for(var i = 0; i < functions.Length; i++) - { - if (functions[i].BindingType == DelayImportLibraryBindingType.Name) - yield return (DelayImportLibraryNamedFunction)functions[i]; - } - } - - public IEnumerable GetOrdinalFunctions() - { - for (var i = 0; i < functions.Length; i++) - { - if (functions[i].BindingType == DelayImportLibraryBindingType.Ordinal) - yield return (DelayImportLibraryOrdinalFunction)functions[i]; - } - } - - private DelayImportLibraryFunction[] LoadFunctions() - { - List list = new List(); - - foreach (DelayImportAddressTableEntry entry in address_table) - { - DelayImportLibraryFunction func = null; - - if (entry.IsOrdinal) - { - func = new DelayImportLibraryOrdinalFunction(this, entry, entry.Ordinal); - } - else - { - DelayImportHintNameEntry hint_entry = name_table.FirstOrDefault(hne => hne.Location.RelativeVirtualAddress == entry.Address); - - if (hint_entry != null) - func = new DelayImportLibraryNamedFunction(this, entry, hint_entry); - } - - if (func != null) - list.Add(func); - } - - DelayImportLibraryFunction[] functions = list.ToArray(); - - return functions; - } - - #endregion - - #region Properties - - public DelayImportCollection Imports - { - get - { - return imports; - } - } - - public DelayImportAddressTable Table - { - get - { - return address_table; - } - } - - public string Name - { - get - { - return name; - } - } - - public int Count - { - get - { - return functions.Length; - } - } - - public DelayImportLibraryFunction this[int index] - { - get - { - return functions[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Delayed Imports/DelayImports.cs b/Src/Workshell.PE/Content/Delayed Imports/DelayImports.cs deleted file mode 100644 index 6ddfde3..0000000 --- a/Src/Workshell.PE/Content/Delayed Imports/DelayImports.cs +++ /dev/null @@ -1,177 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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.Imports -{ - - public sealed class DelayImportCollection : IEnumerable - { - - private DelayImportLibrary[] libraries; - - internal DelayImportCollection(Tuple[] importLibraries) - { - libraries = LoadLibraries(importLibraries); - } - - #region Static Methods - - public static DelayImportCollection Get(ExecutableImage image) - { - DelayImportDirectory directory = DelayImportDirectory.Get(image); - - if (directory == null) - return null; - - DelayImportAddressTables ilt = DelayImportAddressTables.GetLookupTable(directory); - - if (ilt == null) - return null; - - DelayImportHintNameTable hnt = DelayImportHintNameTable.Get(directory); - - if (hnt == null) - return null; - - return Get(ilt, hnt); - } - - - public static DelayImportCollection Get(DelayImportAddressTables ilt, DelayImportHintNameTable hnTable) - { - List> libraries = new List>(); - LocationCalculator calc = ilt.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = ilt.DataDirectory.Directories.Image.GetStream(); - - foreach (DelayImportAddressTable table in ilt) - { - StringBuilder builder = new StringBuilder(256); - ulong offset = calc.RVAToOffset(table.DirectoryEntry.Name); - - stream.Seek(Convert.ToInt64(offset), SeekOrigin.Begin); - - while (true) - { - int b = stream.ReadByte(); - - if (b <= 0) - break; - - builder.Append((char)b); - } - - Tuple tuple = new Tuple(builder.ToString(), table, hnTable); - - libraries.Add(tuple); - } - - DelayImportCollection imports = new DelayImportCollection(libraries.ToArray()); - - return imports; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < libraries.Length; i++) - { - yield return libraries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Library Count: {0}",libraries.Length); - } - - private DelayImportLibrary[] LoadLibraries(Tuple[] importLibraries) - { - DelayImportLibrary[] results = new DelayImportLibrary[importLibraries.Length]; - - for(var i = 0; i < importLibraries.Length; i++) - { - Tuple tuple = importLibraries[i]; - DelayImportLibrary library = new DelayImportLibrary(this, tuple.Item2, tuple.Item3, tuple.Item1); - - results[i] = library; - } - - return results; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return libraries.Length; - } - } - - public DelayImportLibrary this[int index] - { - get - { - return libraries[index]; - } - } - - public DelayImportLibrary this[string libraryName] - { - get - { - DelayImportLibrary library = libraries.FirstOrDefault(lib => String.Compare(libraryName,lib.Name,StringComparison.OrdinalIgnoreCase) == 0); - - return library; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/ExecutableImageContent.cs b/Src/Workshell.PE/Content/ExecutableImageContent.cs deleted file mode 100644 index e77c086..0000000 --- a/Src/Workshell.PE/Content/ExecutableImageContent.cs +++ /dev/null @@ -1,71 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE -{ - - public abstract class ExecutableImageContent : ISupportsLocation - { - - private DataDirectory directory; - private Location location; - - public ExecutableImageContent(DataDirectory dataDirectory, Location dataLocation) - { - directory = dataDirectory; - location = dataLocation; - } - - #region Properties - - public DataDirectory DataDirectory - { - get - { - return directory; - } - } - - public Location Location - { - get - { - return location; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Exports/ExportDirectory.cs b/Src/Workshell.PE/Content/Exports/ExportDirectory.cs deleted file mode 100644 index 8365051..0000000 --- a/Src/Workshell.PE/Content/Exports/ExportDirectory.cs +++ /dev/null @@ -1,327 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Exports -{ - - public class ExportDirectory : ExecutableImageContent, ISupportsBytes - { - - private static readonly int size = Utils.SizeOf(); - - private IMAGE_EXPORT_DIRECTORY directory; - private Lazy name; - private Lazy function_addresses; - private Lazy function_name_addresses; - private Lazy function_ordinals; - - internal ExportDirectory(DataDirectory dataDirectory, Location dirLocation, IMAGE_EXPORT_DIRECTORY exportDirectory) : base(dataDirectory,dirLocation) - { - directory = exportDirectory; - name = new Lazy(DoGetName); - function_addresses = new Lazy(DoGetFunctionAddresses); - function_name_addresses = new Lazy(DoGetFunctionNameAddresses); - function_ordinals = new Lazy(DoGetFunctionOrdinals); - } - - #region Static Methods - - public static ExportDirectory Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ExportTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.ExportTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - uint rva = directory.VirtualAddress; - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - Section section = calc.RVAToSection(rva); - ulong offset = calc.RVAToOffset(section, rva); - uint size = Utils.SizeOf().ToUInt32(); - Location location = new Location(offset, rva, va, size, size, section); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - IMAGE_EXPORT_DIRECTORY export_directory = Utils.Read(stream); - ExportDirectory result = new ExportDirectory(directory, location, export_directory); - - return result; - } - - #endregion - - #region Methods - - public override string ToString() - { - return "Export Directory"; - } - - public byte[] GetBytes() - { - byte[] buffer = new byte[size]; - - Utils.Write(directory,buffer,0,buffer.Length); - - return buffer; - } - - public DateTime GetTimeDateStamp() - { - return Utils.ConvertTimeDateStamp(directory.TimeDateStamp); - } - - public string GetName() - { - return name.Value; - } - - public uint[] GetFunctionAddresses() - { - return function_addresses.Value; - } - - public uint[] GetFunctionNameAddresses() - { - return function_name_addresses.Value; - } - - public ushort[] GetFunctionOrdinals() - { - return function_ordinals.Value; - } - - private string DoGetName() - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - StringBuilder builder = new StringBuilder(256); - long offset = calc.RVAToOffset(directory.Name).ToInt64(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - stream.Seek(offset, SeekOrigin.Begin); - - while (true) - { - int value = stream.ReadByte(); - - if (value <= 0) - break; - - char c = (char)value; - - builder.Append(c); - } - - return builder.ToString(); - } - - private uint[] DoGetFunctionAddresses() - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - long offset = calc.RVAToOffset(directory.AddressOfFunctions).ToInt64(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - stream.Seek(offset, SeekOrigin.Begin); - - uint[] results = new uint[directory.NumberOfFunctions]; - - for (int i = 0; i < directory.NumberOfFunctions; i++) - { - uint address = Utils.ReadUInt32(stream); - - results[i] = address; - } - - return results; - } - - private uint[] DoGetFunctionNameAddresses() - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - long offset = calc.RVAToOffset(directory.AddressOfNames).ToInt64(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - stream.Seek(offset, SeekOrigin.Begin); - - uint[] results = new uint[directory.NumberOfNames]; - - for (int i = 0; i < directory.NumberOfNames; i++) - { - uint address = Utils.ReadUInt32(stream); - - results[i] = address; - } - - return results; - } - - private ushort[] DoGetFunctionOrdinals() - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - long offset = calc.RVAToOffset(directory.AddressOfNameOrdinals).ToInt64(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - stream.Seek(offset, SeekOrigin.Begin); - - ushort[] results = new ushort[directory.NumberOfNames]; - - for (int i = 0; i < directory.NumberOfNames; i++) - { - ushort ord = Utils.ReadUInt16(stream); - - results[i] = ord; - } - - return results; - } - - #endregion - - #region Properties - - [FieldAnnotation("Characteristics")] - public uint Characteristics - { - get - { - return directory.Characteristics; - } - } - - [FieldAnnotation("Date/Time Stamp")] - public uint TimeDateStamp - { - get - { - return directory.TimeDateStamp; - } - } - - [FieldAnnotation("Major Version")] - public ushort MajorVersion - { - get - { - return directory.MajorVersion; - } - } - - [FieldAnnotation("Minor Version")] - public ushort MinorVersion - { - get - { - return directory.MinorVersion; - } - } - - [FieldAnnotation("Name")] - public uint Name - { - get - { - return directory.Name; - } - } - - [FieldAnnotation("Base")] - public uint Base - { - get - { - return directory.Base; - } - } - - [FieldAnnotation("Number of Functions")] - public uint NumberOfFunctions - { - get - { - return directory.NumberOfFunctions; - } - } - - [FieldAnnotation("Number of Names")] - public uint NumberOfNames - { - get - { - return directory.NumberOfNames; - } - } - - [FieldAnnotation("Address of Functions")] - public uint AddressOfFunctions - { - get - { - return directory.AddressOfFunctions; - } - } - - [FieldAnnotation("Address of Names")] - public uint AddressOfNames - { - get - { - return directory.AddressOfNames; - } - } - - [FieldAnnotation("Address of Name Ordinals")] - public uint AddressOfNameOrdinals - { - get - { - return directory.AddressOfNameOrdinals; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Exports/ExportTable.cs b/Src/Workshell.PE/Content/Exports/ExportTable.cs deleted file mode 100644 index 9f79503..0000000 --- a/Src/Workshell.PE/Content/Exports/ExportTable.cs +++ /dev/null @@ -1,190 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Exports -{ - - public sealed class ExportTable : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private ExportDirectory directory; - private T[] table; - - internal ExportTable(ExportDirectory exportDirectory, Location tableLocation, T[] tableContent) : base(exportDirectory.DataDirectory,tableLocation) - { - directory = exportDirectory; - table = tableContent; - } - - #region Static Methods - - public static ExportTable GetFunctionAddressTable(ExportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.AddressOfFunctions); - ulong file_offset = calc.RVAToOffset(section, directory.AddressOfFunctions); - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint size = directory.NumberOfFunctions * sizeof(uint); - Location location = new Location(file_offset, directory.AddressOfFunctions, image_base + directory.AddressOfFunctions, size, size, section); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - uint[] addresses = new uint[directory.NumberOfFunctions]; - - for (int i = 0; i < directory.NumberOfFunctions; i++) - { - uint address = Utils.ReadUInt32(stream); - - addresses[i] = address; - } - - ExportTable address_table = new ExportTable(directory, location, addresses); - - return address_table; - } - - public static ExportTable GetNameAddressTable(ExportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.AddressOfNames); - ulong file_offset = calc.RVAToOffset(section, directory.AddressOfNames); - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint size = directory.NumberOfNames * sizeof(uint); - Location location = new Location(file_offset, directory.AddressOfNames, image_base + directory.AddressOfNames, size, size, section); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - uint[] addresses = new uint[directory.NumberOfNames]; - - for (int i = 0; i < directory.NumberOfNames; i++) - { - uint address = Utils.ReadUInt32(stream); - - addresses[i] = address; - } - - ExportTable address_table = new ExportTable(directory, location, addresses); - - return address_table; - } - - public static ExportTable GetOrdinalTable(ExportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.AddressOfNameOrdinals); - ulong file_offset = calc.RVAToOffset(section, directory.AddressOfNameOrdinals); - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint size = directory.NumberOfNames * sizeof(ushort); - Location location = new Location(file_offset, directory.AddressOfNameOrdinals, image_base + directory.AddressOfNames, size, size, section); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - ushort[] ordinals = new ushort[directory.NumberOfNames]; - - for (var i = 0; i < directory.NumberOfNames; i++) - { - ushort ord = Utils.ReadUInt16(stream); - - ordinals[i] = ord; - } - - ExportTable ordinals_table = new ExportTable(directory, location, ordinals); - - return ordinals_table; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < table.Length; i++) - { - yield return table[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, Location); - - return buffer; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return table.Length; - } - } - - public T this[int index] - { - get - { - return table[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Exports/Exports.cs b/Src/Workshell.PE/Content/Exports/Exports.cs deleted file mode 100644 index 63c7814..0000000 --- a/Src/Workshell.PE/Content/Exports/Exports.cs +++ /dev/null @@ -1,237 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Exports -{ - - public sealed class Export - { - - internal Export(uint entryPoint, string name, uint ord, string forwardName) - { - EntryPoint = entryPoint; - Name = name; - Ordinal = ord; - ForwardName = forwardName; - } - - #region Methods - - public override string ToString() - { - if (String.IsNullOrWhiteSpace(ForwardName)) - { - return String.Format("0x{0:X8} {1:D4} {2}",EntryPoint,Ordinal,Name); - } - else - { - return String.Format("0x{0:X8} {1:D4} {2} -> {3}",EntryPoint,Ordinal,Name,ForwardName); - } - } - - #endregion - - #region Properties - - public uint EntryPoint - { - get; - private set; - } - - public string Name - { - get; - private set; - } - - public uint Ordinal - { - get; - private set; - } - - public string ForwardName - { - get; - private set; - } - - #endregion - - } - - public sealed class ExportCollection : IEnumerable - { - - private Export[] _exports; - - internal ExportCollection(Export[] exports) - { - _exports = exports; - } - - #region Static Methods - - public static ExportCollection Get(ExecutableImage image) - { - ExportDirectory directory = ExportDirectory.Get(image); - - if (directory == null) - return null; - - ExportTable function_addresses = ExportTable.GetFunctionAddressTable(directory); - - if (function_addresses == null) - return null; - - ExportTable name_addresses = ExportTable.GetNameAddressTable(directory); - - if (name_addresses == null) - return null; - - ExportTable ordinals = ExportTable.GetOrdinalTable(directory); - - if (ordinals == null) - return null; - - return Get(directory, function_addresses, name_addresses, ordinals); - } - - public static ExportCollection Get(ExportDirectory directory, ExportTable functionAddresses, ExportTable nameAddresses, ExportTable ordinals) - { - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - List> name_addresses = new List>(); - - for(var i = 0; i < nameAddresses.Count; i++) - { - uint name_address = nameAddresses[i]; - ushort ordinal = ordinals[i]; - uint function_address = functionAddresses[ordinal]; - - long offset = calc.RVAToOffset(name_address).ToInt64(); - string name = GetString(stream, offset); - string fwd_name = String.Empty; - - if (function_address >= directory.DataDirectory.VirtualAddress && function_address <= (directory.DataDirectory.VirtualAddress + directory.DataDirectory.Size)) - { - offset = calc.RVAToOffset(function_address).ToInt64(); - fwd_name = GetString(stream, offset); - } - - Tuple tuple = new Tuple(i, function_address, name_address, ordinal, name, fwd_name); - - name_addresses.Add(tuple); - } - - List exports = new List(); - - for(var i = 0; i < functionAddresses.Count; i++) - { - uint function_address = functionAddresses[i]; - bool is_ordinal = !name_addresses.Any(t => t.Item2 == function_address); - - if (!is_ordinal) - { - Tuple tuple = name_addresses.First(t => t.Item2 == function_address); - Export export = new Export(function_address, tuple.Item5, directory.Base + tuple.Item4, tuple.Item6); - - exports.Add(export); - } - else - { - Export export = new Export(function_address, String.Empty, Convert.ToUInt32(directory.Base + i), String.Empty); - - exports.Add(export); - } - } - - ExportCollection result = new ExportCollection(exports.OrderBy(e => e.Ordinal).ToArray()); - - return result; - } - - private static string GetString(Stream stream, long offset) - { - stream.Seek(offset, SeekOrigin.Begin); - - return Utils.ReadString(stream); - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < _exports.Length; i++) - { - yield return _exports[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - #region Properties - - public int Count - { - get - { - return _exports.Length; - } - } - - public Export this[int index] - { - get - { - return _exports[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Imports/ImportAddressTable.cs b/Src/Workshell.PE/Content/Imports/ImportAddressTable.cs deleted file mode 100644 index 6f81654..0000000 --- a/Src/Workshell.PE/Content/Imports/ImportAddressTable.cs +++ /dev/null @@ -1,510 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.MoreLinq; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Imports -{ - - public sealed class ImportAddressTableEntry : ISupportsLocation, ISupportsBytes - { - - private ImportAddressTable table; - private Location location; - private ulong value; - private uint address; - private ushort ordinal; - private bool is_ordinal; - - internal ImportAddressTableEntry(ImportAddressTable addressTable, ulong entryOffset, ulong entryValue, uint entryAddress, ushort entryOrdinal, bool isOrdinal) - { - bool is_64bit = addressTable.Tables.DataDirectory.Directories.Image.Is64Bit; - LocationCalculator calc = addressTable.Tables.DataDirectory.Directories.Image.GetCalculator(); - uint rva = calc.OffsetToRVA(entryOffset); - ulong image_base = addressTable.Tables.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong size = (is_64bit ? sizeof(ulong) : sizeof(uint)).ToUInt64(); - - table = addressTable; - location = new Location(entryOffset,rva,va,size,size); - value = entryValue; - address = entryAddress; - ordinal = entryOrdinal; - is_ordinal = isOrdinal; - } - - #region Methods - - public override string ToString() - { - string result = String.Format("File Offset: 0x{0:X8}, ",location.FileOffset); - - if (!is_ordinal) - { - if (location.FileSize == sizeof(ulong)) - { - result += String.Format("Address: 0x{0:X16}",address); - } - else - { - result = String.Format("Address: 0x{0:X8}",address); - } - } - else - { - result = String.Format("Ordinal: 0x{0:D4}",ordinal); - } - - return result; - } - - public byte[] GetBytes() - { - Stream stream = table.Tables.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } - - #endregion - - #region Properties - - public ImportAddressTable Table - { - get - { - return table; - } - } - - public Location Location - { - get - { - return location; - } - } - - public ulong Value - { - get - { - return value; - } - } - - public uint Address - { - get - { - return address; - } - } - - public ushort Ordinal - { - get - { - return ordinal; - } - } - - public bool IsOrdinal - { - get - { - return is_ordinal; - } - } - - #endregion - - } - - public sealed class ImportAddressTable : IEnumerable, ISupportsLocation, ISupportsBytes - { - - private ImportAddressTables tables; - private ImportDirectoryEntry dir_entry; - private Location location; - private ImportAddressTableEntry[] entries; - - internal ImportAddressTable(ImportAddressTables addressTables, ImportDirectoryEntry directoryEntry, uint tableRVA/*, ulong tableOffset*/, ulong[] tableEntries) - { - bool is_64bit = addressTables.DataDirectory.Directories.Image.Is64Bit; - LocationCalculator calc = addressTables.DataDirectory.Directories.Image.GetCalculator(); - uint rva = tableRVA; - ulong image_base = addressTables.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong offset = calc.RVAToOffset(rva); - ulong size = (tableEntries.Count() * (is_64bit ? sizeof(ulong) : sizeof(uint))).ToUInt64(); - Section section = calc.RVAToSection(rva); - - tables = addressTables; - dir_entry = directoryEntry; - location = new Location(offset, rva, va, size, size, section); - entries = LoadEntries(is_64bit, offset, tableEntries); - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) - { - yield return entries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("File Offset: 0x{0:X8}, Table Entry Count: {1}",location.FileOffset,entries.Length); - } - - public byte[] GetBytes() - { - Stream stream = tables.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } - - private ImportAddressTableEntry[] LoadEntries(bool is64Bit, ulong tableOffset, ulong[] tableEntries) - { - ImportAddressTableEntry[] results = new ImportAddressTableEntry[tableEntries.Length]; - ulong offset = tableOffset; - - for(var i = 0; i < tableEntries.Length; i++) - { - ulong addr_or_ord = tableEntries[i]; - ushort ordinal = 0; - bool is_ordinal = false; - - if (!is64Bit) - { - uint value = Convert.ToUInt32(addr_or_ord); - - if ((value & 0x80000000) == 0x80000000) - { - value &= 0x7fffffff; - - ordinal = Convert.ToUInt16(value); - is_ordinal = true; - } - } - else - { - ulong value = addr_or_ord; - - if ((value & 0x8000000000000000) == 0x8000000000000000) - { - value &= 0x7fffffffffffffff; - - ordinal = Convert.ToUInt16(value); - is_ordinal = true; - } - } - - uint address; - - if (is_ordinal) - { - address = 0; - } - else - { - address = Utils.LoDWord(addr_or_ord); - } - - ImportAddressTableEntry entry = new ImportAddressTableEntry(this, offset, addr_or_ord, address, ordinal, is_ordinal); - - results[i] = entry; - offset += Convert.ToUInt32(is64Bit ? sizeof(ulong) : sizeof(uint)); - } - - return results; - } - - #endregion - - #region Properties - - public ImportAddressTables Tables - { - get - { - return tables; - } - } - - public ImportDirectoryEntry DirectoryEntry - { - get - { - return dir_entry; - } - } - - public Location Location - { - get - { - return location; - } - } - - public int Count - { - get - { - return entries.Length; - } - } - - public ImportAddressTableEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - - public sealed class ImportAddressTables : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private ImportAddressTable[] tables; - - internal ImportAddressTables(DataDirectory dataDirectory, Location dataLocation, Tuple[] addressTables) : base(dataDirectory,dataLocation) - { - tables = new ImportAddressTable[addressTables.Length]; - - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - - for (var i = 0; i < addressTables.Length; i++) - { - Tuple tuple = addressTables[i]; - ulong offset = calc.RVAToOffset(tuple.Item1); - ImportAddressTable table = new ImportAddressTable(this, tuple.Item2, tuple.Item1, tuple.Item3); - - tables[i] = table; - } - } - - #region Static Methods - - public static ImportAddressTables GetLookupTable(ImportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - bool is_64bit = directory.DataDirectory.Directories.Image.Is64Bit; - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - List> tables = new List>(); - - foreach (ImportDirectoryEntry dir_entry in directory) - { - if (dir_entry.OriginalFirstThunk == 0) - continue; - - List entries = new List(); - ulong offset = calc.RVAToOffset(dir_entry.OriginalFirstThunk); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - while (true) - { - ulong entry = (!is_64bit ? Utils.ReadUInt32(stream) : Utils.ReadUInt64(stream)); - - entries.Add(entry); - - if (entry == 0) - break; - } - - Tuple table = new Tuple(dir_entry.OriginalFirstThunk, dir_entry, entries.ToArray()); - - tables.Add(table); - } - - uint rva = 0; - - if (tables.Count > 0) - rva = tables.MinBy(table => table.Item1).Item1; - - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong file_offset = calc.RVAToOffset(rva); - ulong file_size = 0; - - foreach (var table in tables) - { - int size = table.Item3.Length * (!is_64bit ? sizeof(uint) : sizeof(ulong)); - - file_size += size.ToUInt32(); - } - - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, file_size, file_size, section); - ImportAddressTables result = new ImportAddressTables(directory.DataDirectory, location, tables.ToArray()); - - return result; - } - - public static ImportAddressTables GetAddressTable(ImportDirectory directory) - { - if (directory == null) - return null; - - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - bool is_64bit = directory.DataDirectory.Directories.Image.Is64Bit; - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - List> tables = new List>(); - - foreach (ImportDirectoryEntry dir_entry in directory) - { - if (dir_entry.FirstThunk == 0) - continue; - - List entries = new List(); - ulong offset = calc.RVAToOffset(dir_entry.FirstThunk); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - while (true) - { - ulong entry = (!is_64bit ? Utils.ReadUInt32(stream) : Utils.ReadUInt64(stream)); - - entries.Add(entry); - - if (entry == 0) - break; - } - - Tuple table = new Tuple(dir_entry.FirstThunk, dir_entry, entries.ToArray()); - - tables.Add(table); - } - - uint rva = 0; - - if (tables.Count > 0) - rva = tables.MinBy(table => table.Item1).Item1; - - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong va = image_base + rva; - ulong file_offset = calc.RVAToOffset(rva); - ulong file_size = 0; - - foreach (var table in tables) - { - int size = table.Item3.Length * (!is_64bit ? sizeof(uint) : sizeof(ulong)); - - file_size += size.ToUInt32(); - } - - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, file_size, file_size, section); - ImportAddressTables result = new ImportAddressTables(directory.DataDirectory, location, tables.ToArray()); - - return result; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < tables.Length; i++) - { - yield return tables[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("File Offset: 0x{0:X8}, Table Count: {1}",Location.FileOffset,tables.Length); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return tables.Length; - } - } - - public ImportAddressTable this[int index] - { - get - { - return tables[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Imports/ImportDirectory.cs b/Src/Workshell.PE/Content/Imports/ImportDirectory.cs deleted file mode 100644 index 5b46d1e..0000000 --- a/Src/Workshell.PE/Content/Imports/ImportDirectory.cs +++ /dev/null @@ -1,282 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Imports -{ - - public sealed class ImportDirectoryEntry : ISupportsLocation, ISupportsBytes - { - - private ImportDirectory directory; - private IMAGE_IMPORT_DESCRIPTOR descriptor; - private Location location; - private string name; - - internal ImportDirectoryEntry(ImportDirectory importDirectory, IMAGE_IMPORT_DESCRIPTOR entry, Location entryLocation) - { - directory = importDirectory; - descriptor = entry; - location = entryLocation; - name = null; - } - - #region Methods - - public override string ToString() - { - return GetName(); - } - - public byte[] GetBytes() - { - int size = Utils.SizeOf(); - byte[] buffer = new byte[size]; - - Utils.Write(descriptor, buffer, 0, size); - - return buffer; - } - - public DateTime GetTimeDateStamp() - { - return Utils.ConvertTimeDateStamp(descriptor.TimeDateStamp); - } - - public string GetName() - { - if (name == null) - { - StringBuilder builder = new StringBuilder(256); - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - ulong offset = calc.RVAToOffset(descriptor.Name); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - name = Utils.ReadString(stream); - } - - return name; - } - - #endregion - - #region Properties - - public ImportDirectory Directory - { - get - { - return directory; - } - } - - public Location Location - { - get - { - return location; - } - } - - [FieldAnnotation("Original First Thunk")] - public uint OriginalFirstThunk - { - get - { - return descriptor.OriginalFirstThunk; - } - } - - [FieldAnnotation("Date/Time Stamp")] - public uint TimeDateStamp - { - get - { - return descriptor.TimeDateStamp; - } - } - - [FieldAnnotation("Forwarder Chain")] - public uint ForwarderChain - { - get - { - return descriptor.ForwarderChain; - } - } - - [FieldAnnotation("Name")] - public uint Name - { - get - { - return descriptor.Name; - } - } - - [FieldAnnotation("First Thunk")] - public uint FirstThunk - { - get - { - return descriptor.FirstThunk; - } - } - - #endregion - - } - - public sealed class ImportDirectory : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private ImportDirectoryEntry[] entries; - - internal ImportDirectory(DataDirectory dataDirectory, Location dataLocation, IMAGE_IMPORT_DESCRIPTOR[] importDescriptors) : base(dataDirectory,dataLocation) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - ulong image_base = dataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong offset = dataLocation.FileOffset; - uint size = Utils.SizeOf().ToUInt32(); - - entries = new ImportDirectoryEntry[importDescriptors.Length]; - - for(var i = 0; i < importDescriptors.Length; i++) - { - IMAGE_IMPORT_DESCRIPTOR descriptor = importDescriptors[i]; - uint rva = calc.OffsetToRVA(dataLocation.Section, offset); - Section entry_section = calc.RVAToSection(rva); - Location entry_location = new Location(offset, rva, image_base + rva, size, size, entry_section); - ImportDirectoryEntry entry = new ImportDirectoryEntry(this, descriptor, entry_location); - - entries[i] = entry; - offset += size; - } - } - - #region Static Methods - - public static ImportDirectory Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ImportTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.ImportTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - int size = Utils.SizeOf(); - List descriptors = new List(); - - while (true) - { - IMAGE_IMPORT_DESCRIPTOR descriptor = Utils.Read(stream, size); - - if (descriptor.OriginalFirstThunk == 0 && descriptor.FirstThunk == 0) - break; - - descriptors.Add(descriptor); - } - - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - uint total_size = Convert.ToUInt32((descriptors.Count + 1) * size); - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, total_size, total_size, section); - ImportDirectory result = new ImportDirectory(directory, location, descriptors.ToArray()); - - return result; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) - { - yield return entries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return entries.Length; - } - } - - public ImportDirectoryEntry this[int index] - { - get - { - return entries[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Imports/ImportFunction.cs b/Src/Workshell.PE/Content/Imports/ImportFunction.cs deleted file mode 100644 index 15d1935..0000000 --- a/Src/Workshell.PE/Content/Imports/ImportFunction.cs +++ /dev/null @@ -1,172 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Imports -{ - - public enum ImportLibraryBindingType - { - Name, - Ordinal - } - - public abstract class ImportLibraryFunction - { - - private ImportLibrary library; - private ImportAddressTableEntry table_entry; - - internal ImportLibraryFunction(ImportLibrary importLibrary, ImportAddressTableEntry tableEntry) - { - library = importLibrary; - table_entry = tableEntry; - } - - #region Properties - - public ImportLibrary Library - { - get - { - return library; - } - } - - public ImportAddressTableEntry TableEntry - { - get - { - return table_entry; - } - } - - public abstract ImportLibraryBindingType BindingType - { - get; - } - - #endregion - - } - - public sealed class ImportLibraryOrdinalFunction : ImportLibraryFunction - { - - private int ordinal; - - internal ImportLibraryOrdinalFunction(ImportLibrary importLibrary, ImportAddressTableEntry tableEntry, int ordinalNo) : base(importLibrary, tableEntry) - { - ordinal = ordinalNo; - } - - #region Methods - - public override string ToString() - { - return String.Format("{0:D4} (0x{1})", ordinal, ordinal.ToString("X4")); - } - - #endregion - - #region Properties - - public override ImportLibraryBindingType BindingType - { - get - { - return ImportLibraryBindingType.Ordinal; - } - } - - public int Ordinal - { - get - { - return ordinal; - } - } - - #endregion - - } - - public sealed class ImportLibraryNamedFunction : ImportLibraryFunction - { - - private ImportHintNameEntry hint_entry; - - internal ImportLibraryNamedFunction(ImportLibrary importLibrary, ImportAddressTableEntry tableEntry, ImportHintNameEntry hintEntry) : base(importLibrary, tableEntry) - { - hint_entry = hintEntry; - } - - #region Methods - - public override string ToString() - { - return hint_entry.ToString(); - } - - #endregion - - #region Properties - - public override ImportLibraryBindingType BindingType - { - get - { - return ImportLibraryBindingType.Name; - } - } - - public ImportHintNameEntry HintEntry - { - get - { - return hint_entry; - } - } - - public string Name - { - get - { - return hint_entry.Name; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Imports/ImportHintNameTable.cs b/Src/Workshell.PE/Content/Imports/ImportHintNameTable.cs deleted file mode 100644 index 9ea6bea..0000000 --- a/Src/Workshell.PE/Content/Imports/ImportHintNameTable.cs +++ /dev/null @@ -1,293 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.MoreLinq; - -using Workshell.PE.Extensions; - -namespace Workshell.PE.Imports -{ - - public sealed class ImportHintNameEntry : ISupportsLocation, ISupportsBytes - { - - private ImportHintNameTable table; - private Location location; - private ushort hint; - private string name; - private bool is_padded; - - internal ImportHintNameEntry(ImportHintNameTable parentTable, ulong offset, uint size, ushort entryHint, string entryName, bool isPadded) - { - LocationCalculator calc = parentTable.DataDirectory.Directories.Image.GetCalculator(); - - uint rva = calc.OffsetToRVA(offset); - ulong va = calc.OffsetToVA(offset); - - table = parentTable; - location = new Location(offset, rva, va, size, size); - hint = entryHint; - name = entryName; - is_padded = isPadded; - } - - #region Methods - - public override string ToString() - { - return String.Format("0x{0:X4} {1}", hint, name); - } - - public byte[] GetBytes() - { - Stream stream = table.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, location); - - return buffer; - } - - #endregion - - #region Properties - - public ImportHintNameTable Table - { - get - { - return table; - } - } - - public Location Location - { - get - { - return location; - } - } - - public ushort Hint - { - get - { - return hint; - } - } - - public string Name - { - get - { - return name; - } - } - - public bool IsPadded - { - get - { - return is_padded; - } - } - - #endregion - - } - - public sealed class ImportHintNameTable : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private ImportHintNameEntry[] table; - - internal ImportHintNameTable(DataDirectory dataDirectory, Location dataLocation, Tuple[] tableEntries) : base(dataDirectory,dataLocation) - { - table = LoadTable(tableEntries); - } - - #region Static Methods - - public static ImportHintNameTable Get(ImportDirectory directory) - { - if (directory == null) - return null; - - Dictionary> entries = new Dictionary>(); - ImportAddressTables ilt = ImportAddressTables.GetLookupTable(directory); - LocationCalculator calc = directory.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = directory.DataDirectory.Directories.Image.GetStream(); - - foreach (ImportAddressTable table in ilt) - { - foreach (ImportAddressTableEntry entry in table) - { - if (entry.Address == 0) - continue; - - if (entries.ContainsKey(entry.Address)) - continue; - - if (!entry.IsOrdinal) - { - ulong offset = calc.RVAToOffset(entry.Address); - uint size = 0; - bool is_padded = false; - ushort hint = 0; - StringBuilder name = new StringBuilder(256); - - stream.Seek(offset.ToInt64(), SeekOrigin.Begin); - - hint = Utils.ReadUInt16(stream); - size += sizeof(ushort); - - while (true) - { - int b = stream.ReadByte(); - - size++; - - if (b <= 0) - break; - - name.Append((char)b); - } - - if ((size % 2) != 0) - { - is_padded = true; - size++; - } - - Tuple tuple = new Tuple(offset, size, hint, name.ToString(), is_padded); - - entries.Add(entry.Address, tuple); - } - } - } - - Location location; - - if (entries.Count > 0) - { - var first_entry = entries.Values.MinBy(tuple => tuple.Item1); - var last_entry = entries.Values.MaxBy(tuple => tuple.Item1); - - ulong table_offset = first_entry.Item1; - uint table_size = ((last_entry.Item1 + last_entry.Item2) - table_offset).ToUInt32(); - - uint table_rva = calc.OffsetToRVA(table_offset); - ulong image_base = directory.DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - ulong table_va = image_base + table_rva; - Section table_section = calc.RVAToSection(table_rva); - - location = new Location(table_offset, table_rva, table_va, table_size, table_size, table_section); - } - else - { - location = new Location(0, 0, 0, 0, 0, null); - } - - ImportHintNameTable hint_name_table = new ImportHintNameTable(directory.DataDirectory, location, entries.Values.ToArray()); - - return hint_name_table; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < table.Length; i++) - { - yield return table[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("File Offset: 0x{0:X8}, Name Count: {1}",Location.FileOffset,table.Length); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, Location); - - return buffer; - } - - private ImportHintNameEntry[] LoadTable(Tuple[] tableEntries) - { - ImportHintNameEntry[] results = new ImportHintNameEntry[tableEntries.Length]; - - for(var i = 0; i < tableEntries.Length; i++) - { - ImportHintNameEntry entry = new ImportHintNameEntry(this, tableEntries[i].Item1, tableEntries[i].Item2, tableEntries[i].Item3, tableEntries[i].Item4, tableEntries[i].Item5); - - results[i] = entry; - } - - return results.OrderBy(entry => entry.Location.FileOffset).ToArray(); - } - - #endregion - - #region Properties - - public int Count - { - get - { - return table.Length; - } - } - - public ImportHintNameEntry this[int index] - { - get - { - return table[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Imports/ImportLibrary.cs b/Src/Workshell.PE/Content/Imports/ImportLibrary.cs deleted file mode 100644 index f33df8d..0000000 --- a/Src/Workshell.PE/Content/Imports/ImportLibrary.cs +++ /dev/null @@ -1,171 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Imports -{ - - public sealed class ImportLibrary : IEnumerable - { - - private ImportCollection imports; - private ImportAddressTable address_table; - private ImportHintNameTable name_table; - private string name; - private ImportLibraryFunction[] functions; - - internal ImportLibrary(ImportCollection owningImports, ImportAddressTable addressTable, ImportHintNameTable nameTable, string libraryName) - { - imports = owningImports; - address_table = addressTable; - name_table = nameTable; - name = libraryName; - functions = LoadFunctions(); - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < functions.Length; i++) - { - yield return functions[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Name: {0}, Imported Function Count: {1}",name,functions.Length); - } - - public IEnumerable GetNamedFunctions() - { - for(var i = 0; i < functions.Length; i++) - { - if (functions[i].BindingType == ImportLibraryBindingType.Name) - yield return (ImportLibraryNamedFunction)functions[i]; - } - } - - public IEnumerable GetOrdinalFunctions() - { - for (var i = 0; i < functions.Length; i++) - { - if (functions[i].BindingType == ImportLibraryBindingType.Ordinal) - yield return (ImportLibraryOrdinalFunction)functions[i]; - } - } - - private ImportLibraryFunction[] LoadFunctions() - { - List list = new List(); - - foreach (ImportAddressTableEntry entry in address_table) - { - ImportLibraryFunction func = null; - - if (entry.IsOrdinal) - { - func = new ImportLibraryOrdinalFunction(this, entry, entry.Ordinal); - } - else - { - ImportHintNameEntry hint_entry = name_table.FirstOrDefault(hne => hne.Location.RelativeVirtualAddress == entry.Address); - - if (hint_entry != null) - func = new ImportLibraryNamedFunction(this, entry, hint_entry); - } - - if (func != null) - list.Add(func); - } - - ImportLibraryFunction[] functions = list.ToArray(); - - return functions; - } - - #endregion - - #region Properties - - public ImportCollection Imports - { - get - { - return imports; - } - } - - public ImportAddressTable Table - { - get - { - return address_table; - } - } - - public string Name - { - get - { - return name; - } - } - - public int Count - { - get - { - return functions.Length; - } - } - - public ImportLibraryFunction this[int index] - { - get - { - return functions[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Imports/Imports.cs b/Src/Workshell.PE/Content/Imports/Imports.cs deleted file mode 100644 index dce4287..0000000 --- a/Src/Workshell.PE/Content/Imports/Imports.cs +++ /dev/null @@ -1,176 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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.Imports -{ - - public sealed class ImportCollection : IEnumerable - { - - private ImportLibrary[] libraries; - - internal ImportCollection(Tuple[] importLibraries) - { - libraries = LoadLibraries(importLibraries); - } - - #region Static Methods - - public static ImportCollection Get(ExecutableImage image) - { - ImportDirectory directory = ImportDirectory.Get(image); - - if (directory == null) - return null; - - ImportAddressTables ilt = ImportAddressTables.GetLookupTable(directory); - - if (ilt == null) - return null; - - ImportHintNameTable hnt = ImportHintNameTable.Get(directory); - - if (hnt == null) - return null; - - return Get(ilt, hnt); - } - - public static ImportCollection Get(ImportAddressTables ilt, ImportHintNameTable hnTable) - { - List> libraries = new List>(); - LocationCalculator calc = ilt.DataDirectory.Directories.Image.GetCalculator(); - Stream stream = ilt.DataDirectory.Directories.Image.GetStream(); - - foreach (ImportAddressTable table in ilt) - { - StringBuilder builder = new StringBuilder(256); - ulong offset = calc.RVAToOffset(table.DirectoryEntry.Name); - - stream.Seek(Convert.ToInt64(offset), SeekOrigin.Begin); - - while (true) - { - int b = stream.ReadByte(); - - if (b <= 0) - break; - - builder.Append((char)b); - } - - Tuple tuple = new Tuple(builder.ToString(), table, hnTable); - - libraries.Add(tuple); - } - - ImportCollection imports = new ImportCollection(libraries.ToArray()); - - return imports; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < libraries.Length; i++) - { - yield return libraries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Library Count: {0}",libraries.Length); - } - - private ImportLibrary[] LoadLibraries(Tuple[] importLibraries) - { - ImportLibrary[] results = new ImportLibrary[importLibraries.Length]; - - for(var i = 0; i < importLibraries.Length; i++) - { - Tuple tuple = importLibraries[i]; - ImportLibrary library = new ImportLibrary(this, tuple.Item2, tuple.Item3, tuple.Item1); - - results[i] = library; - } - - return results; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return libraries.Length; - } - } - - public ImportLibrary this[int index] - { - get - { - return libraries[index]; - } - } - - public ImportLibrary this[string libraryName] - { - get - { - ImportLibrary library = libraries.FirstOrDefault(lib => String.Compare(libraryName,lib.Name,StringComparison.OrdinalIgnoreCase) == 0); - - return library; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/LoadConfig/LoadConfigDirectory.cs b/Src/Workshell.PE/Content/LoadConfig/LoadConfigDirectory.cs deleted file mode 100644 index 9bb0cf1..0000000 --- a/Src/Workshell.PE/Content/LoadConfig/LoadConfigDirectory.cs +++ /dev/null @@ -1,696 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.LoadConfiguration -{ - - public abstract class LoadConfigDirectory : ExecutableImageContent, ISupportsBytes - { - - internal LoadConfigDirectory(DataDirectory dataDirectory, Location configLocation) : base(dataDirectory,configLocation) - { - } - - #region Static Methods - - public static LoadConfigDirectory Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.LoadConfigTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.LoadConfigTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - bool is_64bit = directory.Directories.Image.Is64Bit; - LoadConfigDirectory load_config_dir = null; - - if (!is_64bit) - { - IMAGE_LOAD_CONFIG_DIRECTORY32 config_dir = Utils.Read(stream); - - load_config_dir = new LoadConfigDirectory32(directory, location, config_dir); - } - else - { - IMAGE_LOAD_CONFIG_DIRECTORY64 config_dir = Utils.Read(stream); - - load_config_dir = new LoadConfigDirectory64(directory, location, config_dir); - } - - return load_config_dir; - } - - #endregion - - #region Methods - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, Location); - - return buffer; - } - - public DateTime GetTimeDateStamp() - { - return Utils.ConvertTimeDateStamp(TimeDateStamp); - } - - #endregion - - #region Properties - - [FieldAnnotation("Size")] - public abstract uint Size - { - get; - } - - [FieldAnnotation("Date/Time Stamp")] - public abstract uint TimeDateStamp - { - get; - } - - [FieldAnnotation("Major Version")] - public abstract ushort MajorVersion - { - get; - } - - [FieldAnnotation("Minor Version")] - public abstract ushort MinorVersion - { - get; - } - - [FieldAnnotation("Global Flags Clear")] - public abstract uint GlobalFlagsClear - { - get; - } - - [FieldAnnotation("Global Flags Set")] - public abstract uint GlobalFlagsSet - { - get; - } - - [FieldAnnotation("Critical Section Default Timeout")] - public abstract uint CriticalSectionDefaultTimeout - { - get; - } - - [FieldAnnotation("De-commit Free Block Threshold")] - public abstract ulong DeCommitFreeBlockThreshold - { - get; - } - - [FieldAnnotation("De-commit Total Free Threshold")] - public abstract ulong DeCommitTotalFreeThreshold - { - get; - } - - [FieldAnnotation("Lock Prefix Table")] - public abstract ulong LockPrefixTable - { - get; - } - - [FieldAnnotation("Maximum Allocation Size")] - public abstract ulong MaximumAllocationSize - { - get; - } - - [FieldAnnotation("Virtual Memory Threshold")] - public abstract ulong VirtualMemoryThreshold - { - get; - } - - [FieldAnnotation("Process Affinity Mask")] - public abstract ulong ProcessAffinityMask - { - get; - } - - [FieldAnnotation("Process Heap Flags")] - public abstract uint ProcessHeapFlags - { - get; - } - - [FieldAnnotation("CSD Version")] - public abstract ushort CSDVersion - { - get; - } - - [FieldAnnotation("Reserved")] - public abstract ushort Reserved1 - { - get; - } - - [FieldAnnotation("Edit List")] - public abstract ulong EditList - { - get; - } - - [FieldAnnotation("Security Cookie")] - public abstract ulong SecurityCookie - { - get; - } - - [FieldAnnotation("SEHandler Table")] - public abstract ulong SEHandlerTable - { - get; - } - - [FieldAnnotation("SEHandler Count")] - public abstract ulong SEHandlerCount - { - get; - } - - [FieldAnnotation("Guard CF Check Function Pointer")] - public abstract ulong GuardCFCheckFunctionPointer - { - get; - } - - [FieldAnnotation("Reserved")] - public abstract ulong Reserved2 - { - get; - } - - [FieldAnnotation("Guard CF Function Table")] - public abstract ulong GuardCFFunctionTable - { - get; - } - - [FieldAnnotation("Guard CF Function Count")] - public abstract ulong GuardCFFunctionCount - { - get; - } - - [FieldAnnotation("Guard Flags")] - public abstract uint GuardFlags - { - get; - } - - #endregion - - } - - public sealed class LoadConfigDirectory32 : LoadConfigDirectory - { - - private IMAGE_LOAD_CONFIG_DIRECTORY32 directory; - - internal LoadConfigDirectory32(DataDirectory dataDirectory, Location configLocation, IMAGE_LOAD_CONFIG_DIRECTORY32 configDirectory) : base(dataDirectory,configLocation) - { - directory = configDirectory; - } - - #region Properties - - public override uint Size - { - get - { - return directory.Size; - } - } - - public override uint TimeDateStamp - { - get - { - return directory.TimeDateStamp; - } - } - - public override ushort MajorVersion - { - get - { - return directory.MajorVersion; - } - } - - public override ushort MinorVersion - { - get - { - return directory.MinorVersion; - } - } - - public override uint GlobalFlagsClear - { - get - { - return directory.GlobalFlagsClear; - } - } - - public override uint GlobalFlagsSet - { - get - { - return directory.GlobalFlagsSet; - } - } - - public override uint CriticalSectionDefaultTimeout - { - get - { - return directory.CriticalSectionDefaultTimeout; - } - } - - public override ulong DeCommitFreeBlockThreshold - { - get - { - return directory.DeCommitFreeBlockThreshold; - } - } - - public override ulong DeCommitTotalFreeThreshold - { - get - { - return directory.DeCommitTotalFreeThreshold; - } - } - - public override ulong LockPrefixTable - { - get - { - return directory.LockPrefixTable; - } - } - - public override ulong MaximumAllocationSize - { - get - { - return directory.MaximumAllocationSize; - } - } - - public override ulong VirtualMemoryThreshold - { - get - { - return directory.VirtualMemoryThreshold; - } - } - - public override ulong ProcessAffinityMask - { - get - { - return directory.ProcessAffinityMask; - } - } - - public override uint ProcessHeapFlags - { - get - { - return directory.ProcessHeapFlags; - } - } - - public override ushort CSDVersion - { - get - { - return directory.CSDVersion; - } - } - - public override ushort Reserved1 - { - get - { - return directory.Reserved1; - } - } - - public override ulong EditList - { - get - { - return directory.EditList; - } - } - - public override ulong SecurityCookie - { - get - { - return directory.SecurityCookie; - } - } - - public override ulong SEHandlerTable - { - get - { - return directory.SEHandlerTable; - } - } - - public override ulong SEHandlerCount - { - get - { - return directory.SEHandlerCount; - } - } - - public override ulong GuardCFCheckFunctionPointer - { - get - { - return directory.GuardCFCheckFunctionPointer; - } - } - - public override ulong Reserved2 - { - get - { - return directory.Reserved2; - } - } - - public override ulong GuardCFFunctionTable - { - get - { - return directory.GuardCFFunctionTable; - } - } - - public override ulong GuardCFFunctionCount - { - get - { - return directory.GuardCFFunctionCount; - } - } - - public override uint GuardFlags - { - get - { - return directory.GuardFlags; - } - } - - #endregion - - } - - public sealed class LoadConfigDirectory64 : LoadConfigDirectory - { - - private IMAGE_LOAD_CONFIG_DIRECTORY64 directory; - - internal LoadConfigDirectory64(DataDirectory dataDirectory, Location configLocation, IMAGE_LOAD_CONFIG_DIRECTORY64 configDirectory) : base(dataDirectory,configLocation) - { - directory = configDirectory; - } - - #region Properties - - public override uint Size - { - get - { - return directory.Size; - } - } - - public override uint TimeDateStamp - { - get - { - return directory.TimeDateStamp; - } - } - - public override ushort MajorVersion - { - get - { - return directory.MajorVersion; - } - } - - public override ushort MinorVersion - { - get - { - return directory.MinorVersion; - } - } - - public override uint GlobalFlagsClear - { - get - { - return directory.GlobalFlagsClear; - } - } - - public override uint GlobalFlagsSet - { - get - { - return directory.GlobalFlagsSet; - } - } - - public override uint CriticalSectionDefaultTimeout - { - get - { - return directory.CriticalSectionDefaultTimeout; - } - } - - public override ulong DeCommitFreeBlockThreshold - { - get - { - return directory.DeCommitFreeBlockThreshold; - } - } - - public override ulong DeCommitTotalFreeThreshold - { - get - { - return directory.DeCommitTotalFreeThreshold; - } - } - - public override ulong LockPrefixTable - { - get - { - return directory.LockPrefixTable; - } - } - - public override ulong MaximumAllocationSize - { - get - { - return directory.MaximumAllocationSize; - } - } - - public override ulong VirtualMemoryThreshold - { - get - { - return directory.VirtualMemoryThreshold; - } - } - - public override ulong ProcessAffinityMask - { - get - { - return directory.ProcessAffinityMask; - } - } - - public override uint ProcessHeapFlags - { - get - { - return directory.ProcessHeapFlags; - } - } - - public override ushort CSDVersion - { - get - { - return directory.CSDVersion; - } - } - - public override ushort Reserved1 - { - get - { - return directory.Reserved1; - } - } - - public override ulong EditList - { - get - { - return directory.EditList; - } - } - - public override ulong SecurityCookie - { - get - { - return directory.SecurityCookie; - } - } - - public override ulong SEHandlerTable - { - get - { - return directory.SEHandlerTable; - } - } - - public override ulong SEHandlerCount - { - get - { - return directory.SEHandlerCount; - } - } - - public override ulong GuardCFCheckFunctionPointer - { - get - { - return directory.GuardCFCheckFunctionPointer; - } - } - - public override ulong Reserved2 - { - get - { - return directory.Reserved2; - } - } - - public override ulong GuardCFFunctionTable - { - get - { - return directory.GuardCFFunctionTable; - } - } - - public override ulong GuardCFFunctionCount - { - get - { - return directory.GuardCFFunctionCount; - } - } - - public override uint GuardFlags - { - get - { - return directory.GuardFlags; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Relocation/Relocation.cs b/Src/Workshell.PE/Content/Relocation/Relocation.cs deleted file mode 100644 index 552fbdb..0000000 --- a/Src/Workshell.PE/Content/Relocation/Relocation.cs +++ /dev/null @@ -1,159 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Native; - -namespace Workshell.PE.Relocations -{ - - public enum RelocationType : byte - { - [EnumAnnotationAttribute("IMAGE_REL_BASED_ABSOLUTE")] - Absolute = 0, - [EnumAnnotationAttribute("IMAGE_REL_BASED_HIGH")] - High = 1, - [EnumAnnotationAttribute("IMAGE_REL_BASED_LOW")] - Low = 2, - [EnumAnnotationAttribute("IMAGE_REL_BASED_HIGHLOW")] - HighLow = 3, - [EnumAnnotationAttribute("IMAGE_REL_BASED_HIGHADJ")] - HighAdj = 4, - [EnumAnnotationAttribute("IMAGE_REL_BASED_MIPS_JMPADDR")] - MIPSJmpAddr = 5, - [EnumAnnotationAttribute("IMAGE_REL_BASED_ARM_MOV32A")] - ARMMov32a = 6, - [EnumAnnotationAttribute("IMAGE_REL_BASED_ARM_MOV32T")] - ARMMov32t = 7, - [EnumAnnotationAttribute("IMAGE_REL_BASED_MIPS_JMPADDR16")] - MIPSJmpAddr16 = 9, - [EnumAnnotationAttribute("IMAGE_REL_BASED_DIR64")] - Dir64 = 10 - } - - public sealed class Relocation - { - - private RelocationBlock block; - private RelocationType type; - private ushort offset; - private ushort value; - private uint computed_rva; - - internal Relocation(RelocationBlock relocBlock, ushort relocValue) - { - block = relocBlock; - - int reloc_type = relocValue >> 12; - int reloc_offset = relocValue & 0xFFF; - - type = (RelocationType)reloc_type; - offset = Convert.ToUInt16(reloc_offset); - value = relocValue; - computed_rva = block.PageRVA; - - switch (type) - { - case RelocationType.Absolute: - break; - case RelocationType.HighLow: - computed_rva += offset; - break; - case RelocationType.Dir64: - computed_rva += offset; - break; - case RelocationType.High: - case RelocationType.Low: - default: - computed_rva = 0; - break; - } - } - - #region Methods - - public override string ToString() - { - return String.Format("Type: {0}, Computed RVA: 0x{1:X8}",type,computed_rva); - } - - #endregion - - #region Properties - - public RelocationBlock Block - { - get - { - return block; - } - } - - public RelocationType Type - { - get - { - return type; - } - } - - public ushort Offset - { - get - { - return offset; - } - } - - public ushort Value - { - get - { - return value; - } - } - - public uint ComputedRVA - { - get - { - return computed_rva; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Relocation/RelocationBlock.cs b/Src/Workshell.PE/Content/Relocation/RelocationBlock.cs deleted file mode 100644 index 61575f3..0000000 --- a/Src/Workshell.PE/Content/Relocation/RelocationBlock.cs +++ /dev/null @@ -1,166 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE.Relocations -{ - - public sealed class RelocationBlock : IEnumerable, ISupportsLocation, ISupportsBytes - { - - private RelocationTable table; - private Location location; - private uint page_rva; - private uint block_size; - private Lazy
reloc_section; - private Relocation[] relocations; - - internal RelocationBlock(RelocationTable relocTable, Location blockLocation, uint pageRVA, uint blockSize, ushort[] relocs) - { - table = relocTable; - location = blockLocation; - page_rva = pageRVA; - block_size = blockSize; - reloc_section = new Lazy
(GetSection); - relocations = new Relocation[relocs.Length]; - - for(var i = 0; i < relocs.Length; i++) - { - ushort offset = relocs[i]; - Relocation reloc = new Relocation(this, offset); - - relocations[i] = reloc; - } - } - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < relocations.Length; i++) - { - yield return relocations[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return String.Format("Page RVA: 0x{0:X8}, Block Size: {1}, Relocations: {2}",page_rva,block_size,relocations.Length); - } - - public byte[] GetBytes() - { - Stream stream = table.DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; - } - - private Section GetSection() - { - LocationCalculator calc = table.DataDirectory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(page_rva); - - return section; - } - - #endregion - - #region Properties - - public RelocationTable Table - { - get - { - return table; - } - } - - public Location Location - { - get - { - return location; - } - } - - public uint PageRVA - { - get - { - return page_rva; - } - } - - public uint BlockSize - { - get - { - return block_size; - } - } - - public Section Section - { - get - { - return reloc_section.Value; - } - } - - public int Count - { - get - { - return relocations.Length; - } - } - - public Relocation this[int index] - { - get - { - return relocations[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Relocation/RelocationTable.cs b/Src/Workshell.PE/Content/Relocation/RelocationTable.cs deleted file mode 100644 index 6884fe9..0000000 --- a/Src/Workshell.PE/Content/Relocation/RelocationTable.cs +++ /dev/null @@ -1,182 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Relocations -{ - - public sealed class RelocationTable : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private RelocationBlock[] blocks; - - internal RelocationTable(DataDirectory dataDirectory, Location relocLocation, Tuple[] relocBlocks) : base(dataDirectory,relocLocation) - { - blocks = Load(relocBlocks); - } - - #region Static Methods - - public static RelocationTable Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.Debug)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.BaseRelocationTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - ulong block_offset = file_offset; - uint block_size = 0; - List> block_relocs = new List>(); - - while (true) - { - IMAGE_BASE_RELOCATION base_reloc = Utils.Read(stream); - - block_size += sizeof(ulong); - - long count = (base_reloc.SizeOfBlock - sizeof(ulong)) / sizeof(ushort); - ushort[] relocs = new ushort[count]; - - for (var i = 0; i < count; i++) - { - ushort reloc = Utils.ReadUInt16(stream); - - relocs[i] = reloc; - block_size += sizeof(ushort); - } - - Tuple block = new Tuple(block_offset, base_reloc.SizeOfBlock, base_reloc.VirtualAddress, relocs); - - block_relocs.Add(block); - - if (block_size >= directory.Size) - break; - - block_offset += sizeof(ulong); - block_offset += sizeof(ushort) * (uint)count; - } - - RelocationTable relocations = new RelocationTable(directory, location, block_relocs.ToArray()); - - return relocations; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < blocks.Length; i++) - { - yield return blocks[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, Location); - - return buffer; - } - - private RelocationBlock[] Load(Tuple[] relocBlocks) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - RelocationBlock[] results = new RelocationBlock[relocBlocks.Length]; - - for(var i = 0; i < relocBlocks.Length; i++) - { - Tuple tuple = relocBlocks[i]; - ulong offset = tuple.Item1; - uint rva = calc.OffsetToRVA(offset); - Section section = calc.RVAToSection(rva); - ulong va = DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase + rva; - uint size = tuple.Item2; - uint page_rva = tuple.Item3; - ushort[] relocs = tuple.Item4; - Location block_location = new Location(offset, rva, va, size, size, section); - RelocationBlock block = new RelocationBlock(this, block_location, page_rva, size, relocs); - - results[i] = block; - } - - return results; - } - - #endregion - - #region Properties - - public int Count - { - get - { - return blocks.Length; - } - } - - public RelocationBlock this[int index] - { - get - { - return blocks[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Resources/ResourceCollection.cs b/Src/Workshell.PE/Content/Resources/ResourceCollection.cs deleted file mode 100644 index 9317b83..0000000 --- a/Src/Workshell.PE/Content/Resources/ResourceCollection.cs +++ /dev/null @@ -1,720 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - [Serializable] - public class ResourceException : Exception - { - - public ResourceException() : base() - { - } - - public ResourceException(string message) : base(message) - { - } - - public ResourceException(string message, Exception innerException) : base(message, innerException) - { - } - - protected ResourceException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - } - - public class Resource : ISupportsBytes - { - - public const uint DEFAULT_LANGUAGE = 1033; - - private ResourceType type; - private ResourceDirectoryEntry directory_entry; - private ResourceId id; - private Dictionary languages; - - internal Resource(ResourceType owningType, ResourceDirectoryEntry directoryEntry) - { - type = owningType; - directory_entry = directoryEntry; - - if (directory_entry.NameType == NameType.ID) - { - id = directory_entry.GetId(); - } - else - { - id = directory_entry.GetName(); - } - - languages = LoadLanguages(); - } - - #region Methods - - public ResourceData ToData() - { - return ToData(DEFAULT_LANGUAGE); - } - - public ResourceData ToData(uint languageId) - { - if (!languages.ContainsKey(languageId)) - { - return null; - } - else - { - ResourceDirectoryEntry language_entry = languages[languageId]; - ResourceDataEntry data_entry = language_entry.GetDataEntry(); - ResourceData data = data_entry.GetData(); - - return data; - } - } - - public byte[] GetBytes() - { - return GetBytes(DEFAULT_LANGUAGE); - } - - public byte[] GetBytes(uint languageId) - { - if (!languages.ContainsKey(languageId)) - { - throw new ResourceException(String.Format("Cannot find specified language: {0}", languageId)); - } - else - { - ResourceDirectoryEntry language_entry = languages[languageId]; - ResourceDataEntry data_entry = language_entry.GetDataEntry(); - ResourceData data = data_entry.GetData(); - - return data.GetBytes(); - } - } - - public void Save(string fileName) - { - Save(fileName, DEFAULT_LANGUAGE); - } - - public void Save(string fileName, uint language) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file, language); - file.Flush(); - } - } - - public void Save(Stream stream) - { - Save(stream, DEFAULT_LANGUAGE); - } - - public virtual void Save(Stream stream, uint language) - { - byte[] data = GetBytes(language); - - stream.Write(data, 0, data.Length); - } - - public override string ToString() - { - return id.ToString(); - } - - private Dictionary LoadLanguages() - { - Dictionary results = new Dictionary(); - ResourceDirectory directory = directory_entry.GetDirectory(); - - foreach (ResourceDirectoryEntry entry in directory) - { - results.Add(entry.GetId(),entry); - } - - return results; - } - - #endregion - - #region Properties - - public ResourceType Type - { - get - { - return type; - } - } - - public ResourceDirectoryEntry DirectoryEntry - { - get - { - return directory_entry; - } - } - - public ResourceId Id - { - get - { - return id; - } - } - - public uint[] Languages - { - get - { - return languages.Keys.ToArray(); - } - } - - #endregion - - } - - public sealed class ResourceType : IEnumerable - { - - public const ushort RT_CURSOR = 1; - public const ushort RT_BITMAP = 2; - public const ushort RT_ICON = 3; - public const ushort RT_MENU = 4; - public const ushort RT_DIALOG = 5; - public const ushort RT_STRING = 6; - public const ushort RT_FONTDIR = 7; - public const ushort RT_FONT = 8; - public const ushort RT_ACCELERATOR = 9; - public const ushort RT_RCDATA = 10; - public const ushort RT_MESSAGETABLE = 11; - public const ushort RT_GROUP_CURSOR = 12; - public const ushort RT_GROUP_ICON = 14; - public const ushort RT_VERSION = 16; - public const ushort RT_DLGINCLUDE = 17; - public const ushort RT_PLUGPLAY = 19; - public const ushort RT_VXD = 20; - public const ushort RT_ANICURSOR = 21; - public const ushort RT_ANIICON = 22; - public const ushort RT_HTML = 23; - public const ushort RT_MANIFEST = 24; - - private static Dictionary resource_types; - - private ResourceCollection resources; - private ResourceDirectoryEntry directory_entry; - private ResourceId id; - private Resource[] resource_items; - - static ResourceType() - { - resource_types = new Dictionary(); - } - - internal ResourceType(ResourceCollection owningResources, ResourceDirectoryEntry directoryEntry) - { - resources = owningResources; - directory_entry = directoryEntry; - - if (directory_entry.NameType == NameType.ID) - { - id = directory_entry.GetId(); - } - else - { - id = directory_entry.GetName(); - } - - resource_items = LoadResources(); - } - - #region Static Methods - - public static bool Register(ResourceId typeId, Type dataType) - { - if (resource_types.ContainsKey(typeId)) - return false; - - resource_types.Add(typeId, dataType); - - return true; - } - - public static bool Unregister(ResourceId typeId) - { - if (!resource_types.ContainsKey(typeId)) - return false; - - resource_types.Remove(typeId); - - return true; - } - - private static Type Get(ResourceId typeId) - { - if (resource_types.ContainsKey(typeId)) - { - return resource_types[typeId]; - } - else - { - return null; - } - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < resource_items.Length; i++) - { - Resource resource_name = resource_items[i]; - - yield return resource_name; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - string result; - - if (!id.IsNumeric) - { - result = id.ToString(); - } - else - { - string constant = ResourceCollection.GetTypeConstant(id); - - result = String.Format("{0} ({1})", id, constant); - } - - return result; - } - - private Resource[] LoadResources() - { - List results = new List(); - ResourceDirectory directory = directory_entry.GetDirectory(); - - foreach(ResourceDirectoryEntry entry in directory) - { - Type resource_type = Get(id); - Resource resource = null; - - if (resource_type != null) - { - if (!resource_type.IsSubclassOf(typeof(Resource))) - throw new Exception("Type must be a subclass of Resource."); - - resource = (Resource)Activator.CreateInstance(resource_type, this, entry); - } - else - { - resource = new Resource(this, entry); - } - - results.Add(resource); - } - - return results.ToArray(); - } - - #endregion - - #region Properties - - public ResourceCollection Resources - { - get - { - return resources; - } - } - - public ResourceDirectoryEntry DirectoryEntry - { - get - { - return directory_entry; - } - } - - public ResourceId Id - { - get - { - return id; - } - } - - public int Count - { - get - { - return resource_items.Length; - } - } - - public Resource this[int index] - { - get - { - return resource_items[index]; - } - } - - #endregion - - } - - public sealed class ResourceCollection : IEnumerable - { - - private static Dictionary> type_info; - - private ExecutableImage image; - private ResourceType[] types; - - static ResourceCollection() - { - type_info = new Dictionary>(); - - PopulateTypeInfo(); - } - - internal ResourceCollection(ExecutableImage exeImage, ResourceDirectory rootDirectory) - { - image = exeImage; - types = LoadTypes(rootDirectory); - } - - #region Static Methods - - public static ResourceCollection Get(ExecutableImage image) - { - ResourceDirectory root_directory = ResourceDirectory.GetRootDirectory(image); - - if (root_directory == null) - return null; - - ResourceCollection result = new ResourceCollection(image, root_directory); - - return result; - } - - public static string GetTypeName(uint typeId) - { - if (!type_info.ContainsKey(typeId)) - { - return String.Empty; - } - else - { - return type_info[typeId].Item1; - } - } - - public static string GetTypeConstant(uint typeId) - { - if (!type_info.ContainsKey(typeId)) - { - return String.Empty; - } - else - { - return type_info[typeId].Item2; - } - } - - private static void PopulateTypeInfo() - { - ushort[] known_types = new ushort[] { - ResourceType.RT_CURSOR, - ResourceType.RT_BITMAP, - ResourceType.RT_ICON, - ResourceType.RT_MENU, - ResourceType.RT_DIALOG, - ResourceType.RT_STRING, - ResourceType.RT_FONTDIR, - ResourceType.RT_FONT, - ResourceType.RT_ACCELERATOR, - ResourceType.RT_RCDATA, - ResourceType.RT_MESSAGETABLE, - ResourceType.RT_GROUP_CURSOR, - ResourceType.RT_GROUP_ICON, - ResourceType.RT_VERSION, - ResourceType.RT_DLGINCLUDE, - ResourceType.RT_PLUGPLAY, - ResourceType.RT_VXD, - ResourceType.RT_ANICURSOR, - ResourceType.RT_ANIICON, - ResourceType.RT_HTML, - ResourceType.RT_MANIFEST - }; - - foreach (ushort type_id in known_types) - PopulateTypeInfo(type_id); - } - - private static void PopulateTypeInfo(ushort typeId) - { - string name; - string constant_name; - - switch (typeId) - { - case ResourceType.RT_CURSOR: - name = "Cursor"; - constant_name = "RT_CURSOR"; - break; - case ResourceType.RT_BITMAP: - name = "Bitmap"; - constant_name = "RT_BITMAP"; - break; - case ResourceType.RT_ICON: - name = "Icon"; - constant_name = "RT_ICON"; - break; - case ResourceType.RT_MENU: - name = "Menu"; - constant_name = "RT_MENU"; - break; - case ResourceType.RT_DIALOG: - name = "Dialog"; - constant_name = "RT_DIALOG"; - break; - case ResourceType.RT_STRING: - name = "String"; - constant_name = "RT_STRING"; - break; - case ResourceType.RT_FONTDIR: - name = "Font Directory"; - constant_name = "RT_FONTDIR"; - break; - case ResourceType.RT_FONT: - name = "Font"; - constant_name = "RT_FONT"; - break; - case ResourceType.RT_ACCELERATOR: - name = "Accelerator"; - constant_name = "RT_ACCELERATOR"; - break; - case ResourceType.RT_RCDATA: - name = "RC Data"; - constant_name = "RT_RCDATA"; - break; - case ResourceType.RT_MESSAGETABLE: - name = "Message Table"; - constant_name = "RT_MESSAGETABLE"; - break; - case ResourceType.RT_GROUP_CURSOR: - name = "Cursor Group"; - constant_name = "RT_GROUP_CURSOR"; - break; - case ResourceType.RT_GROUP_ICON: - name = "Icon Group"; - constant_name = "RT_GROUP_ICON"; - break; - case ResourceType.RT_VERSION: - name = "Version"; - constant_name = "RT_VERSION"; - break; - case ResourceType.RT_DLGINCLUDE: - name = "Dialog Include"; - constant_name = "RT_DLGINCLUDE"; - break; - case ResourceType.RT_PLUGPLAY: - name = "Plug & Play"; - constant_name = "RT_PLUGPLAY"; - break; - case ResourceType.RT_VXD: - name = "VxD"; - constant_name = "RT_VXD"; - break; - case ResourceType.RT_ANICURSOR: - name = "Animated Cursor"; - constant_name = "RT_ANICURSOR"; - break; - case ResourceType.RT_ANIICON: - name = "Animated Icon"; - constant_name = "RT_ANIICON"; - break; - case ResourceType.RT_HTML: - name = "HTML"; - constant_name = "RT_HTML"; - break; - case ResourceType.RT_MANIFEST: - name = "Manifest"; - constant_name = "RT_MANIFEST"; - break; - default: - name = null; - constant_name = null; - break; - } - - if (name == null && constant_name == null) - return; - - Tuple tuple = new Tuple(name, constant_name); - - type_info.Add(typeId,tuple); - } - - #endregion - - #region Methods - - public Resource Find(ResourceDirectoryEntry typeEntry, ResourceDirectoryEntry nameEntry, ResourceDirectoryEntry langEntry) - { - foreach(ResourceType type in types) - { - ResourceId type_id; - - if (typeEntry.NameType == NameType.ID) - { - type_id = new ResourceId(typeEntry.GetId()); - } - else - { - type_id = new ResourceId(typeEntry.GetName()); - } - - if (type.Id == type_id) - { - foreach(Resource res in type) - { - ResourceId res_id; - - if (nameEntry.NameType == NameType.ID) - { - res_id = new ResourceId(nameEntry.GetId()); - } - else - { - res_id = new ResourceId(nameEntry.GetName()); - } - - if (res.Id == res_id) - { - uint lang_id = langEntry.GetId(); - - if (res.Languages.Contains(lang_id)) - return res; - } - } - } - } - - return null; - } - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < types.Length; i++) - yield return types[i]; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - private ResourceType[] LoadTypes(ResourceDirectory rootDirectory) - { - List results = new List(); - - foreach(ResourceDirectoryEntry entry in rootDirectory) - { - ResourceType type = new ResourceType(this, entry); - - results.Add(type); - } - - return results.ToArray(); - } - - #endregion - - #region Properties - - public ExecutableImage Image - { - get - { - return image; - } - } - - public int Count - { - get - { - return types.Length; - } - } - - public ResourceType this[int index] - { - get - { - return types[index]; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Resources/ResourceData.cs b/Src/Workshell.PE/Content/Resources/ResourceData.cs deleted file mode 100644 index 49641d0..0000000 --- a/Src/Workshell.PE/Content/Resources/ResourceData.cs +++ /dev/null @@ -1,92 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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.Resources -{ - - public sealed class ResourceData : ExecutableImageContent, ISupportsBytes - { - - private ResourceDataEntry data_entry; - - internal ResourceData(DataDirectory dataDirectory, Location dataLocation, ResourceDataEntry dataEntry) : base(dataDirectory,dataLocation) - { - data_entry = dataEntry; - } - - #region Methods - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - public void Save(string fileName) - { - using (FileStream file = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) - { - Save(file); - file.Flush(); - } - } - - public void Save(Stream stream) - { - byte[] data = GetBytes(); - - stream.Write(data, 0, data.Length); - } - - #endregion - - #region Properties - - public ResourceDataEntry DataEntry - { - get - { - return data_entry; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Resources/ResourceDataEntry.cs b/Src/Workshell.PE/Content/Resources/ResourceDataEntry.cs deleted file mode 100644 index 0c04d5d..0000000 --- a/Src/Workshell.PE/Content/Resources/ResourceDataEntry.cs +++ /dev/null @@ -1,140 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class ResourceDataEntry : ExecutableImageContent, ISupportsBytes - { - - private ResourceDirectoryEntry directory_entry; - private IMAGE_RESOURCE_DATA_ENTRY entry; - private ResourceData data; - - internal ResourceDataEntry(DataDirectory dataDirectory, Location dataLocation, ResourceDirectoryEntry directoryEntry) : base(dataDirectory,dataLocation) - { - Stream stream = directoryEntry.Directory.DataDirectory.Directories.Image.GetStream(); - - stream.Seek(dataLocation.FileOffset.ToInt64(),SeekOrigin.Begin); - - directory_entry = directoryEntry; - entry = Utils.Read(stream); - data = GetData(); - } - - #region Methods - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - public ResourceData GetData() - { - if (data == null) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - uint rva = entry.OffsetToData; - ulong va = DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase + rva; - ulong file_offset = calc.VAToOffset(va); - ulong size = entry.Size; - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, size, size, section); - - data = new ResourceData(DataDirectory, location, this); - } - - return data; - } - - #endregion - - #region Properties - - public ResourceDirectoryEntry DirectoryEntry - { - get - { - return directory_entry; - } - } - - [FieldAnnotation("Offset to Data")] - public uint OffsetToData - { - get - { - return entry.OffsetToData; - } - } - - [FieldAnnotation("Size")] - public uint Size - { - get - { - return entry.Size; - } - } - - [FieldAnnotation("Code Page")] - public uint CodePage - { - get - { - return entry.CodePage; - } - } - - [FieldAnnotation("Reserved")] - public uint Reserved - { - get - { - return entry.Reserved; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Resources/ResourceDirectory.cs b/Src/Workshell.PE/Content/Resources/ResourceDirectory.cs deleted file mode 100644 index 7fa9cf5..0000000 --- a/Src/Workshell.PE/Content/Resources/ResourceDirectory.cs +++ /dev/null @@ -1,220 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public sealed class ResourceDirectory : ExecutableImageContent, IEnumerable, ISupportsBytes - { - - private IMAGE_RESOURCE_DIRECTORY directory; - private ResourceDirectoryEntry directory_entry; - private ResourceDirectoryEntry[] entries; - - internal ResourceDirectory(DataDirectory dataDirectory, Location dataLocation, ResourceDirectoryEntry directoryEntry) : base(dataDirectory,dataLocation) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - stream.Seek(dataLocation.FileOffset.ToInt64(),SeekOrigin.Begin); - - directory = Utils.Read(stream); - directory_entry = directoryEntry; - - int count = directory.NumberOfNamedEntries + directory.NumberOfIdEntries; - List list = new List(count); - uint size = Utils.SizeOf().ToUInt32(); - ulong offset = dataLocation.FileOffset + size; - uint entry_size = Utils.SizeOf().ToUInt32(); - - for (int i = 0; i < count; i++) - { - stream.Seek(offset.ToInt64(),SeekOrigin.Begin); - - IMAGE_RESOURCE_DIRECTORY_ENTRY directory_entry = Utils.Read(stream); - - uint rva = calc.OffsetToRVA(offset); - ulong va = DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase + rva; - Section section = calc.RVAToSection(rva); - Location location = new Location(offset, rva, va, entry_size, entry_size, section); - - ResourceDirectoryEntry entry = new ResourceDirectoryEntry(DataDirectory, location, this, directory_entry); - - list.Add(entry); - offset += entry_size; - } - - entries = list.ToArray(); - } - - #region Static Methods - - public static ResourceDirectory GetRootDirectory(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ResourceTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.ResourceTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - uint rva = directory.VirtualAddress; - ulong va = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase + rva; - ulong file_offset = calc.RVAToOffset(rva); - uint size = Utils.SizeOf().ToUInt32(); - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, size, size, section); - ResourceDirectory result = new ResourceDirectory(directory, location, null); - - return result; - } - - #endregion - - #region Methods - - public IEnumerator GetEnumerator() - { - for(var i = 0; i < entries.Length; i++) - { - yield return entries[i]; - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public ResourceDirectoryEntry DirectoryEntry - { - get - { - return directory_entry; - } - } - - public int Count - { - get - { - return entries.Length; - } - } - - public ResourceDirectoryEntry this[int index] - { - get - { - return entries[index]; - } - } - - [FieldAnnotation("Characteristics")] - public uint Characteristics - { - get - { - return directory.Characteristics; - } - } - - [FieldAnnotation("Date/Time Stamp")] - public uint TimeDateStamp - { - get - { - return directory.TimeDateStamp; - } - } - - [FieldAnnotation("Major Version")] - public ushort MajorVersion - { - get - { - return directory.MajorVersion; - } - } - - [FieldAnnotation("Minor Version")] - public ushort MinorVersion - { - get - { - return directory.MinorVersion; - } - } - - [FieldAnnotation("Number of Named Entries")] - public ushort NumberOfNamedEntries - { - get - { - return directory.NumberOfNamedEntries; - } - } - - [FieldAnnotation("Number of ID Entries")] - public ushort NumberOfIdEntries - { - get - { - return directory.NumberOfIdEntries; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Resources/ResourceDirectoryEntry.cs b/Src/Workshell.PE/Content/Resources/ResourceDirectoryEntry.cs deleted file mode 100644 index cc60f77..0000000 --- a/Src/Workshell.PE/Content/Resources/ResourceDirectoryEntry.cs +++ /dev/null @@ -1,222 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.Resources -{ - - public enum NameType - { - ID, - Name - } - - public enum OffsetType - { - Directory, - Data - } - - public sealed class ResourceDirectoryEntry : ExecutableImageContent, ISupportsBytes - { - - private ResourceDirectory parent_directory; - private IMAGE_RESOURCE_DIRECTORY_ENTRY entry; - private string name; - private ResourceDirectory directory; - private ResourceDataEntry data; - - internal ResourceDirectoryEntry(DataDirectory dataDirectory, Location dataLocation, ResourceDirectory parentDirectory, IMAGE_RESOURCE_DIRECTORY_ENTRY directoryEntry) : base(dataDirectory,dataLocation) - { - parent_directory = parentDirectory; - entry = directoryEntry; - name = null; - directory = null; - data = null; - } - - #region Methods - - public uint GetId() - { - if ((entry.Name & 0x80000000) == 0x80000000) - { - return 0; - } - else - { - return entry.Name; - } - } - - public string GetName() - { - if (name == null) - { - if ((entry.Name & 0x80000000) == 0x80000000) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - uint offset = entry.Name & 0x7fffffff; - uint rva = DataDirectory.VirtualAddress + offset; - ulong file_offset = calc.RVAToOffset(rva); - - stream.Seek(file_offset.ToInt64(),SeekOrigin.Begin); - - ushort count = Utils.ReadUInt16(stream); - StringBuilder builder = new StringBuilder(count); - - for(int i = 0; i < count; i++) - { - ushort value = Utils.ReadUInt16(stream); - char c = Convert.ToChar(value); - - builder.Append(c); - } - - name = builder.ToString(); - } - else - { - name = String.Empty; - } - } - - return name; - } - - public ResourceDirectory GetDirectory() - { - if (directory == null && ((entry.OffsetToData & 0x80000000) == 0x80000000)) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - Stream stream = DataDirectory.Directories.Image.GetStream(); - - uint offset = entry.OffsetToData & 0x7fffffff; - uint rva = DataDirectory.VirtualAddress + offset; - ulong va = DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase + rva; - ulong file_offset = calc.RVAToOffset(rva); - uint size = Utils.SizeOf().ToUInt32(); - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, size, size, section); - - directory = new ResourceDirectory(parent_directory.DataDirectory,location,this); - } - - return directory; - } - - public ResourceDataEntry GetDataEntry() - { - if (data == null && ((entry.OffsetToData & 0x80000000) != 0x80000000)) - { - LocationCalculator calc = DataDirectory.Directories.Image.GetCalculator(); - - uint offset = entry.OffsetToData & 0x7fffffff; - uint rva = DataDirectory.VirtualAddress + offset; - ulong va = DataDirectory.Directories.Image.NTHeaders.OptionalHeader.ImageBase + rva; - ulong file_offset = calc.RVAToOffset(rva); - uint size = Utils.SizeOf().ToUInt32(); - Section section = calc.RVAToSection(rva); - Location location = new Location(file_offset, rva, va, size, size, section); - - data = new ResourceDataEntry(DataDirectory,location,this); - } - - return data; - } - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - public ResourceDirectory Directory - { - get - { - return parent_directory; - } - } - - public NameType NameType - { - get - { - return ((entry.Name & 0x80000000) == 0x80000000 ? NameType.Name : NameType.ID); - } - } - - public OffsetType OffsetType - { - get - { - return ((entry.OffsetToData & 0x80000000) == 0x80000000 ? OffsetType.Directory : OffsetType.Data); - } - } - - [FieldAnnotation("Name")] - public uint Name - { - get - { - return entry.Name; - } - } - - [FieldAnnotation("Offset to Data")] - public uint OffsetToData - { - get - { - return entry.OffsetToData; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/Resources/ResourceId.cs b/Src/Workshell.PE/Content/Resources/ResourceId.cs deleted file mode 100644 index 407efae..0000000 --- a/Src/Workshell.PE/Content/Resources/ResourceId.cs +++ /dev/null @@ -1,314 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Workshell.PE.Resources -{ - - public struct ResourceId : IEquatable - { - - private readonly uint id; - private readonly string name; - - public ResourceId(uint resourceId) - { - id = resourceId; - name = id.ToString(); - } - - public ResourceId(string resourceName) - { - id = 0; - name = resourceName; - } - - public ResourceId(uint resourceId, string resourceName) - { - id = resourceId; - name = resourceName; - } - - #region Operators - - public static implicit operator ResourceId(short resourceId) - { - return new ResourceId(Convert.ToUInt32(resourceId)); - } - - public static implicit operator ResourceId(int resourceId) - { - return new ResourceId(Convert.ToUInt32(resourceId)); - } - - public static implicit operator ResourceId(long resourceId) - { - return new ResourceId(Convert.ToUInt32(resourceId)); - } - - public static implicit operator ResourceId(ushort resourceId) - { - return new ResourceId(resourceId); - } - - public static implicit operator ResourceId(uint resourceId) - { - return new ResourceId(resourceId); - } - - public static implicit operator ResourceId(ulong resourceId) - { - return new ResourceId(Convert.ToUInt32(resourceId)); - } - - public static implicit operator ResourceId(string resourceName) - { - return new ResourceId(resourceName); - } - - public static implicit operator short(ResourceId resourceId) - { - return Convert.ToInt16(resourceId.Id); - } - - public static implicit operator int(ResourceId resourceId) - { - return Convert.ToInt32(resourceId.Id); - } - - public static implicit operator long(ResourceId resourceId) - { - return resourceId.Id; - } - - public static implicit operator ushort(ResourceId resourceId) - { - return Convert.ToUInt16(resourceId.Id); - } - - public static implicit operator uint(ResourceId resourceId) - { - return resourceId.Id; - } - - public static implicit operator ulong(ResourceId resourceId) - { - return resourceId.Id; - } - - public static implicit operator string(ResourceId resourceId) - { - if (resourceId.Id > 0) - { - return resourceId.Id.ToString(); - } - else - { - return resourceId.Name; - } - } - - public static bool operator ==(ResourceId firstId, ResourceId secondId) - { - return firstId.Equals(secondId); - } - - public static bool operator !=(ResourceId firstId, ResourceId secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, short secondId) - { - return (firstId.Id == Convert.ToUInt32(secondId)); - } - - public static bool operator !=(ResourceId firstId, short secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, ushort secondId) - { - return (firstId.Id == Convert.ToUInt32(secondId)); - } - - public static bool operator !=(ResourceId firstId, ushort secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, int secondId) - { - return (firstId.Id == Convert.ToUInt32(secondId)); - } - - public static bool operator !=(ResourceId firstId, int secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, uint secondId) - { - return (firstId.Id == secondId); - } - - public static bool operator !=(ResourceId firstId, uint secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, long secondId) - { - return (firstId.Id == Convert.ToUInt32(secondId)); - } - - public static bool operator !=(ResourceId firstId, long secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, ulong secondId) - { - return (firstId.Id == Convert.ToUInt32(secondId)); - } - - public static bool operator !=(ResourceId firstId, ulong secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(ResourceId firstId, string secondId) - { - return (String.Compare(firstId.Name, secondId, true) == 0); - } - - public static bool operator !=(ResourceId firstId, string secondId) - { - return !(firstId == secondId); - } - - public static bool operator ==(string firstId, ResourceId secondId) - { - return (String.Compare(firstId, secondId.Name, true) == 0); - } - - public static bool operator !=(string firstId, ResourceId secondId) - { - return !(firstId == secondId); - } - - #endregion - - #region Methods - - public override string ToString() - { - if (IsEmpty) - { - return "(Empty)"; - } - else - { - return name; - } - } - - public override int GetHashCode() - { - int hash = 13; - - hash = (hash * 7) + id.GetHashCode(); - hash = (hash * 7) + name.GetHashCode(); - - return hash; - } - - public override bool Equals(object obj) - { - if (Object.ReferenceEquals(obj, null)) - return false; - - if (!(obj is ResourceId)) - return false; - - if (Object.ReferenceEquals(obj, this)) - return true; - - return Equals((ResourceId)obj); - } - - public bool Equals(ResourceId resourceId) - { - return (id == resourceId.Id && String.Compare(name, resourceId.Name, true) == 0); - } - - #endregion - - #region Properties - - public uint Id - { - get - { - return id; - } - } - - public string Name - { - get - { - return name; - } - } - - public bool IsNumeric - { - get - { - return (id != 0); - } - } - - public bool IsEmpty - { - get - { - return (id == 0 && String.IsNullOrWhiteSpace(name)); - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Content/TLS/TLSDirectory.cs b/Src/Workshell.PE/Content/TLS/TLSDirectory.cs deleted file mode 100644 index 757645b..0000000 --- a/Src/Workshell.PE/Content/TLS/TLSDirectory.cs +++ /dev/null @@ -1,273 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Annotations; -using Workshell.PE.Extensions; -using Workshell.PE.Native; - -namespace Workshell.PE.TLS -{ - - public abstract class TLSDirectory : ExecutableImageContent, ISupportsBytes - { - - internal TLSDirectory(DataDirectory dataDirectory, Location tlsLocation) : base(dataDirectory,tlsLocation) - { - } - - #region Static Methods - - public static TLSDirectory Get(ExecutableImage image) - { - if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.TLSTable)) - return null; - - DataDirectory directory = image.NTHeaders.DataDirectories[DataDirectoryType.TLSTable]; - - if (DataDirectory.IsNullOrEmpty(directory)) - return null; - - LocationCalculator calc = directory.Directories.Image.GetCalculator(); - Section section = calc.RVAToSection(directory.VirtualAddress); - ulong file_offset = calc.RVAToOffset(section, directory.VirtualAddress); - ulong image_base = directory.Directories.Image.NTHeaders.OptionalHeader.ImageBase; - Location location = new Location(file_offset, directory.VirtualAddress, image_base + directory.VirtualAddress, directory.Size, directory.Size, section); - Stream stream = directory.Directories.Image.GetStream(); - - stream.Seek(file_offset.ToInt64(), SeekOrigin.Begin); - - bool is_64bit = directory.Directories.Image.Is64Bit; - TLSDirectory tls_directory; - - if (!is_64bit) - { - IMAGE_TLS_DIRECTORY32 tls_dir = Utils.Read(stream); - - tls_directory = new TLSDirectory32(directory, location, tls_dir); - } - else - { - IMAGE_TLS_DIRECTORY64 tls_dir = Utils.Read(stream); - - tls_directory = new TLSDirectory64(directory, location, tls_dir); - } - - return tls_directory; - } - - #endregion - - #region Methods - - public byte[] GetBytes() - { - Stream stream = DataDirectory.Directories.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - - #region Properties - - [FieldAnnotation("Start Address of Raw Data")] - public abstract ulong StartAddress - { - get; - } - - [FieldAnnotation("End Address of Raw Data")] - public abstract ulong EndAddress - { - get; - } - - [FieldAnnotation("Address of Index")] - public abstract ulong AddressOfIndex - { - get; - } - - [FieldAnnotation("Address of Callbacks")] - public abstract ulong AddressOfCallbacks - { - get; - } - - [FieldAnnotation("Size of Zero Fill")] - public abstract uint SizeOfZeroFill - { - get; - } - - [FieldAnnotation("Characteristics")] - public abstract uint Characteristics - { - get; - } - - #endregion - - } - - public sealed class TLSDirectory32 : TLSDirectory - { - - private IMAGE_TLS_DIRECTORY32 directory; - - internal TLSDirectory32(DataDirectory dataDirectory, Location tlsLocation, IMAGE_TLS_DIRECTORY32 tlsDirectory) : base(dataDirectory,tlsLocation) - { - directory = tlsDirectory; - } - - #region Properties - - public override ulong StartAddress - { - get - { - return directory.StartAddress; - } - } - - public override ulong EndAddress - { - get - { - return directory.EndAddress; - } - } - - public override ulong AddressOfIndex - { - get - { - return directory.AddressOfIndex; - } - } - - public override ulong AddressOfCallbacks - { - get - { - return directory.AddressOfCallbacks; - } - } - - public override uint SizeOfZeroFill - { - get - { - return directory.SizeOfZeroFill; - } - } - - public override uint Characteristics - { - get - { - return directory.Characteristics; - } - } - - #endregion - - } - - public sealed class TLSDirectory64 : TLSDirectory - { - - private IMAGE_TLS_DIRECTORY64 directory; - - internal TLSDirectory64(DataDirectory dataDirectory, Location tlsLocation, IMAGE_TLS_DIRECTORY64 tlsDirectory) : base(dataDirectory,tlsLocation) - { - directory = tlsDirectory; - } - - #region Properties - - public override ulong StartAddress - { - get - { - return directory.StartAddress; - } - } - - public override ulong EndAddress - { - get - { - return directory.EndAddress; - } - } - - public override ulong AddressOfIndex - { - get - { - return directory.AddressOfIndex; - } - } - - public override ulong AddressOfCallbacks - { - get - { - return directory.AddressOfCallbacks; - } - } - - public override uint SizeOfZeroFill - { - get - { - return directory.SizeOfZeroFill; - } - } - - public override uint Characteristics - { - get - { - return directory.Characteristics; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/DOSHeader.cs b/Src/Workshell.PE/DOSHeader.cs index 1096a41..c02296c 100644 --- a/Src/Workshell.PE/DOSHeader.cs +++ b/Src/Workshell.PE/DOSHeader.cs @@ -1,60 +1,28 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; -using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Annotations; +using Workshell.PE.Extensions; using Workshell.PE.Native; namespace Workshell.PE { - public sealed class DOSHeader : ISupportsLocation, ISupportsBytes { - public const ushort DOS_MAGIC_MZ = 23117; - private static readonly int size = Utils.SizeOf(); - - private ExecutableImage image; - private IMAGE_DOS_HEADER header; - private Location location; - - internal DOSHeader(ExecutableImage exeImage, IMAGE_DOS_HEADER dosHeader, ulong imageBase) + private readonly PortableExecutableImage _image; + private readonly IMAGE_DOS_HEADER _header; + + internal DOSHeader(PortableExecutableImage image, IMAGE_DOS_HEADER dosHeader, ulong imageBase) { - image = exeImage; - header = dosHeader; - location = new Location(0,0,imageBase,Convert.ToUInt32(DOSHeader.Size),Convert.ToUInt32(DOSHeader.Size)); + _image = image; + _header = dosHeader; + + Location = new Location(image.GetCalculator(), 0, 0, imageBase, Size.ToUInt32(), Size.ToUInt32()); } #region Methods @@ -66,8 +34,13 @@ public override string ToString() public byte[] GetBytes() { - Stream stream = image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } @@ -76,207 +49,71 @@ public byte[] GetBytes() #region Static Properties - public static int Size - { - get - { - return size; - } - } + public static int Size { get; } = Marshal.SizeOf(); #endregion #region Properties - public ExecutableImage Image - { - get - { - return image; - } - } - - public Location Location - { - get - { - return location; - } - } + public Location Location { get; } [FieldAnnotation("Signature")] - public ushort Magic - { - get - { - return header.e_magic; - } - } + public ushort Magic => _header.e_magic; [FieldAnnotation("Bytes on last page of file")] - public ushort BytesOnLastPage - { - get - { - return header.e_cblp; - } - } + public ushort BytesOnLastPage => _header.e_cblp; [FieldAnnotation("Pages in file")] - public ushort PagesInFile - { - get - { - return header.e_cp; - } - } + public ushort PagesInFile => _header.e_cp; [FieldAnnotation("Relocations")] - public ushort Relocations - { - get - { - return header.e_crlc; - } - } + public ushort Relocations => _header.e_crlc; [FieldAnnotation("Size of header in paragraphs")] - public ushort SizeHeaderParagraphs - { - get - { - return header.e_cparhdr; - } - } + public ushort SizeHeaderParagraphs => _header.e_cparhdr; [FieldAnnotation("Minimum extra paragraphs needed")] - public ushort MinExtraParagraphs - { - get - { - return header.e_minalloc; - } - } + public ushort MinExtraParagraphs => _header.e_minalloc; [FieldAnnotation("Maximum extra paragraphs needed")] - public ushort MaxExtraParagraphs - { - get - { - return header.e_maxalloc; - } - } + public ushort MaxExtraParagraphs => _header.e_maxalloc; [FieldAnnotation("Initial (relative) CS value")] - public ushort InitialSSValue - { - get - { - return header.e_ss; - } - } + public ushort InitialSSValue => _header.e_ss; [FieldAnnotation("Initial SP value")] - public ushort InitialSPValue - { - get - { - return header.e_sp; - } - } + public ushort InitialSPValue => _header.e_sp; [FieldAnnotation("Checksum")] - public ushort Checksum - { - get - { - return header.e_csum; - } - } + public ushort Checksum => _header.e_csum; [FieldAnnotation("Initial SP value")] - public ushort InitialIPValue - { - get - { - return header.e_ip; - } - } + public ushort InitialIPValue => _header.e_ip; [FieldAnnotation("Initial (relative) CS value")] - public ushort InitialCSValue - { - get - { - return header.e_cs; - } - } + public ushort InitialCSValue => _header.e_cs; [FieldAnnotation("File address of relocation table")] - public ushort FileAddressRelocationTable - { - get - { - return header.e_lfarlc; - } - } + public ushort FileAddressRelocationTable => _header.e_lfarlc; [FieldAnnotation("Overlay number")] - public ushort OverlayNumber - { - get - { - return header.e_ovno; - } - } + public ushort OverlayNumber => _header.e_ovno; [FieldAnnotation("Reserved",ArrayLength = 4)] - public ushort[] Reserved1 - { - get - { - return header.e_res_1; - } - } + public ushort[] Reserved1 => _header.e_res_1; [FieldAnnotation("OEM identifier")] - public ushort OEMIdentifier - { - get - { - return header.e_oemid; - } - } + public ushort OEMIdentifier => _header.e_oemid; [FieldAnnotation("OEM information")] - public ushort OEMInformation - { - get - { - return header.e_oeminfo; - } - } + public ushort OEMInformation => _header.e_oeminfo; [FieldAnnotation("Reserved",ArrayLength = 10)] - public ushort[] Reserved2 - { - get - { - return header.e_res_2; - } - } + public ushort[] Reserved2 => _header.e_res_2; [FieldAnnotation("File address of new header")] - public int FileAddressNewHeader - { - get - { - return header.e_lfanew; - } - } + public int FileAddressNewHeader => _header.e_lfanew; #endregion - } - } diff --git a/Src/Workshell.PE/DOSStub.cs b/Src/Workshell.PE/DOSStub.cs index 43bc36f..e080d77 100644 --- a/Src/Workshell.PE/DOSStub.cs +++ b/Src/Workshell.PE/DOSStub.cs @@ -1,50 +1,21 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; +using Workshell.PE.Extensions; namespace Workshell.PE { - public sealed class DOSStub : ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; - private ExecutableImage image; - private Location location; - - internal DOSStub(ExecutableImage exeImage, ulong stubOffset, uint stubSize, ulong imageBase) + internal DOSStub(PortableExecutableImage image, ulong stubOffset, uint stubSize, ulong imageBase) { - image = exeImage; - location = new Location(stubOffset,Convert.ToUInt32(stubOffset),imageBase + stubOffset,stubSize,stubSize); + _image = image; + + Location = new Location(image.GetCalculator(), stubOffset, Convert.ToUInt32(stubOffset), imageBase + stubOffset, stubSize, stubSize); } #region Methods @@ -56,8 +27,13 @@ public override string ToString() public byte[] GetBytes() { - Stream stream = image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } @@ -66,24 +42,8 @@ public byte[] GetBytes() #region Properties - public ExecutableImage Image - { - get - { - return image; - } - } - - public Location Location - { - get - { - return location; - } - } + public Location Location { get; } #endregion - } - } diff --git a/Src/Workshell.PE/DataDirectory.cs b/Src/Workshell.PE/DataDirectory.cs index 17e09cd..ddaf9be 100644 --- a/Src/Workshell.PE/DataDirectory.cs +++ b/Src/Workshell.PE/DataDirectory.cs @@ -1,43 +1,16 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; +using System.Net.Http.Headers; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; - +using Workshell.PE.Content; using Workshell.PE.Extensions; using Workshell.PE.Native; namespace Workshell.PE { - public enum DataDirectoryType : int { Unknown = -1, @@ -60,22 +33,23 @@ public enum DataDirectoryType : int public sealed class DataDirectory { - - private DataDirectoryCollection dirs; - private DataDirectoryType dir_type; - private IMAGE_DATA_DIRECTORY data_dir; - private ulong image_base; - private Lazy section_name; - private Lazy
section; - - internal DataDirectory(DataDirectoryCollection dataDirs, DataDirectoryType dirType, IMAGE_DATA_DIRECTORY dataDirectory, ulong imageBase) + private readonly PortableExecutableImage _image; + private readonly DataDirectoryType _type; + private readonly IMAGE_DATA_DIRECTORY _header; + private readonly ulong _imageBase; + private readonly Lazy _sectionName; + private readonly Lazy
_section; + + internal DataDirectory(PortableExecutableImage image, DataDirectoryCollection dataDirs, DataDirectoryType dirType, IMAGE_DATA_DIRECTORY dataDirectory, ulong imageBase) { - dirs = dataDirs; - dir_type = dirType; - data_dir = dataDirectory; - image_base = imageBase; - section_name = new Lazy(DoGetSectionName); - section = new Lazy
(DoGetSection); + _image = image; + _type = dirType; + _header = dataDirectory; + _imageBase = imageBase; + _sectionName = new Lazy(DoGetSectionName); + _section = new Lazy
(DoGetSection); + + Directories = dataDirs; } #region Static Methods @@ -100,18 +74,39 @@ public static bool IsNullOrEmpty(DataDirectory dataDirectory) public override string ToString() { - if (dir_type != DataDirectoryType.Unknown) - { - return dir_type.ToString(); - } - else - { - return String.Format("0x{0:X8}:{1}",data_dir.VirtualAddress,data_dir.Size); - } + return (_type != DataDirectoryType.Unknown ? _type.ToString() : $"0x{_header.VirtualAddress:X8}:{_header.Size}"); + } + + public DataContent GetContent() + { + return GetContentAsync().GetAwaiter().GetResult(); } - public ExecutableImageContent GetContent() + public async Task GetContentAsync() { + if (VirtualAddress == 0) + return null; + + switch (DirectoryType) + { + case DataDirectoryType.LoadConfigTable: + return await LoadConfigurationDirectory.LoadAsync(_image).ConfigureAwait(false); + case DataDirectoryType.TLSTable: + return await TLSDirectory.LoadAsync(_image).ConfigureAwait(false); + case DataDirectoryType.CertificateTable: + return await Certificate.LoadAsync(_image).ConfigureAwait(false); + case DataDirectoryType.CLRRuntimeHeader: + return await CLR.LoadAsync(_image).ConfigureAwait(false); + default: + { + var calc = _image.GetCalculator(); + var fileOffset = calc.VAToOffset(VirtualAddress); + var location = new Location(calc, fileOffset, calc.OffsetToRVA(fileOffset), VirtualAddress, Size, Size); + + return new DataContent(_image, this, location); + } + } + /* if (data_dir.VirtualAddress == 0) // No content so no point... return null; @@ -155,42 +150,40 @@ public ExecutableImageContent GetContent() return dir_content; */ - - return null; } public string GetSectionName() { - return section_name.Value; + return _sectionName.Value; } public Section GetSection() { - return section.Value; + return _section.Value; } private string DoGetSectionName() { - if (data_dir.VirtualAddress == 0 || dir_type == DataDirectoryType.CertificateTable) - return String.Empty; + if (_header.VirtualAddress == 0 || _type == DataDirectoryType.CertificateTable) + return string.Empty; - foreach (SectionTableEntry entry in dirs.Image.SectionTable) + foreach (var entry in _image.SectionTable) { - if (data_dir.VirtualAddress >= entry.VirtualAddress && data_dir.VirtualAddress < (entry.VirtualAddress + entry.SizeOfRawData)) + if (_header.VirtualAddress >= entry.VirtualAddress && _header.VirtualAddress < (entry.VirtualAddress + entry.SizeOfRawData)) return entry.Name; } - return String.Empty; + return string.Empty; } private Section DoGetSection() { - if (data_dir.VirtualAddress == 0 || dir_type == DataDirectoryType.CertificateTable) + if (_header.VirtualAddress == 0 || _type == DataDirectoryType.CertificateTable) return null; - foreach (Section section in dirs.Image.Sections) + foreach (var section in _image.Sections) { - if (data_dir.VirtualAddress >= section.TableEntry.VirtualAddress && data_dir.VirtualAddress < (section.TableEntry.VirtualAddress + section.TableEntry.SizeOfRawData)) + if (_header.VirtualAddress >= section.TableEntry.VirtualAddress && _header.VirtualAddress < (section.TableEntry.VirtualAddress + section.TableEntry.SizeOfRawData)) return section; } @@ -201,78 +194,43 @@ private Section DoGetSection() #region Properties - public DataDirectoryCollection Directories - { - get - { - return dirs; - } - } - - public DataDirectoryType DirectoryType - { - get - { - return dir_type; - } - } - - public uint VirtualAddress - { - get - { - return data_dir.VirtualAddress; - } - } - - public uint Size - { - get - { - return data_dir.Size; - } - } - - public bool IsEmpty - { - get - { - return (data_dir.Size == 0); - } - } + public DataDirectoryCollection Directories { get; } + public DataDirectoryType DirectoryType => _type; + public uint VirtualAddress => _header.VirtualAddress; + public uint Size => _header.Size; + public bool IsEmpty => (_header.Size == 0); #endregion - } public sealed class DataDirectoryCollection : IEnumerable, ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; + private readonly Dictionary _directories; - private ExecutableImage image; - private Location location; - private Dictionary dirs; - - internal DataDirectoryCollection(ExecutableImage exeImage, OptionalHeader optHeader, IMAGE_DATA_DIRECTORY[] dataDirs) + internal DataDirectoryCollection(PortableExecutableImage image, OptionalHeader optHeader, IMAGE_DATA_DIRECTORY[] dataDirs) { - uint size = (Utils.SizeOf() * dataDirs.Length).ToUInt32(); - ulong file_offset = optHeader.Location.FileOffset + optHeader.Location.FileSize; - uint rva = optHeader.Location.RelativeVirtualAddress + optHeader.Location.VirtualSize.ToUInt32(); - ulong va = optHeader.Location.VirtualAddress + optHeader.Location.VirtualSize; + _image = image; + + var size = (Marshal.SizeOf() * dataDirs.Length).ToUInt32(); + var fileOffset = optHeader.Location.FileOffset + optHeader.Location.FileSize; + var rva = optHeader.Location.RelativeVirtualAddress + optHeader.Location.VirtualSize.ToUInt32(); + var va = optHeader.Location.VirtualAddress + optHeader.Location.VirtualSize; - image = exeImage; - location = new Location(file_offset,rva,va,size,size); - dirs = new Dictionary(); + Location = new Location(image.GetCalculator(), fileOffset, rva, va, size, size); - for(int i = 0; i < dataDirs.Length; i++) + _directories = new Dictionary(); + + for (var i = 0; i < dataDirs.Length; i++) { - DataDirectoryType type = DataDirectoryType.Unknown; + var type = DataDirectoryType.Unknown; if (i >= 0 && i <= 14) type = (DataDirectoryType)i; - DataDirectory dir = new DataDirectory(this,type,dataDirs[i],optHeader.ImageBase); + var dir = new DataDirectory(image,this,type,dataDirs[i],optHeader.ImageBase); - dirs.Add(type,dir); + _directories.Add(type,dir); } } @@ -280,7 +238,7 @@ internal DataDirectoryCollection(ExecutableImage exeImage, OptionalHeader optHea public IEnumerator GetEnumerator() { - foreach(KeyValuePair kvp in dirs) + foreach(var kvp in _directories) { yield return kvp.Value; } @@ -293,15 +251,20 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() public byte[] GetBytes() { - Stream stream = image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } public bool Exists(DataDirectoryType directoryType) { - return dirs.ContainsKey(directoryType); + return _directories.ContainsKey(directoryType); } public bool Exists(int directoryType) @@ -313,57 +276,11 @@ public bool Exists(int directoryType) #region Properties - public ExecutableImage Image - { - get - { - return image; - } - } - - public Location Location - { - get - { - return location; - } - } + public Location Location { get; } + public int Count => _directories.Count; + public DataDirectory this[DataDirectoryType directoryType] => (_directories.ContainsKey(directoryType) ? _directories[directoryType] : null); + public DataDirectory this[int directoryType] => this[(DataDirectoryType)directoryType]; - public int Count - { - get - { - return dirs.Count; - } - } - - public DataDirectory this[DataDirectoryType directoryType] - { - get - { - if (dirs.ContainsKey(directoryType)) - { - return dirs[directoryType]; - } - else - { - return null; - } - } - } - - public DataDirectory this[int directoryType] - { - get - { - DataDirectoryType dir_type = (DataDirectoryType)directoryType; - - return this[dir_type]; - } - } - - #endregion - + #endregion } - } diff --git a/Src/Workshell.PE/Exceptions.cs b/Src/Workshell.PE/Exceptions.cs deleted file mode 100644 index 096184b..0000000 --- a/Src/Workshell.PE/Exceptions.cs +++ /dev/null @@ -1,82 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace Workshell.PE -{ - - [Serializable] - public class ExecutableImageException : Exception - { - - public ExecutableImageException() : base() - { - } - - public ExecutableImageException(string message) : base(message) - { - } - - public ExecutableImageException(string message, Exception innerException) : base(message, innerException) - { - } - - protected ExecutableImageException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - } - - [Serializable] - public class DataDirectoryException : Exception - { - - public DataDirectoryException() : base() - { - } - - public DataDirectoryException(string message) : base(message) - { - } - - public DataDirectoryException(string message, Exception innerException) : base(message, innerException) - { - } - - protected DataDirectoryException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - - } - -} diff --git a/Src/Workshell.PE/ExecutableImage.cs b/Src/Workshell.PE/ExecutableImage.cs deleted file mode 100644 index a1b2e49..0000000 --- a/Src/Workshell.PE/ExecutableImage.cs +++ /dev/null @@ -1,509 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE.Native; - -namespace Workshell.PE -{ - - public class ExecutableImage : IDisposable, ISupportsBytes - { - - private class PreloadedInformation - { - - public IMAGE_DOS_HEADER DOSHeader; - public ulong StubOffset; - public uint StubSize; - public IMAGE_FILE_HEADER FileHeader; - public IMAGE_OPTIONAL_HEADER32? OptHeader32; - public IMAGE_OPTIONAL_HEADER64? OptHeader64; - public IMAGE_DATA_DIRECTORY[] DataDirectories; - public IMAGE_SECTION_HEADER[] SectionHeaders; - - public bool Is32Bit; - public bool Is64Bit; - public bool IsCLR; - public bool IsSigned; - - } - - private bool _disposed; - private Stream _stream; - private bool _own_stream; - private LocationCalculator _calc; - - private DOSHeader _dos_header; - private DOSStub _dos_stub; - private NTHeaders _nt_headers; - private SectionTable _section_table; - private Sections _sections; - - private bool _is_32bit; - private bool _is_64bit; - private bool _is_clr; - private bool _is_signed; - - private ExecutableImage(Stream sourceStream, bool ownStream) - { - _disposed = false; - _stream = sourceStream; - _own_stream = ownStream; - _calc = null; - - _dos_header = null; - _dos_stub = null; - _nt_headers = null; - _section_table = null; - _sections = null; - - _is_32bit = false; - _is_64bit = false; - _is_clr = false; - _is_signed = false; - - Load(); - } - - #region Static Methods - - public static bool IsValid(Stream stream) - { - string error_message; - - return IsValid(stream,out error_message); - } - - public static bool IsValid(Stream stream, out string errorMessage) - { - PreloadedInformation preload_info = TryPreload(stream,out errorMessage); - - return (preload_info != null); - } - - public static bool IsValid(string fileName) - { - string error_message; - - return IsValid(fileName,out error_message); - } - - public static bool IsValid(string fileName, out string errorMessage) - { - using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read)) - { - return IsValid(file, out errorMessage); - } - } - - public static ExecutableImage FromFile(string fileName) - { - FileStream file = new FileStream(fileName,FileMode.Open,FileAccess.Read); - - return FromStream(file,true); - } - - public static ExecutableImage FromStream(Stream stream) - { - return FromStream(stream,false); - } - - public static ExecutableImage FromStream(Stream stream, bool ownStream) - { - return new ExecutableImage(stream,ownStream); - } - - private static PreloadedInformation TryPreload(Stream stream, out string errorMessage) - { - errorMessage = String.Empty; - - if (!stream.CanSeek) - { - errorMessage = "Cannot seek in stream."; - - return null; - } - - if (!stream.CanRead) - { - errorMessage = "Cannot read from stream."; - - return null; - } - - stream.Seek(0,SeekOrigin.Begin); - - IMAGE_DOS_HEADER dos_header = Utils.Read(stream,DOSHeader.Size); - - if (dos_header.e_magic != DOSHeader.DOS_MAGIC_MZ) - { - errorMessage = "Incorrect magic number specified in MS-DOS header."; - - return null; - } - - if (dos_header.e_lfanew == 0) - { - errorMessage = "No new header location specified in MS-DOS header, most likely a 16-bit executable."; - - return null; - } - - if (dos_header.e_lfanew >= (256 * (1024 * 1024))) - { - errorMessage = "New header location specified in MS-DOS header is beyond 256mb boundary (see RtlImageNtHeaderEx)."; - - return null; - } - - if (dos_header.e_lfanew % 4 != 0) - { - errorMessage = "New header location specified in MS-DOS header is not properly aligned."; - - return null; - } - - if (dos_header.e_lfanew < DOSHeader.Size) - { - errorMessage = "New header location specified is invalid."; - - return null; - } - - long stub_offset = DOSHeader.Size; - int stub_size = dos_header.e_lfanew - DOSHeader.Size; - - if ((stub_offset + stub_size) > stream.Length) - { - errorMessage = "Cannot read beyond end of stream."; - - return null; - } - - stream.Seek(dos_header.e_lfanew,SeekOrigin.Begin); - - uint pe_sig = Utils.ReadUInt32(stream); - - if (pe_sig != NTHeaders.PE_MAGIC_MZ) - { - errorMessage = "Incorrect PE signature found in NT Header."; - - return null; - } - - if ((stream.Position + FileHeader.Size) > stream.Length) - { - errorMessage = "Cannot read beyond end of stream."; - - return null; - } - - IMAGE_FILE_HEADER file_header = Utils.Read(stream,FileHeader.Size); - - ushort magic = 0; - long position = stream.Position; - - try - { - magic = Utils.ReadUInt16(stream); - } - finally - { - stream.Seek(position, SeekOrigin.Begin); - } - - bool is_32bit = (magic == (ushort)MagicType.PE32); - bool is_64bit = (magic == (ushort)MagicType.PE32plus); - - if (!is_32bit && !is_64bit) - throw new ExecutableImageException("Unknown PE type."); - - if ((stream.Position + file_header.SizeOfOptionalHeader) > stream.Length) - { - errorMessage = "Cannot read beyond end of stream."; - - return null; - } - - IMAGE_OPTIONAL_HEADER32 opt_header_32 = new IMAGE_OPTIONAL_HEADER32(); - IMAGE_OPTIONAL_HEADER64 opt_header_64 = new IMAGE_OPTIONAL_HEADER64(); - int data_dir_count = 0; - - if (!is_64bit) - { - opt_header_32 = Utils.Read(stream,OptionalHeader.Size32); - data_dir_count = Convert.ToInt32(opt_header_32.NumberOfRvaAndSizes); - } - else - { - opt_header_64 = Utils.Read(stream,OptionalHeader.Size64); - data_dir_count = Convert.ToInt32(opt_header_64.NumberOfRvaAndSizes); - } - - IMAGE_DATA_DIRECTORY[] data_directories = new IMAGE_DATA_DIRECTORY[data_dir_count]; - - for(int i = 0; i < data_dir_count; i++) - data_directories[i] = Utils.Read(stream,Utils.SizeOf()); - - long section_table_size = Utils.SizeOf() * file_header.NumberOfSections; - - if ((stream.Position + section_table_size) > stream.Length) - { - errorMessage = "Cannot read beyond end of stream."; - - return null; - } - - IMAGE_SECTION_HEADER[] section_table_headers = new IMAGE_SECTION_HEADER[file_header.NumberOfSections]; - - for(int i = 0; i < file_header.NumberOfSections; i++) - section_table_headers[i] = Utils.Read(stream,Utils.SizeOf()); - - foreach(IMAGE_SECTION_HEADER section_header in section_table_headers) - { - if ((section_header.PointerToRawData + section_header.SizeOfRawData) > stream.Length) - { - errorMessage = "Section data is beyond end of stream."; - - return null; - } - - stream.Seek(section_header.PointerToRawData,SeekOrigin.Begin); - } - - bool is_clr = false; - int clr_dir_index = (int)DataDirectoryType.CLRRuntimeHeader; - - if (clr_dir_index >= 0 && clr_dir_index <= (data_directories.Length - 1)) - { - IMAGE_DATA_DIRECTORY clr_dir = data_directories[clr_dir_index]; - - if (clr_dir.VirtualAddress > 0 && clr_dir.Size > 0) - 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), - StubSize = Convert.ToUInt32(stub_size), - FileHeader = file_header, - OptHeader32 = opt_header_32, - OptHeader64 = opt_header_64, - DataDirectories = data_directories, - SectionHeaders = section_table_headers, - - Is32Bit = is_32bit, - Is64Bit = is_64bit, - IsCLR = is_clr, - IsSigned = is_signed - }; - - return info; - } - - #endregion - - #region Methods - - public void Dispose() - { - if (!_disposed) - { - if (_own_stream) - _stream.Dispose(); - - _disposed = true; - } - } - - public Stream GetStream() - { - return _stream; - } - - public byte[] GetBytes() - { - using (MemoryStream mem = new MemoryStream()) - { - _stream.Seek(0,SeekOrigin.Begin); - _stream.CopyTo(mem,4096); - - return mem.ToArray(); - } - } - - public LocationCalculator GetCalculator() - { - if (_calc == null) - _calc = new LocationCalculator(this); - - return _calc; - } - - private void Load() - { - string error_message = String.Empty; - PreloadedInformation preload_info = TryPreload(_stream,out error_message); - - if (preload_info == null) - throw new ExecutableImageException(error_message); - - ulong image_base = 0; - - if (preload_info.OptHeader32 != null) - image_base = preload_info.OptHeader32.Value.ImageBase; - - if (preload_info.OptHeader64 != null) - image_base = preload_info.OptHeader64.Value.ImageBase; - - _dos_header = new DOSHeader(this,preload_info.DOSHeader,image_base); - _dos_stub = new DOSStub(this,preload_info.StubOffset,preload_info.StubSize,image_base); - - FileHeader file_header = new FileHeader(this,preload_info.FileHeader,_dos_stub.Location.FileOffset + _dos_stub.Location.FileSize + 4,image_base); - OptionalHeader opt_header; - - if (preload_info.Is32Bit) - { - opt_header = new OptionalHeader32(this,preload_info.OptHeader32.Value,file_header.Location.FileOffset + file_header.Location.FileSize,image_base); - } - else - { - opt_header = new OptionalHeader64(this,preload_info.OptHeader64.Value,file_header.Location.FileOffset + file_header.Location.FileSize,image_base); - } - - DataDirectoryCollection data_dirs = new DataDirectoryCollection(this,opt_header,preload_info.DataDirectories); - - _nt_headers = new NTHeaders(this,file_header.Location.FileOffset - 4,image_base,file_header,opt_header,data_dirs); - _section_table = new SectionTable(this,preload_info.SectionHeaders,_nt_headers.Location.FileOffset + _nt_headers.Location.FileSize,image_base); - _sections = new Sections(_section_table); - - _is_32bit = preload_info.Is32Bit; - _is_64bit = preload_info.Is64Bit; - _is_clr = preload_info.IsCLR; - _is_signed = preload_info.IsSigned; - } - - #endregion - - #region Properties - - public bool Is32Bit - { - get - { - return _is_32bit; - } - } - - public bool Is64Bit - { - get - { - return _is_64bit; - } - } - - public bool IsCLR - { - get - { - return _is_clr; - } - } - - public bool IsSigned - { - get - { - return _is_signed; - } - } - - public DOSHeader DOSHeader - { - get - { - return _dos_header; - } - } - - public DOSStub DOSStub - { - get - { - return _dos_stub; - } - } - - public NTHeaders NTHeaders - { - get - { - return _nt_headers; - } - } - - public SectionTable SectionTable - { - get - { - return _section_table; - } - } - - public Sections Sections - { - get - { - return _sections; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Extensions/Attributes.cs b/Src/Workshell.PE/Extensions/Attributes.cs deleted file mode 100644 index 2d5fd38..0000000 --- a/Src/Workshell.PE/Extensions/Attributes.cs +++ /dev/null @@ -1,222 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; - -namespace Workshell.PE.Extensions -{ - - internal static class AttributeExtensions - { - - public static Attribute GetCustomAttribute(this Assembly element, Type attributeType) - { - return Attribute.GetCustomAttribute(element, attributeType); - } - - public static Attribute GetCustomAttribute(this Module element, Type attributeType) - { - return Attribute.GetCustomAttribute(element, attributeType); - } - - public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType) - { - return Attribute.GetCustomAttribute(element, attributeType); - } - - public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType) - { - return Attribute.GetCustomAttribute(element, attributeType); - } - - public static T GetCustomAttribute(this Assembly element) where T : Attribute - { - return (T)GetCustomAttribute(element, typeof(T)); - } - - public static T GetCustomAttribute(this Module element) where T : Attribute - { - return (T)GetCustomAttribute(element, typeof(T)); - } - - public static T GetCustomAttribute(this MemberInfo element) where T : Attribute - { - return (T)GetCustomAttribute(element, typeof(T)); - } - - public static T GetCustomAttribute(this ParameterInfo element) where T : Attribute - { - return (T)GetCustomAttribute(element, typeof(T)); - } - - public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType, bool inherit) - { - return Attribute.GetCustomAttribute(element, attributeType, inherit); - } - - public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType, bool inherit) - { - return Attribute.GetCustomAttribute(element, attributeType, inherit); - } - - public static T GetCustomAttribute(this MemberInfo element, bool inherit) where T : Attribute - { - return (T)GetCustomAttribute(element, typeof(T), inherit); - } - - public static T GetCustomAttribute(this ParameterInfo element, bool inherit) where T : Attribute - { - return (T)GetCustomAttribute(element, typeof(T), inherit); - } - - public static IEnumerable GetCustomAttributes(this Assembly element) - { - return Attribute.GetCustomAttributes(element); - } - - public static IEnumerable GetCustomAttributes(this Module element) - { - return Attribute.GetCustomAttributes(element); - } - - public static IEnumerable GetCustomAttributes(this MemberInfo element) - { - return Attribute.GetCustomAttributes(element); - } - - public static IEnumerable GetCustomAttributes(this ParameterInfo element) - { - return Attribute.GetCustomAttributes(element); - } - - public static IEnumerable GetCustomAttributes(this MemberInfo element, bool inherit) - { - return Attribute.GetCustomAttributes(element, inherit); - } - - public static IEnumerable GetCustomAttributes(this ParameterInfo element, bool inherit) - { - return Attribute.GetCustomAttributes(element, inherit); - } - - public static IEnumerable GetCustomAttributes(this Assembly element, Type attributeType) - { - return Attribute.GetCustomAttributes(element, attributeType); - } - - public static IEnumerable GetCustomAttributes(this Module element, Type attributeType) - { - return Attribute.GetCustomAttributes(element, attributeType); - } - - public static IEnumerable GetCustomAttributes(this MemberInfo element, Type attributeType) - { - return Attribute.GetCustomAttributes(element, attributeType); - } - - public static IEnumerable GetCustomAttributes(this ParameterInfo element, Type attributeType) - { - return Attribute.GetCustomAttributes(element, attributeType); - } - - public static IEnumerable GetCustomAttributes(this Assembly element) where T : Attribute - { - return (IEnumerable)GetCustomAttributes(element, typeof(T)); - } - - public static IEnumerable GetCustomAttributes(this Module element) where T : Attribute - { - return (IEnumerable)GetCustomAttributes(element, typeof(T)); - } - - public static IEnumerable GetCustomAttributes(this MemberInfo element) where T : Attribute - { - return (IEnumerable)GetCustomAttributes(element, typeof(T)); - } - - public static IEnumerable GetCustomAttributes(this ParameterInfo element) where T : Attribute - { - return (IEnumerable)GetCustomAttributes(element, typeof(T)); - } - - public static IEnumerable GetCustomAttributes(this MemberInfo element, Type attributeType, bool inherit) - { - return Attribute.GetCustomAttributes(element, attributeType, inherit); - } - - public static IEnumerable GetCustomAttributes(this ParameterInfo element, Type attributeType, bool inherit) - { - return Attribute.GetCustomAttributes(element, attributeType, inherit); - } - - public static IEnumerable GetCustomAttributes(this MemberInfo element, bool inherit) where T : Attribute - { - return (IEnumerable)GetCustomAttributes(element, typeof(T), inherit); - } - - public static IEnumerable GetCustomAttributes(this ParameterInfo element, bool inherit) where T : Attribute - { - return (IEnumerable)GetCustomAttributes(element, typeof(T), inherit); - } - - public static bool IsDefined(this Assembly element, Type attributeType) - { - return Attribute.IsDefined(element, attributeType); - } - - public static bool IsDefined(this Module element, Type attributeType) - { - return Attribute.IsDefined(element, attributeType); - } - - public static bool IsDefined(this MemberInfo element, Type attributeType) - { - return Attribute.IsDefined(element, attributeType); - } - - public static bool IsDefined(this ParameterInfo element, Type attributeType) - { - return Attribute.IsDefined(element, attributeType); - } - - public static bool IsDefined(this MemberInfo element, Type attributeType, bool inherit) - { - return Attribute.IsDefined(element, attributeType, inherit); - } - - public static bool IsDefined(this ParameterInfo element, Type attributeType, bool inherit) - { - return Attribute.IsDefined(element, attributeType, inherit); - } - - } - -} diff --git a/Src/Workshell.PE/Extensions/Conversion.cs b/Src/Workshell.PE/Extensions/Conversion.cs index 8425d5e..acb5189 100644 --- a/Src/Workshell.PE/Extensions/Conversion.cs +++ b/Src/Workshell.PE/Extensions/Conversion.cs @@ -1,41 +1,12 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace Workshell.PE.Extensions { - internal static class ConversionExtensions { + #region Methods public static int ToInt32(this uint value) { @@ -77,6 +48,6 @@ public static ulong ToUInt64(this long value) return Convert.ToUInt32(value); } + #endregion } - } diff --git a/Src/Workshell.PE/FileHeader.cs b/Src/Workshell.PE/FileHeader.cs index a437ec3..c4854d3 100644 --- a/Src/Workshell.PE/FileHeader.cs +++ b/Src/Workshell.PE/FileHeader.cs @@ -1,44 +1,15 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; -using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Annotations; +using Workshell.PE.Extensions; using Workshell.PE.Native; namespace Workshell.PE { - public enum MachineType : int { Native = 0, @@ -89,21 +60,15 @@ public enum CharacteristicsType : int public sealed class FileHeader : ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; + private readonly IMAGE_FILE_HEADER _header; - internal static readonly int Size = Utils.SizeOf(); - - private ExecutableImage image; - private IMAGE_FILE_HEADER header; - private Location location; - - internal FileHeader(ExecutableImage exeImage, IMAGE_FILE_HEADER fileHeader, ulong headerOffset, ulong imageBase) + internal FileHeader(PortableExecutableImage image, IMAGE_FILE_HEADER fileHeader, ulong headerOffset, ulong imageBase) { - image = exeImage; - header = fileHeader; - - uint size = Convert.ToUInt32(Utils.SizeOf()); + _image = image; + _header = fileHeader; - location = new Location(headerOffset,Convert.ToUInt32(headerOffset),imageBase + headerOffset,size,size); + Location = new Location(image.GetCalculator(), headerOffset, headerOffset.ToUInt32(), imageBase + headerOffset, Size.ToUInt32(), Size.ToUInt32()); } #region Methods @@ -115,112 +80,66 @@ public override string ToString() public byte[] GetBytes() { - Stream stream = image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } public MachineType GetMachineType() { - return (MachineType)header.Machine; + return (MachineType)_header.Machine; } public DateTime GetTimeDateStamp() { - return Utils.ConvertTimeDateStamp(header.TimeDateStamp); + return Utils.ConvertTimeDateStamp(_header.TimeDateStamp); } public CharacteristicsType GetCharacteristics() { - return (CharacteristicsType)header.Characteristics; + return (CharacteristicsType)_header.Characteristics; } #endregion - #region Properties - public ExecutableImage Image - { - get - { - return image; - } - } + #region Static Properties - public Location Location - { - get - { - return location; - } - } + public static int Size { get; } = Marshal.SizeOf(); + + #endregion + + #region Properties + + public Location Location { get; } [FieldAnnotation("Machine Type",Flags = true,FlagType = typeof(MachineType))] - public ushort Machine - { - get - { - return header.Machine; - } - } + public ushort Machine => _header.Machine; [FieldAnnotation("Number of Sections")] - public ushort NumberOfSections - { - get - { - return header.NumberOfSections; - } - } + public ushort NumberOfSections => _header.NumberOfSections; [FieldAnnotation("Date/Time Stamp")] - public uint TimeDateStamp - { - get - { - return header.TimeDateStamp; - } - } + public uint TimeDateStamp => _header.TimeDateStamp; [FieldAnnotation("Pointer to Symbol Table")] - public uint PointerToSymbolTable - { - get - { - return header.PointerToSymbolTable; - } - } + public uint PointerToSymbolTable => _header.PointerToSymbolTable; [FieldAnnotation("Number of Symbols")] - public uint NumberOfSymbols - { - get - { - return header.NumberOfSymbols; - } - } + public uint NumberOfSymbols => _header.NumberOfSymbols; [FieldAnnotation("Size of Optional Header")] - public ushort SizeOfOptionalHeader - { - get - { - return header.SizeOfOptionalHeader; - } - } + public ushort SizeOfOptionalHeader => _header.SizeOfOptionalHeader; [FieldAnnotation("Characteristics",Flags = true,FlagType = typeof(CharacteristicsType))] - public ushort Characteristics - { - get - { - return header.Characteristics; - } - } + public ushort Characteristics => _header.Characteristics; #endregion - } - } diff --git a/Src/Workshell.PE/GenericLocatable.cs b/Src/Workshell.PE/GenericLocatable.cs deleted file mode 100644 index eb39ba4..0000000 --- a/Src/Workshell.PE/GenericLocatable.cs +++ /dev/null @@ -1,68 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Workshell.PE; - -namespace Workshell.PE -{ - - public sealed class GenericLocatable : ISupportsLocation - { - - private Location _location; - - public GenericLocatable(Location location) - { - _location = new Workshell.PE.Location(location.FileOffset, location.RelativeVirtualAddress, location.VirtualAddress, location.FileSize, location.VirtualSize); - } - - public GenericLocatable(ulong fileOffset, uint rva, ulong va, uint fileSize, uint virtualSize) - { - _location = new Workshell.PE.Location(fileOffset, rva, va, fileSize, virtualSize); - } - - #region Properties - - public Location Location - { - get - { - return _location; - } - } - - #endregion - - } - -} diff --git a/Src/Workshell.PE/Location.cs b/Src/Workshell.PE/Location.cs index 441c103..1e4feab 100644 --- a/Src/Workshell.PE/Location.cs +++ b/Src/Workshell.PE/Location.cs @@ -1,71 +1,43 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace Workshell.PE { - public sealed class Location : IEquatable { - - private ulong _file_offset; - private uint _rva; - private ulong _va; - private ulong _file_size; - private ulong _virtual_size; + private readonly LocationCalculator _calc; private Section _section; - public Location(ulong fileOffset, uint rva, ulong va, ulong fileSize, ulong virtualSize) : this(fileOffset,rva,va,fileSize,virtualSize,null) + internal Location(LocationCalculator calc, ulong fileOffset, uint rva, ulong va, ulong fileSize, ulong virtualSize) : this(calc, fileOffset, rva, va, fileSize, virtualSize, null) + { + } + + internal Location(ulong fileOffset, uint rva, ulong va, ulong fileSize, ulong virtualSize, Section section) : this(null, fileOffset, rva, va, fileSize, virtualSize, section) { } - public Location(ulong fileOffset, uint rva, ulong va, ulong fileSize, ulong virtualSize, Section section) + private Location(LocationCalculator calc, ulong fileOffset, uint rva, ulong va, ulong fileSize, ulong virtualSize, Section section) { - _file_offset = fileOffset; - _file_size = fileSize; - _rva = rva; - _va = va; - _virtual_size = virtualSize; + _calc = calc; _section = section; + + FileOffset = fileOffset; + FileSize = fileSize; + RelativeVirtualAddress = rva; + VirtualAddress = va; + VirtualSize = virtualSize; } + #region Methods public override string ToString() { - string result = String.Format("File Offset: 0x{0:X16}, File Size: 0x{1:X8}, RVA: 0x{2:X8}, Virtual Address: 0x{3:X16}, Virtual Size: 0x{4:X8}", FileOffset, FileSize, RelativeVirtualAddress, VirtualAddress, VirtualSize); + var result = $"File Offset: 0x{FileOffset:X16}, File Size: 0x{FileSize:X8} ({FileSize}), RVA: 0x{RelativeVirtualAddress:X8}, Virtual Address: 0x{VirtualAddress:X16}, Virtual Size: 0x{VirtualSize:X8} ({VirtualSize})"; - if (_section != null) - result += String.Format(", Section: {0}",_section.Name); + if (Section != null) + result += $", Section: {Section.Name}"; return result; } @@ -80,22 +52,19 @@ public bool Equals(Location other) if (other == null) return false; - if (_file_offset != other.FileOffset) + if (FileOffset != other.FileOffset) return false; - if (_file_size != other.FileSize) + if (FileSize != other.FileSize) return false; - if (_rva != other.RelativeVirtualAddress) + if (RelativeVirtualAddress != other.RelativeVirtualAddress) return false; - if (_va != other.VirtualAddress) + if (VirtualAddress != other.VirtualAddress) return false; - if (_virtual_size != other.VirtualSize) - return false; - - if (_section != other.Section) + if (VirtualSize != other.VirtualSize) return false; return true; @@ -103,16 +72,13 @@ public bool Equals(Location other) public override int GetHashCode() { - int hash = 13; - - hash = (hash * 7) + _file_offset.GetHashCode(); - hash = (hash * 7) + _file_size.GetHashCode(); - hash = (hash * 7) + _rva.GetHashCode(); - hash = (hash * 7) + _va.GetHashCode(); - hash = (hash * 7) + _virtual_size.GetHashCode(); + var hash = 13; - if (_section != null) - hash = (hash * 7) + _section.GetHashCode(); + hash = (hash * 7) + FileOffset.GetHashCode(); + hash = (hash * 7) + FileSize.GetHashCode(); + hash = (hash * 7) + RelativeVirtualAddress.GetHashCode(); + hash = (hash * 7) + VirtualAddress.GetHashCode(); + hash = (hash * 7) + VirtualSize.GetHashCode(); return hash; } @@ -121,56 +87,27 @@ public override int GetHashCode() #region Properties - public ulong FileOffset - { - get - { - return _file_offset; - } - } + public ulong FileOffset { get; } - public ulong FileSize - { - get - { - return _file_size; - } - } + public ulong FileSize { get; } - public uint RelativeVirtualAddress - { - get - { - return _rva; - } - } + public uint RelativeVirtualAddress { get; } - public ulong VirtualAddress - { - get - { - return _va; - } - } + public ulong VirtualAddress { get; } - public ulong VirtualSize - { - get - { - return _virtual_size; - } - } + public ulong VirtualSize { get; } public Section Section { get { + if (_section == null) + _section = _calc.VAToSection(VirtualAddress); + return _section; } } #endregion - } - } diff --git a/Src/Workshell.PE/LocationCalculator.cs b/Src/Workshell.PE/LocationCalculator.cs index 5a63796..6f4ec8c 100644 --- a/Src/Workshell.PE/LocationCalculator.cs +++ b/Src/Workshell.PE/LocationCalculator.cs @@ -1,47 +1,17 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading.Tasks; namespace Workshell.PE { - - public class LocationCalculator + public sealed class LocationCalculator { + private PortableExecutableImage _image; - private ExecutableImage reader; - - internal LocationCalculator(ExecutableImage imageReader) + internal LocationCalculator(PortableExecutableImage image) { - reader = imageReader; + _image = image; } #region Methods @@ -50,24 +20,24 @@ internal LocationCalculator(ExecutableImage imageReader) public Section VAToSection(ulong va) { - ulong image_base = reader.NTHeaders.OptionalHeader.ImageBase; - uint rva = Convert.ToUInt32(va - image_base); + var imageBase = _image.NTHeaders.OptionalHeader.ImageBase; + var rva = Convert.ToUInt32(va - imageBase); return RVAToSection(rva); } public SectionTableEntry VAToSectionTableEntry(ulong va) { - ulong image_base = reader.NTHeaders.OptionalHeader.ImageBase; - uint rva = Convert.ToUInt32(va - image_base); + var imageBase = _image.NTHeaders.OptionalHeader.ImageBase; + var rva = Convert.ToUInt32(va - imageBase); return RVAToSectionTableEntry(rva); } public ulong VAToOffset(ulong va) { - ulong image_base = reader.NTHeaders.OptionalHeader.ImageBase; - uint rva = Convert.ToUInt32(va - image_base); + var imageBase = _image.NTHeaders.OptionalHeader.ImageBase; + var rva = Convert.ToUInt32(va - imageBase); return RVAToOffset(rva); } @@ -79,15 +49,15 @@ public ulong VAToOffset(Section section, ulong va) public ulong VAToOffset(SectionTableEntry section, ulong va) { - ulong image_base = reader.NTHeaders.OptionalHeader.ImageBase; - uint rva = Convert.ToUInt32(va - image_base); + var imageBase = _image.NTHeaders.OptionalHeader.ImageBase; + var rva = Convert.ToUInt32(va - imageBase); return RVAToOffset(section,rva); } public ulong OffsetToVA(ulong offset) { - SectionTableEntry[] entries = reader.SectionTable.OrderBy(e => e.PointerToRawData).ToArray(); + var entries = _image.SectionTable.OrderBy(e => e.PointerToRawData).ToArray(); SectionTableEntry entry = null; for(var i = 0; i < entries.Length; i++) @@ -97,13 +67,9 @@ public ulong OffsetToVA(ulong offset) } if (entry != null) - { return OffsetToVA(entry, offset); - } - else - { - return 0; - } + + return 0; } public ulong OffsetToVA(Section section, ulong offset) @@ -113,37 +79,37 @@ public ulong OffsetToVA(Section section, ulong offset) public ulong OffsetToVA(SectionTableEntry section, ulong offset) { - ulong image_base = reader.NTHeaders.OptionalHeader.ImageBase; - uint rva = Convert.ToUInt32((offset + section.VirtualAddress) - section.PointerToRawData); + var imageBase = _image.NTHeaders.OptionalHeader.ImageBase; + var rva = Convert.ToUInt32((offset + section.VirtualAddress) - section.PointerToRawData); - return image_base + rva; + return imageBase + rva; } /* RVA */ public Section RVAToSection(uint rva) { - SectionTableEntry entry = RVAToSectionTableEntry(rva); + var entry = RVAToSectionTableEntry(rva); if (entry == null) return null; - return reader.Sections[entry]; + return _image.Sections[entry]; } public SectionTableEntry RVAToSectionTableEntry(uint rva) { - SectionTableEntry[] entries = reader.SectionTable.OrderBy(e => e.VirtualAddress).ToArray(); + var entries = _image.SectionTable.OrderBy(e => e.VirtualAddress).ToArray(); SectionTableEntry entry = null; for (var i = 0; i < entries.Length; i++) { - uint max_rva = entries[i].VirtualAddress + entries[i].SizeOfRawData; + var maxRVA = entries[i].VirtualAddress + entries[i].SizeOfRawData; if (i != (entries.Length - 1)) - max_rva = entries[i + 1].VirtualAddress; + maxRVA = entries[i + 1].VirtualAddress; - if (rva >= entries[i].VirtualAddress && rva < max_rva) + if (rva >= entries[i].VirtualAddress && rva < maxRVA) entry = entries[i]; } @@ -152,7 +118,7 @@ public SectionTableEntry RVAToSectionTableEntry(uint rva) public ulong RVAToOffset(uint rva) { - SectionTableEntry[] entries = reader.SectionTable.OrderBy(e => e.VirtualAddress).ToArray(); + var entries = _image.SectionTable.OrderBy(e => e.VirtualAddress).ToArray(); SectionTableEntry entry = null; for (var i = 0; i < entries.Length; i++) @@ -162,13 +128,9 @@ public ulong RVAToOffset(uint rva) } if (entry != null) - { return RVAToOffset(entry, rva); - } - else - { - return 0; - } + + return 0; } public ulong RVAToOffset(Section section, uint rva) @@ -178,14 +140,14 @@ public ulong RVAToOffset(Section section, uint rva) public ulong RVAToOffset(SectionTableEntry section, uint rva) { - ulong offset = (rva - section.VirtualAddress) + section.PointerToRawData; + var offset = (rva - section.VirtualAddress) + section.PointerToRawData; return offset; } public uint OffsetToRVA(ulong offset) { - SectionTableEntry[] entries = reader.SectionTable.OrderBy(e => e.PointerToRawData).ToArray(); + var entries = _image.SectionTable.OrderBy(e => e.PointerToRawData).ToArray(); SectionTableEntry entry = null; for (var i = 0; i < entries.Length; i++) @@ -195,13 +157,9 @@ public uint OffsetToRVA(ulong offset) } if (entry != null) - { return OffsetToRVA(entry, offset); - } - else - { - return 0; - } + + return 0; } public uint OffsetToRVA(Section section, ulong offset) @@ -211,13 +169,11 @@ public uint OffsetToRVA(Section section, ulong offset) public uint OffsetToRVA(SectionTableEntry section, ulong offset) { - uint rva = Convert.ToUInt32((offset + section.VirtualAddress) - section.PointerToRawData); + var rva = Convert.ToUInt32((offset + section.VirtualAddress) - section.PointerToRawData); return rva; } #endregion - } - } diff --git a/Src/Workshell.PE/MoreLinq/DistinctBy.cs b/Src/Workshell.PE/MoreLinq/DistinctBy.cs deleted file mode 100644 index 7fe5451..0000000 --- a/Src/Workshell.PE/MoreLinq/DistinctBy.cs +++ /dev/null @@ -1,105 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -#if NO_HASHSET -using System.Linq; -#endif - -// To stop any collisions with references to actual MoreLinq library, -// renamed namespace and made all classes internal. - -namespace Workshell.MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { - /// - /// Returns all distinct elements of the given source, where "distinctness" - /// is determined via a projection and the default equality comparer for the projected type. - /// - /// - /// This operator uses deferred execution and streams the results, although - /// a set of already-seen keys is retained. If a key is seen multiple times, - /// only the first element with that key is returned. - /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Projection for determining "distinctness" - /// A sequence consisting of distinct elements from the source sequence, - /// comparing them by the specified key projection. - - public static IEnumerable DistinctBy(this IEnumerable source, - Func keySelector) - { - return source.DistinctBy(keySelector, null); - } - - /// - /// Returns all distinct elements of the given source, where "distinctness" - /// is determined via a projection and the specified comparer for the projected type. - /// - /// - /// This operator uses deferred execution and streams the results, although - /// a set of already-seen keys is retained. If a key is seen multiple times, - /// only the first element with that key is returned. - /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Projection for determining "distinctness" - /// The equality comparer to use to determine whether or not keys are equal. - /// If null, the default equality comparer for TSource is used. - /// A sequence consisting of distinct elements from the source sequence, - /// comparing them by the specified key projection. - - public static IEnumerable DistinctBy(this IEnumerable source, - Func keySelector, IEqualityComparer comparer) - { - if (source == null) throw new ArgumentNullException("source"); - if (keySelector == null) throw new ArgumentNullException("keySelector"); - return DistinctByImpl(source, keySelector, comparer); - } - - private static IEnumerable DistinctByImpl(IEnumerable source, - Func keySelector, IEqualityComparer comparer) - { -#if !NO_HASHSET - var knownKeys = new HashSet(comparer); - foreach (var element in source) - { - if (knownKeys.Add(keySelector(element))) - { - yield return element; - } - } -#else - // - // On platforms where LINQ is available but no HashSet - // (like on Silverlight), implement this operator using - // existing LINQ operators. Using GroupBy is slightly less - // efficient since it has do all the grouping work before - // it can start to yield any one element from the source. - // - - return source.GroupBy(keySelector, comparer).Select(g => g.First()); -#endif - } - } -} \ No newline at end of file diff --git a/Src/Workshell.PE/MoreLinq/MaxBy.cs b/Src/Workshell.PE/MoreLinq/MaxBy.cs deleted file mode 100644 index 0b70267..0000000 --- a/Src/Workshell.PE/MoreLinq/MaxBy.cs +++ /dev/null @@ -1,100 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -// To stop any collisions with references to actual MoreLinq library, -// renamed namespace and made all classes internal. - -namespace Workshell.MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { - /// - /// Returns the maximal element of the given sequence, based on - /// the given projection. - /// - /// - /// If more than one element has the maximal projected value, the first - /// one encountered will be returned. This overload uses the default comparer - /// for the projected type. This operator uses immediate execution, but - /// only buffers a single result (the current maximal element). - /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Selector to use to pick the results to compare - /// The maximal element, according to the projection. - /// or is null - /// is empty - - public static TSource MaxBy(this IEnumerable source, - Func selector) - { - return source.MaxBy(selector, Comparer.Default); - } - - /// - /// Returns the maximal element of the given sequence, based on - /// the given projection and the specified comparer for projected values. - /// - /// - /// If more than one element has the maximal projected value, the first - /// one encountered will be returned. This overload uses the default comparer - /// for the projected type. This operator uses immediate execution, but - /// only buffers a single result (the current maximal element). - /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Selector to use to pick the results to compare - /// Comparer to use to compare projected values - /// The maximal element, according to the projection. - /// , - /// or is null - /// is empty - - public static TSource MaxBy(this IEnumerable source, - Func selector, IComparer comparer) - { - if (source == null) throw new ArgumentNullException("source"); - if (selector == null) throw new ArgumentNullException("selector"); - if (comparer == null) throw new ArgumentNullException("comparer"); - using (var sourceIterator = source.GetEnumerator()) - { - if (!sourceIterator.MoveNext()) - { - throw new InvalidOperationException("Sequence contains no elements"); - } - var max = sourceIterator.Current; - var maxKey = selector(max); - while (sourceIterator.MoveNext()) - { - var candidate = sourceIterator.Current; - var candidateProjected = selector(candidate); - if (comparer.Compare(candidateProjected, maxKey) > 0) - { - max = candidate; - maxKey = candidateProjected; - } - } - return max; - } - } - } -} \ No newline at end of file diff --git a/Src/Workshell.PE/MoreLinq/MinBy.cs b/Src/Workshell.PE/MoreLinq/MinBy.cs deleted file mode 100644 index aed99c0..0000000 --- a/Src/Workshell.PE/MoreLinq/MinBy.cs +++ /dev/null @@ -1,101 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -// To stop any collisions with references to actual MoreLinq library, -// renamed namespace and made all classes internal. - -namespace Workshell.MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { - /// - /// Returns the minimal element of the given sequence, based on - /// the given projection. - /// - /// - /// If more than one element has the minimal projected value, the first - /// one encountered will be returned. This overload uses the default comparer - /// for the projected type. This operator uses immediate execution, but - /// only buffers a single result (the current minimal element). - /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Selector to use to pick the results to compare - /// The minimal element, according to the projection. - /// or is null - /// is empty - - public static TSource MinBy(this IEnumerable source, - Func selector) - { - return source.MinBy(selector, Comparer.Default); - } - - /// - /// Returns the minimal element of the given sequence, based on - /// the given projection and the specified comparer for projected values. - /// - /// - /// If more than one element has the minimal projected value, the first - /// one encountered will be returned. This overload uses the default comparer - /// for the projected type. This operator uses immediate execution, but - /// only buffers a single result (the current minimal element). - /// - /// Type of the source sequence - /// Type of the projected element - /// Source sequence - /// Selector to use to pick the results to compare - /// Comparer to use to compare projected values - /// The minimal element, according to the projection. - /// , - /// or is null - /// is empty - - public static TSource MinBy(this IEnumerable source, - Func selector, IComparer comparer) - { - if (source == null) throw new ArgumentNullException("source"); - if (selector == null) throw new ArgumentNullException("selector"); - if (comparer == null) throw new ArgumentNullException("comparer"); - using (var sourceIterator = source.GetEnumerator()) - { - if (!sourceIterator.MoveNext()) - { - throw new InvalidOperationException("Sequence contains no elements"); - } - var min = sourceIterator.Current; - var minKey = selector(min); - while (sourceIterator.MoveNext()) - { - var candidate = sourceIterator.Current; - var candidateProjected = selector(candidate); - if (comparer.Compare(candidateProjected, minKey) < 0) - { - min = candidate; - minKey = candidateProjected; - } - } - return min; - } - } - } - -} diff --git a/Src/Workshell.PE/MoreLinq/MoreEnumerable.cs b/Src/Workshell.PE/MoreLinq/MoreEnumerable.cs deleted file mode 100644 index d2466fb..0000000 --- a/Src/Workshell.PE/MoreLinq/MoreEnumerable.cs +++ /dev/null @@ -1,36 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -// To stop any collisions with references to actual MoreLinq library, -// renamed namespace and made all classes internal. - -namespace Workshell.MoreLinq -{ - - using System.Collections.Generic; - - /// - /// Provides a set of static methods for querying objects that - /// implement . The actual methods - /// are implemented in files reflecting the method name. - /// - - internal static partial class MoreEnumerable - { - } - -} \ No newline at end of file diff --git a/Src/Workshell.PE/NTHeaders.cs b/Src/Workshell.PE/NTHeaders.cs index 8000cb7..fff7bb8 100644 --- a/Src/Workshell.PE/NTHeaders.cs +++ b/Src/Workshell.PE/NTHeaders.cs @@ -1,62 +1,27 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Extensions; namespace Workshell.PE { - - public class NTHeaders : ISupportsLocation, ISupportsBytes + public sealed class NTHeaders : ISupportsLocation, ISupportsBytes { - public const uint PE_MAGIC_MZ = 17744; - private ExecutableImage image; - private Location location; - private FileHeader file_header; - private OptionalHeader opt_header; - private DataDirectoryCollection data_dirs; + private readonly PortableExecutableImage _image; - internal NTHeaders(ExecutableImage exeImage, ulong headerOffset, ulong imageBase, FileHeader fileHeader, OptionalHeader optHeader, DataDirectoryCollection dataDirs) + internal NTHeaders(PortableExecutableImage image, ulong headerOffset, ulong imageBase, FileHeader fileHeader, OptionalHeader optHeader, DataDirectoryCollection dataDirs) { - uint size = (4U + fileHeader.Location.FileSize + optHeader.Location.FileSize + dataDirs.Location.FileSize).ToUInt32(); + _image = image; + + var size = (4U + fileHeader.Location.FileSize + optHeader.Location.FileSize + dataDirs.Location.FileSize).ToUInt32(); - image = exeImage; - location = new Location(headerOffset,Convert.ToUInt32(headerOffset),imageBase + headerOffset,size,size); - file_header = fileHeader; - opt_header = optHeader; - data_dirs = dataDirs; + Location = new Location(image.GetCalculator(), headerOffset, headerOffset.ToUInt32(), imageBase + headerOffset, size, size); + FileHeader = fileHeader; + OptionalHeader = optHeader; + DataDirectories = dataDirs; } #region Methods @@ -68,58 +33,26 @@ public override string ToString() public byte[] GetBytes() { - Stream stream = image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); - - return buffer; + return GetBytesAsync().GetAwaiter().GetResult(); } - #endregion - - #region Properties - - public ExecutableImage Image + public async Task GetBytesAsync() { - get - { - return image; - } - } + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); - public Location Location - { - get - { - return location; - } + return buffer; } - public FileHeader FileHeader - { - get - { - return file_header; - } - } + #endregion - public OptionalHeader OptionalHeader - { - get - { - return opt_header; - } - } + #region Properties - public DataDirectoryCollection DataDirectories - { - get - { - return data_dirs; - } - } + public Location Location { get; } + public FileHeader FileHeader { get; } + public OptionalHeader OptionalHeader { get; } + public DataDirectoryCollection DataDirectories { get; } #endregion - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_BASE_RELOCATION.cs b/Src/Workshell.PE/Native/IMAGE_BASE_RELOCATION.cs deleted file mode 100644 index 2961606..0000000 --- a/Src/Workshell.PE/Native/IMAGE_BASE_RELOCATION.cs +++ /dev/null @@ -1,47 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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)] - internal struct IMAGE_BASE_RELOCATION - { - - public uint VirtualAddress; - public uint SizeOfBlock; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_COR20_HEADER.cs b/Src/Workshell.PE/Native/IMAGE_COR20_HEADER.cs index 66d9fc1..0fdef25 100644 --- a/Src/Workshell.PE/Native/IMAGE_COR20_HEADER.cs +++ b/Src/Workshell.PE/Native/IMAGE_COR20_HEADER.cs @@ -1,44 +1,13 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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)] internal struct IMAGE_COR20_HEADER { - public uint cb; public ushort MajorRuntimeVersion; public ushort MinorRuntimeVersion; @@ -51,7 +20,5 @@ internal struct IMAGE_COR20_HEADER public IMAGE_DATA_DIRECTORY VTableFixups; public IMAGE_DATA_DIRECTORY ExportAddressTableJumps; public IMAGE_DATA_DIRECTORY ManagedNativeHeader; - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_DATA_DIRECTORY.cs b/Src/Workshell.PE/Native/IMAGE_DATA_DIRECTORY.cs index 488c801..e68cb08 100644 --- a/Src/Workshell.PE/Native/IMAGE_DATA_DIRECTORY.cs +++ b/Src/Workshell.PE/Native/IMAGE_DATA_DIRECTORY.cs @@ -1,47 +1,14 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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)] internal struct IMAGE_DATA_DIRECTORY { - public uint VirtualAddress; public uint Size; - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_DEBUG_DIRECTORY.cs b/Src/Workshell.PE/Native/IMAGE_DEBUG_DIRECTORY.cs deleted file mode 100644 index 55a4321..0000000 --- a/Src/Workshell.PE/Native/IMAGE_DEBUG_DIRECTORY.cs +++ /dev/null @@ -1,53 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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, Pack = 1)] - internal struct IMAGE_DEBUG_DIRECTORY - { - - public uint Characteristics; - public uint TimeDateStamp; - public ushort MajorVersion; - public ushort MinorVersion; - public uint Type; - public uint SizeOfData; - public uint AddressOfRawData; - public uint PointerToRawData; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_DELAY_IMPORT_DESCRIPTOR.cs b/Src/Workshell.PE/Native/IMAGE_DELAY_IMPORT_DESCRIPTOR.cs deleted file mode 100644 index 3f3a159..0000000 --- a/Src/Workshell.PE/Native/IMAGE_DELAY_IMPORT_DESCRIPTOR.cs +++ /dev/null @@ -1,53 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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, Pack = 1)] - internal struct IMAGE_DELAY_IMPORT_DESCRIPTOR - { - - public uint Attributes; - public uint Name; - public uint ModuleHandle; - public uint DelayAddressTable; - public uint DelayNameTable; - public uint BoundDelayIAT; - public uint UnloadDelayIAT; - public uint TimeDateStamp; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_DOS_HEADER.cs b/Src/Workshell.PE/Native/IMAGE_DOS_HEADER.cs index 1614285..3f78708 100644 --- a/Src/Workshell.PE/Native/IMAGE_DOS_HEADER.cs +++ b/Src/Workshell.PE/Native/IMAGE_DOS_HEADER.cs @@ -1,44 +1,13 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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, Pack = 1)] internal struct IMAGE_DOS_HEADER { - public ushort e_magic; // Magic number public ushort e_cblp; // Bytes on last page of file public ushort e_cp; // Pages in file @@ -60,7 +29,5 @@ internal struct IMAGE_DOS_HEADER [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public ushort[] e_res_2; // Reserved words public int e_lfanew; // File address of new exe header - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_EXPORT_DIRECTORY.cs b/Src/Workshell.PE/Native/IMAGE_EXPORT_DIRECTORY.cs deleted file mode 100644 index 3032290..0000000 --- a/Src/Workshell.PE/Native/IMAGE_EXPORT_DIRECTORY.cs +++ /dev/null @@ -1,56 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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)] - internal struct IMAGE_EXPORT_DIRECTORY - { - - public uint Characteristics; - public uint TimeDateStamp; - public ushort MajorVersion; - public ushort MinorVersion; - public uint Name; - public uint Base; - public uint NumberOfFunctions; - public uint NumberOfNames; - public uint AddressOfFunctions; // RVA from base of image - public uint AddressOfNames; // RVA from base of image - public uint AddressOfNameOrdinals; // RVA from base of image - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_FILE_HEADER.cs b/Src/Workshell.PE/Native/IMAGE_FILE_HEADER.cs index c5de62a..152c771 100644 --- a/Src/Workshell.PE/Native/IMAGE_FILE_HEADER.cs +++ b/Src/Workshell.PE/Native/IMAGE_FILE_HEADER.cs @@ -1,44 +1,13 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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, Pack = 1)] internal struct IMAGE_FILE_HEADER { - public ushort Machine; public ushort NumberOfSections; public uint TimeDateStamp; @@ -46,7 +15,5 @@ internal struct IMAGE_FILE_HEADER public uint NumberOfSymbols; public ushort SizeOfOptionalHeader; public ushort Characteristics; - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_IMPORT_DESCRIPTOR.cs b/Src/Workshell.PE/Native/IMAGE_IMPORT_DESCRIPTOR.cs deleted file mode 100644 index 0f2605f..0000000 --- a/Src/Workshell.PE/Native/IMAGE_IMPORT_DESCRIPTOR.cs +++ /dev/null @@ -1,50 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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, Pack = 1)] - internal struct IMAGE_IMPORT_DESCRIPTOR - { - - public uint OriginalFirstThunk; - public uint TimeDateStamp; - public uint ForwarderChain; - public uint Name; - public uint FirstThunk; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_LOAD_CONFIG_DIRECTORY.cs b/Src/Workshell.PE/Native/IMAGE_LOAD_CONFIG_DIRECTORY.cs index 1c6c70b..156fc94 100644 --- a/Src/Workshell.PE/Native/IMAGE_LOAD_CONFIG_DIRECTORY.cs +++ b/Src/Workshell.PE/Native/IMAGE_LOAD_CONFIG_DIRECTORY.cs @@ -1,44 +1,13 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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, Pack = 1)] internal struct IMAGE_LOAD_CONFIG_DIRECTORY32 { - public uint Size; public uint TimeDateStamp; public ushort MajorVersion; @@ -64,13 +33,11 @@ internal struct IMAGE_LOAD_CONFIG_DIRECTORY32 public uint GuardCFFunctionTable; public uint GuardCFFunctionCount; public uint GuardFlags; - } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct IMAGE_LOAD_CONFIG_DIRECTORY64 { - public uint Size; public uint TimeDateStamp; public ushort MajorVersion; @@ -96,7 +63,5 @@ internal struct IMAGE_LOAD_CONFIG_DIRECTORY64 public ulong GuardCFFunctionTable; public ulong GuardCFFunctionCount; public uint GuardFlags; - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_OPTIONAL_HEADER.cs b/Src/Workshell.PE/Native/IMAGE_OPTIONAL_HEADER.cs index af7fc4b..68981b9 100644 --- a/Src/Workshell.PE/Native/IMAGE_OPTIONAL_HEADER.cs +++ b/Src/Workshell.PE/Native/IMAGE_OPTIONAL_HEADER.cs @@ -1,46 +1,14 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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, Pack = 1)] internal struct IMAGE_OPTIONAL_HEADER32 { - - public ushort Magic; + //public ushort Magic; public byte MajorLinkerVersion; public byte MinorLinkerVersion; public uint SizeOfCode; @@ -89,14 +57,12 @@ internal struct IMAGE_OPTIONAL_HEADER32 public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; public IMAGE_DATA_DIRECTORY Reserved; */ - } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct IMAGE_OPTIONAL_HEADER64 { - - public ushort Magic; + //public ushort Magic; public byte MajorLinkerVersion; public byte MinorLinkerVersion; public uint SizeOfCode; @@ -144,7 +110,5 @@ internal struct IMAGE_OPTIONAL_HEADER64 public IMAGE_DATA_DIRECTORY CLRRuntimeHeader; public IMAGE_DATA_DIRECTORY Reserved; */ - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_RESOURCE_DATA_ENTRY.cs b/Src/Workshell.PE/Native/IMAGE_RESOURCE_DATA_ENTRY.cs deleted file mode 100644 index 6067bf4..0000000 --- a/Src/Workshell.PE/Native/IMAGE_RESOURCE_DATA_ENTRY.cs +++ /dev/null @@ -1,49 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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)] - internal struct IMAGE_RESOURCE_DATA_ENTRY - { - - public uint OffsetToData; - public uint Size; - public uint CodePage; - public uint Reserved; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_RESOURCE_DIRECTORY.cs b/Src/Workshell.PE/Native/IMAGE_RESOURCE_DIRECTORY.cs deleted file mode 100644 index ddfafad..0000000 --- a/Src/Workshell.PE/Native/IMAGE_RESOURCE_DIRECTORY.cs +++ /dev/null @@ -1,51 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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)] - internal struct IMAGE_RESOURCE_DIRECTORY - { - - public uint Characteristics; - public uint TimeDateStamp; - public ushort MajorVersion; - public ushort MinorVersion; - public ushort NumberOfNamedEntries; - public ushort NumberOfIdEntries; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs b/Src/Workshell.PE/Native/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs deleted file mode 100644 index 140f0dd..0000000 --- a/Src/Workshell.PE/Native/IMAGE_RESOURCE_DIRECTORY_ENTRY.cs +++ /dev/null @@ -1,47 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -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, Pack = 1)] - internal struct IMAGE_RESOURCE_DIRECTORY_ENTRY - { - - public uint Name; - public uint OffsetToData; - - } - -} diff --git a/Src/Workshell.PE/Native/IMAGE_SECTION_HEADER.cs b/Src/Workshell.PE/Native/IMAGE_SECTION_HEADER.cs index e7d4fd4..2e5a3f7 100644 --- a/Src/Workshell.PE/Native/IMAGE_SECTION_HEADER.cs +++ b/Src/Workshell.PE/Native/IMAGE_SECTION_HEADER.cs @@ -1,44 +1,13 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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.Explicit, Pack = 1)] internal struct IMAGE_SECTION_HEADER { - [FieldOffset(0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public char[] Name; @@ -69,7 +38,5 @@ internal struct IMAGE_SECTION_HEADER [FieldOffset(36)] public uint Characteristics; - } - } diff --git a/Src/Workshell.PE/Native/IMAGE_TLS_DIRECTORY.cs b/Src/Workshell.PE/Native/IMAGE_TLS_DIRECTORY.cs index d386a97..b7f22a2 100644 --- a/Src/Workshell.PE/Native/IMAGE_TLS_DIRECTORY.cs +++ b/Src/Workshell.PE/Native/IMAGE_TLS_DIRECTORY.cs @@ -1,64 +1,29 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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, Pack = 1)] internal struct IMAGE_TLS_DIRECTORY32 { - public uint StartAddress; public uint EndAddress; public uint AddressOfIndex; public uint AddressOfCallbacks; public uint SizeOfZeroFill; public uint Characteristics; - } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct IMAGE_TLS_DIRECTORY64 { - public ulong StartAddress; public ulong EndAddress; public ulong AddressOfIndex; public ulong AddressOfCallbacks; public uint SizeOfZeroFill; - public uint Characteristics; - + public uint Characteristics; } - } diff --git a/Src/Workshell.PE/Native/WIN_CERTIFICATE.cs b/Src/Workshell.PE/Native/WIN_CERTIFICATE.cs index 6aa5c99..dae4b8b 100644 --- a/Src/Workshell.PE/Native/WIN_CERTIFICATE.cs +++ b/Src/Workshell.PE/Native/WIN_CERTIFICATE.cs @@ -1,48 +1,15 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +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 + internal struct WIN_CERTIFICATE { - public uint dwLength; public ushort wRevision; public ushort wCertificateType; - } - } diff --git a/Src/Workshell.PE/OptionalHeader.cs b/Src/Workshell.PE/OptionalHeader.cs index ffca37b..11bb9f3 100644 --- a/Src/Workshell.PE/OptionalHeader.cs +++ b/Src/Workshell.PE/OptionalHeader.cs @@ -1,43 +1,15 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Annotations; +using Workshell.PE.Extensions; using Workshell.PE.Native; namespace Workshell.PE { - public enum MagicType : int { [EnumAnnotation("IMAGE_NT_OPTIONAL_HDR32_MAGIC")] @@ -107,22 +79,30 @@ public enum DllCharacteristicsType : int public abstract class OptionalHeader : ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; - public static readonly int Size32 = Utils.SizeOf(); - public static readonly int Size64 = Utils.SizeOf(); + internal OptionalHeader(PortableExecutableImage image, ulong headerOffset, uint headerSize, ulong imageBase, ushort magic) + { + _image = image; - private ExecutableImage image; - private Location location; + Location = new Location(image.GetCalculator(), headerOffset, headerOffset.ToUInt32(), imageBase + headerOffset, headerSize, headerSize); + Magic = magic; + } - internal OptionalHeader(ExecutableImage exeImage, ulong headerOffset, uint headerSize, ulong imageBase) + #region Methods + + public byte[] GetBytes() { - image = exeImage; - location = new Location(headerOffset,Convert.ToUInt32(headerOffset),imageBase + headerOffset,headerSize,headerSize); + return GetBytesAsync().GetAwaiter().GetResult(); } - #region Methods + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); - public abstract byte[] GetBytes(); + return buffer; + } public MagicType GetMagic() { @@ -161,742 +141,195 @@ public DllCharacteristicsType GetDllCharacteristics() #endregion - #region Properties + #region Static Properties - public ExecutableImage Image - { - get - { - return image; - } - } + public static int Size32 { get; } = Marshal.SizeOf(); + public static int Size64 { get; } = Marshal.SizeOf(); - public Location Location - { - get - { - return location; - } - } + #endregion + + #region Properties + + public Location Location { get; } [FieldAnnotation("Magic")] - public abstract ushort Magic - { - get; - } + public ushort Magic { get; } [FieldAnnotation("Major Linker Version")] - public abstract byte MajorLinkerVersion - { - get; - } + public abstract byte MajorLinkerVersion { get; } [FieldAnnotation("Minor Linker Version")] - public abstract byte MinorLinkerVersion - { - get; - } + public abstract byte MinorLinkerVersion { get; } [FieldAnnotation("Size of Code")] - public abstract uint SizeOfCode - { - get; - } + public abstract uint SizeOfCode { get; } [FieldAnnotation("Size of Initialized Data")] - public abstract uint SizeOfInitializedData - { - get; - } + public abstract uint SizeOfInitializedData { get; } [FieldAnnotation("Size of Uninitialized Data")] - public abstract uint SizeOfUninitializedData - { - get; - } + public abstract uint SizeOfUninitializedData { get; } [FieldAnnotation("Address of Entry Point")] - public abstract uint AddressOfEntryPoint - { - get; - } + public abstract uint AddressOfEntryPoint { get; } [FieldAnnotation("Base of Code")] - public abstract uint BaseOfCode - { - get; - } + public abstract uint BaseOfCode { get; } [FieldAnnotation("Base of Data")] - public abstract uint BaseOfData - { - get; - } + public abstract uint BaseOfData { get; } [FieldAnnotation("Image Base")] - public abstract ulong ImageBase - { - get; - } + public abstract ulong ImageBase { get; } [FieldAnnotation("Section Alignment")] - public abstract uint SectionAlignment - { - get; - } + public abstract uint SectionAlignment { get; } [FieldAnnotation("File Alignment")] - public abstract uint FileAlignment - { - get; - } + public abstract uint FileAlignment { get; } [FieldAnnotation("Major Operating System Version")] - public abstract ushort MajorOperatingSystemVersion - { - get; - } + public abstract ushort MajorOperatingSystemVersion { get; } [FieldAnnotation("Minor Operating System Version")] - public abstract ushort MinorOperatingSystemVersion - { - get; - } + public abstract ushort MinorOperatingSystemVersion { get; } [FieldAnnotation("Major Image Version")] - public abstract ushort MajorImageVersion - { - get; - } + public abstract ushort MajorImageVersion { get; } [FieldAnnotation("Minor Image Version")] - public abstract ushort MinorImageVersion - { - get; - } + public abstract ushort MinorImageVersion { get; } [FieldAnnotation("Major Sub-System Version")] - public abstract ushort MajorSubsystemVersion - { - get; - } + public abstract ushort MajorSubsystemVersion { get; } [FieldAnnotation("Minor Sub-System Version")] - public abstract ushort MinorSubsystemVersion - { - get; - } + public abstract ushort MinorSubsystemVersion { get; } [FieldAnnotation("Win32 Version Value")] - public abstract uint Win32VersionValue - { - get; - } + public abstract uint Win32VersionValue { get; } [FieldAnnotation("Size of Image")] - public abstract uint SizeOfImage - { - get; - } + public abstract uint SizeOfImage { get; } [FieldAnnotation("Size of Headers")] - public abstract uint SizeOfHeaders - { - get; - } + public abstract uint SizeOfHeaders { get; } [FieldAnnotation("Checksum")] - public abstract uint CheckSum - { - get; - } + public abstract uint CheckSum { get; } [FieldAnnotation("Sub-System",Flags = true,FlagType = typeof(SubSystemType))] - public abstract ushort Subsystem - { - get; - } + public abstract ushort Subsystem { get; } [FieldAnnotation("DLL Characteristics",Flags = true,FlagType = typeof(DllCharacteristicsType))] - public abstract ushort DllCharacteristics - { - get; - } + public abstract ushort DllCharacteristics { get; } [FieldAnnotation("Size of Stack Reserve")] - public abstract ulong SizeOfStackReserve - { - get; - } + public abstract ulong SizeOfStackReserve { get; } [FieldAnnotation("Size of Stack Commit")] - public abstract ulong SizeOfStackCommit - { - get; - } + public abstract ulong SizeOfStackCommit { get; } [FieldAnnotation("Size of Heap Reserve")] - public abstract ulong SizeOfHeapReserve - { - get; - } + public abstract ulong SizeOfHeapReserve { get; } [FieldAnnotation("Size of Heap Commit")] - public abstract ulong SizeOfHeapCommit - { - get; - } + public abstract ulong SizeOfHeapCommit { get; } [FieldAnnotation("Loader Flags")] - public abstract uint LoaderFlags - { - get; - } + public abstract uint LoaderFlags { get; } [FieldAnnotation("Number of RVA and Sizes")] - public abstract uint NumberOfRvaAndSizes - { - get; - } + public abstract uint NumberOfRvaAndSizes { get; } #endregion - } public sealed class OptionalHeader32 : OptionalHeader { + private readonly IMAGE_OPTIONAL_HEADER32 _header; - private IMAGE_OPTIONAL_HEADER32 header; - - internal OptionalHeader32(ExecutableImage exeReader, IMAGE_OPTIONAL_HEADER32 optHeader, ulong headerOffset, ulong imageBase) : base(exeReader,headerOffset,Convert.ToUInt32(OptionalHeader.Size32),imageBase) + internal OptionalHeader32(PortableExecutableImage image, IMAGE_OPTIONAL_HEADER32 optHeader, ulong headerOffset, ulong imageBase, ushort magic) : base(image, headerOffset, OptionalHeader.Size32.ToUInt32(), imageBase,magic) { - header = optHeader; + _header = optHeader; } - #region Methods - - public override byte[] GetBytes() - { - Stream stream = Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; - } - - #endregion - #region Properties - public override ushort Magic - { - get - { - return header.Magic; - } - } - - public override byte MajorLinkerVersion - { - get - { - return header.MajorLinkerVersion; - } - } - - public override byte MinorLinkerVersion - { - get - { - return header.MinorLinkerVersion; - } - } - - public override uint SizeOfCode - { - get - { - return header.SizeOfCode; - } - } - - public override uint SizeOfInitializedData - { - get - { - return header.SizeOfInitializedData; - } - } - - public override uint SizeOfUninitializedData - { - get - { - return header.SizeOfUninitializedData; - } - } - - public override uint AddressOfEntryPoint - { - get - { - return header.AddressOfEntryPoint; - } - } - - public override uint BaseOfCode - { - get - { - return header.BaseOfCode; - } - } - - public override uint BaseOfData - { - get - { - return header.BaseOfData; - } - } - - public override ulong ImageBase - { - get - { - return header.ImageBase; - } - } - - public override uint SectionAlignment - { - get - { - return header.SectionAlignment; - } - } - - public override uint FileAlignment - { - get - { - return header.FileAlignment; - } - } - - public override ushort MajorOperatingSystemVersion - { - get - { - return header.MajorOperatingSystemVersion; - } - } - - public override ushort MinorOperatingSystemVersion - { - get - { - return header.MinorOperatingSystemVersion; - } - } - - public override ushort MajorImageVersion - { - get - { - return header.MajorImageVersion; - } - } - - public override ushort MinorImageVersion - { - get - { - return header.MinorImageVersion; - } - } - - public override ushort MajorSubsystemVersion - { - get - { - return header.MajorSubsystemVersion; - } - } - - public override ushort MinorSubsystemVersion - { - get - { - return header.MinorSubsystemVersion; - } - } - - public override uint Win32VersionValue - { - get - { - return header.Win32VersionValue; - } - } - - public override uint SizeOfImage - { - get - { - return header.SizeOfImage; - } - } - - public override uint SizeOfHeaders - { - get - { - return header.SizeOfHeaders; - } - } - - public override uint CheckSum - { - get - { - return header.CheckSum; - } - } - - public override ushort Subsystem - { - get - { - return header.Subsystem; - } - } - - public override ushort DllCharacteristics - { - get - { - return header.DllCharacteristics; - } - } - - public override ulong SizeOfStackReserve - { - get - { - return header.SizeOfStackReserve; - } - } - - public override ulong SizeOfStackCommit - { - get - { - return header.SizeOfStackCommit; - } - } - - public override ulong SizeOfHeapReserve - { - get - { - return header.SizeOfHeapReserve; - } - } - - public override ulong SizeOfHeapCommit - { - get - { - return header.SizeOfHeapCommit; - } - } - - public override uint LoaderFlags - { - get - { - return header.LoaderFlags; - } - } - - public override uint NumberOfRvaAndSizes - { - get - { - return header.NumberOfRvaAndSizes; - } - } + public override byte MajorLinkerVersion => _header.MajorLinkerVersion; + public override byte MinorLinkerVersion => _header.MinorLinkerVersion; + public override uint SizeOfCode => _header.SizeOfCode; + public override uint SizeOfInitializedData => _header.SizeOfInitializedData; + public override uint SizeOfUninitializedData => _header.SizeOfUninitializedData; + public override uint AddressOfEntryPoint => _header.AddressOfEntryPoint; + public override uint BaseOfCode => _header.BaseOfCode; + public override uint BaseOfData => _header.BaseOfData; + public override ulong ImageBase => _header.ImageBase; + public override uint SectionAlignment => _header.SectionAlignment; + public override uint FileAlignment => _header.FileAlignment; + public override ushort MajorOperatingSystemVersion => _header.MajorOperatingSystemVersion; + public override ushort MinorOperatingSystemVersion => _header.MinorOperatingSystemVersion; + public override ushort MajorImageVersion => _header.MajorImageVersion; + public override ushort MinorImageVersion => _header.MinorImageVersion; + public override ushort MajorSubsystemVersion => _header.MajorSubsystemVersion; + public override ushort MinorSubsystemVersion => _header.MinorSubsystemVersion; + public override uint Win32VersionValue => _header.Win32VersionValue; + public override uint SizeOfImage => _header.SizeOfImage; + public override uint SizeOfHeaders => _header.SizeOfHeaders; + public override uint CheckSum => _header.CheckSum; + public override ushort Subsystem => _header.Subsystem; + public override ushort DllCharacteristics => _header.DllCharacteristics; + public override ulong SizeOfStackReserve => _header.SizeOfStackReserve; + public override ulong SizeOfStackCommit => _header.SizeOfStackCommit; + public override ulong SizeOfHeapReserve => _header.SizeOfHeapReserve; + public override ulong SizeOfHeapCommit => _header.SizeOfHeapCommit; + public override uint LoaderFlags => _header.LoaderFlags; + public override uint NumberOfRvaAndSizes => _header.NumberOfRvaAndSizes; #endregion - } public sealed class OptionalHeader64 : OptionalHeader { + private readonly IMAGE_OPTIONAL_HEADER64 _header; - private IMAGE_OPTIONAL_HEADER64 header; - - internal OptionalHeader64(ExecutableImage exeImage, IMAGE_OPTIONAL_HEADER64 optHeader, ulong headerOffset, ulong imageBase) : base(exeImage,headerOffset,Convert.ToUInt32(OptionalHeader.Size64),imageBase) - { - header = optHeader; - } - - #region Methods - - public override byte[] GetBytes() + internal OptionalHeader64(PortableExecutableImage image, IMAGE_OPTIONAL_HEADER64 optHeader, ulong headerOffset, ulong imageBase, ushort magic) : base(image, headerOffset, OptionalHeader.Size64.ToUInt32(), imageBase, magic) { - Stream stream = Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,Location); - - return buffer; + _header = optHeader; } - #endregion - #region Properties - public override ushort Magic - { - get - { - return header.Magic; - } - } - - public override byte MajorLinkerVersion - { - get - { - return header.MajorLinkerVersion; - } - } - - public override byte MinorLinkerVersion - { - get - { - return header.MinorLinkerVersion; - } - } - - public override uint SizeOfCode - { - get - { - return header.SizeOfCode; - } - } - - public override uint SizeOfInitializedData - { - get - { - return header.SizeOfInitializedData; - } - } - - public override uint SizeOfUninitializedData - { - get - { - return header.SizeOfUninitializedData; - } - } - - public override uint AddressOfEntryPoint - { - get - { - return header.AddressOfEntryPoint; - } - } - - public override uint BaseOfCode - { - get - { - return header.BaseOfCode; - } - } - - public override uint BaseOfData - { - get - { - return 0; - } - } - - public override ulong ImageBase - { - get - { - return header.ImageBase; - } - } - - public override uint SectionAlignment - { - get - { - return header.SectionAlignment; - } - } - - public override uint FileAlignment - { - get - { - return header.FileAlignment; - } - } - - public override ushort MajorOperatingSystemVersion - { - get - { - return header.MajorOperatingSystemVersion; - } - } - - public override ushort MinorOperatingSystemVersion - { - get - { - return header.MinorOperatingSystemVersion; - } - } - - public override ushort MajorImageVersion - { - get - { - return header.MajorImageVersion; - } - } - - public override ushort MinorImageVersion - { - get - { - return header.MinorImageVersion; - } - } - - public override ushort MajorSubsystemVersion - { - get - { - return header.MajorSubsystemVersion; - } - } - - public override ushort MinorSubsystemVersion - { - get - { - return header.MinorSubsystemVersion; - } - } - - public override uint Win32VersionValue - { - get - { - return header.Win32VersionValue; - } - } - - public override uint SizeOfImage - { - get - { - return header.SizeOfImage; - } - } - - public override uint SizeOfHeaders - { - get - { - return header.SizeOfHeaders; - } - } - - public override uint CheckSum - { - get - { - return header.CheckSum; - } - } - - public override ushort Subsystem - { - get - { - return header.Subsystem; - } - } - - public override ushort DllCharacteristics - { - get - { - return header.DllCharacteristics; - } - } - - public override ulong SizeOfStackReserve - { - get - { - return header.SizeOfStackReserve; - } - } - - public override ulong SizeOfStackCommit - { - get - { - return header.SizeOfStackCommit; - } - } - - public override ulong SizeOfHeapReserve - { - get - { - return header.SizeOfHeapReserve; - } - } - - public override ulong SizeOfHeapCommit - { - get - { - return header.SizeOfHeapCommit; - } - } - - public override uint LoaderFlags - { - get - { - return header.LoaderFlags; - } - } - - public override uint NumberOfRvaAndSizes - { - get - { - return header.NumberOfRvaAndSizes; - } - } - - #endregion - + public override byte MajorLinkerVersion => _header.MajorLinkerVersion; + public override byte MinorLinkerVersion => _header.MinorLinkerVersion; + public override uint SizeOfCode => _header.SizeOfCode; + public override uint SizeOfInitializedData => _header.SizeOfInitializedData; + public override uint SizeOfUninitializedData => _header.SizeOfUninitializedData; + public override uint AddressOfEntryPoint => _header.AddressOfEntryPoint; + public override uint BaseOfCode => _header.BaseOfCode; + public override uint BaseOfData => 0; + public override ulong ImageBase => _header.ImageBase; + public override uint SectionAlignment => _header.SectionAlignment; + public override uint FileAlignment => _header.FileAlignment; + public override ushort MajorOperatingSystemVersion => _header.MajorOperatingSystemVersion; + public override ushort MinorOperatingSystemVersion => _header.MinorOperatingSystemVersion; + public override ushort MajorImageVersion => _header.MajorImageVersion; + public override ushort MinorImageVersion => _header.MinorImageVersion; + public override ushort MajorSubsystemVersion => _header.MajorSubsystemVersion; + public override ushort MinorSubsystemVersion => _header.MinorSubsystemVersion; + public override uint Win32VersionValue => _header.Win32VersionValue; + public override uint SizeOfImage => _header.SizeOfImage; + public override uint SizeOfHeaders => _header.SizeOfHeaders; + public override uint CheckSum => _header.CheckSum; + public override ushort Subsystem => _header.Subsystem; + public override ushort DllCharacteristics => _header.DllCharacteristics; + public override ulong SizeOfStackReserve => _header.SizeOfStackReserve; + public override ulong SizeOfStackCommit => _header.SizeOfStackCommit; + public override ulong SizeOfHeapReserve => _header.SizeOfHeapReserve; + public override ulong SizeOfHeapCommit => _header.SizeOfHeapCommit; + public override uint LoaderFlags => _header.LoaderFlags; + public override uint NumberOfRvaAndSizes => _header.NumberOfRvaAndSizes; + + #endregion } - } diff --git a/Src/Workshell.PE/Properties/AssemblyInfo.cs b/Src/Workshell.PE/Properties/AssemblyInfo.cs deleted file mode 100644 index ffeba9a..0000000 --- a/Src/Workshell.PE/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,68 +0,0 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Workshell.PE")] -[assembly: AssemblyDescription("A .NET class library for reading the PE executable format")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Workshell Ltd")] -[assembly: AssemblyProduct(".NET PE Class Library")] -[assembly: AssemblyCopyright("Copyright ©2016 Workshell Ltd")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5ef8a44d-2548-4cda-b507-bc3a7907ee1e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.7.*")] -[assembly: AssemblyInformationalVersion("1.7.0")] - -#if !SIGNED -[assembly: InternalsVisibleTo("peres")] -#else -[assembly: InternalsVisibleTo("peres, PublicKey=0024000004800000940000000602000000240000525341310004000001000100259ed23116da6a496f873182c31284a428d040b37885524e9b53049cd99d5cc84feb00dbe77278afda8ebc9def14111b20b561f8d958e3f4aea2d492fed946245c528b16cad6ee785995ccfd7e6b7b34fe4be452a651069b2c0bbcf668bfb1dd9b99a7f30ab10d289525d61e82fd45e1ebcc11fc3d286e6096a1ee7edeee6091")] -#endif \ No newline at end of file diff --git a/Src/Workshell.PE/Section.cs b/Src/Workshell.PE/Section.cs index 130efc7..3d792fe 100644 --- a/Src/Workshell.PE/Section.cs +++ b/Src/Workshell.PE/Section.cs @@ -1,68 +1,44 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; using System.Text; using System.Threading.Tasks; +using Workshell.PE.Extensions; namespace Workshell.PE { - public sealed class Section : ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; - private Sections _sections; - private SectionTableEntry _table_entry; - private Location _location; - - internal Section(Sections sections, SectionTableEntry tableEntry) + internal Section(PortableExecutableImage image, Sections sections, SectionTableEntry tableEntry) { - ulong image_base = tableEntry.Table.Image.NTHeaders.OptionalHeader.ImageBase; + _image = image; - _sections = sections; - _table_entry = tableEntry; - _location = new Location(tableEntry.PointerToRawData,tableEntry.VirtualAddress,image_base + tableEntry.VirtualAddress,tableEntry.SizeOfRawData,tableEntry.VirtualSizeOrPhysicalAddress); + var imageBase = _image.NTHeaders.OptionalHeader.ImageBase; + + Sections = sections; + TableEntry = tableEntry; + Location = new Location(image.GetCalculator(), tableEntry.PointerToRawData, tableEntry.VirtualAddress, imageBase + tableEntry.VirtualAddress, tableEntry.SizeOfRawData, tableEntry.VirtualSizeOrPhysicalAddress); } #region Methods public override string ToString() { - return _table_entry.Name; + return TableEntry.Name; } public byte[] GetBytes() { - Stream stream = _table_entry.Table.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,_location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } @@ -71,61 +47,34 @@ public byte[] GetBytes() #region Properties - public Sections Sections - { - get - { - return _sections; - } - } - - public SectionTableEntry TableEntry - { - get - { - return _table_entry; - } - } - - public Location Location - { - get - { - return _location; - } - } - - public string Name - { - get - { - return _table_entry.Name; - } - } + public Sections Sections { get; } + public SectionTableEntry TableEntry { get; } + public Location Location { get; } + public string Name => TableEntry.Name; #endregion - } public sealed class Sections : IEnumerable
{ + private readonly PortableExecutableImage _image; + private readonly Dictionary _sections; - private SectionTable table; - private Dictionary sections; - - internal Sections(SectionTable sectionTable) + internal Sections(PortableExecutableImage image, SectionTable sectionTable) { - table = sectionTable; - sections = new Dictionary(); + _image = image; + _sections = new Dictionary(sectionTable.Count); + + Table = sectionTable; } #region Methods public IEnumerator
GetEnumerator() { - for(var i = 0; i < table.Count; i++) + foreach (var entry in Table) { - Section section = GetSection(table[i]); + var section = GetSection(entry); yield return section; } @@ -138,41 +87,28 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() private Section GetSection(SectionTableEntry tableEntry) { - if (!sections.ContainsKey(tableEntry)) + if (!_sections.ContainsKey(tableEntry)) { - Section section = new Section(this, tableEntry); + var section = new Section(_image, this, tableEntry); - sections[tableEntry] = section; + _sections[tableEntry] = section; } - return sections[tableEntry]; + return _sections[tableEntry]; } #endregion #region Properties - public SectionTable Table - { - get - { - return table; - } - } - - public int Count - { - get - { - return table.Count; - } - } + public SectionTable Table { get; } + public int Count => Table.Count; public Section this[int index] { get { - SectionTableEntry entry = table[index]; + var entry = Table[index]; return this[entry]; } @@ -182,22 +118,14 @@ public Section this[string sectionName] { get { - SectionTableEntry entry = table.FirstOrDefault(e => String.Compare(sectionName,e.Name,StringComparison.OrdinalIgnoreCase) == 0); + var entry = Table.FirstOrDefault(e => String.Compare(sectionName,e.Name,StringComparison.OrdinalIgnoreCase) == 0); return this[entry]; } } - public Section this[SectionTableEntry tableEntry] - { - get - { - return GetSection(tableEntry); - } - } + public Section this[SectionTableEntry tableEntry] => GetSection(tableEntry); #endregion - } - } diff --git a/Src/Workshell.PE/SectionTable.cs b/Src/Workshell.PE/SectionTable.cs index e267f0f..a757490 100644 --- a/Src/Workshell.PE/SectionTable.cs +++ b/Src/Workshell.PE/SectionTable.cs @@ -1,44 +1,16 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; - using Workshell.PE.Annotations; using Workshell.PE.Extensions; using Workshell.PE.Native; namespace Workshell.PE { - [Flags] public enum SectionCharacteristicsType : uint { @@ -128,36 +100,28 @@ public enum SectionCharacteristicsType : uint MemoryWrite = 0x80000000 } - public sealed class SectionTableEntry : IEquatable, ISupportsLocation + public sealed class SectionTableEntry : IEquatable, ISupportsLocation, ISupportsBytes { + private static readonly uint _headerSize = Marshal.SizeOf().ToUInt32(); - private static readonly uint size = Utils.SizeOf().ToUInt32(); + private readonly PortableExecutableImage _image; + private readonly IMAGE_SECTION_HEADER _header; - private SectionTable table; - private IMAGE_SECTION_HEADER header; - private Location location; - private string name; - - internal SectionTableEntry(SectionTable sectionTable, IMAGE_SECTION_HEADER entryHeader, ulong entryOffset, ulong imageBase) + internal SectionTableEntry(PortableExecutableImage image, SectionTable sectionTable, IMAGE_SECTION_HEADER entryHeader, ulong entryOffset, ulong imageBase) { - table = sectionTable; - header = entryHeader; - location = new Location(entryOffset,Convert.ToUInt32(entryOffset),imageBase + entryOffset,size,size); - name = GetName(); + _image = image; + _header = entryHeader; + + Table = sectionTable; + Location = new Location(image.GetCalculator(), entryOffset, entryOffset.ToUInt32(), imageBase + entryOffset, _headerSize, _headerSize); + Name = GetName(); } #region Methods public override string ToString() { - if (!String.IsNullOrWhiteSpace(name)) - { - return name; - } - else - { - return base.ToString(); - } + return !string.IsNullOrWhiteSpace(Name) ? Name : base.ToString(); } public override bool Equals(object other) @@ -211,46 +175,51 @@ public bool Equals(SectionTableEntry other) public override int GetHashCode() { - int prime = 397; - int result = 0; - - result = (result * prime) ^ location.GetHashCode(); - result = (result * prime) ^ name.GetHashCode(); - result = (result * prime) ^ header.VirtualSize.GetHashCode(); - result = (result * prime) ^ header.SizeOfRawData.GetHashCode(); - result = (result * prime) ^ header.PointerToRawData.GetHashCode(); - result = (result * prime) ^ header.PointerToRelocations.GetHashCode(); - result = (result * prime) ^ header.PointerToLineNumbers.GetHashCode(); - result = (result * prime) ^ header.NumberOfRelocations.GetHashCode(); - result = (result * prime) ^ header.NumberOfLineNumbers.GetHashCode(); - result = (result * prime) ^ header.Characteristics.GetHashCode(); + var prime = 397; + var result = 0; + + result = (result * prime) ^ Location.GetHashCode(); + result = (result * prime) ^ Name.GetHashCode(); + result = (result * prime) ^ _header.VirtualSize.GetHashCode(); + result = (result * prime) ^ _header.SizeOfRawData.GetHashCode(); + result = (result * prime) ^ _header.PointerToRawData.GetHashCode(); + result = (result * prime) ^ _header.PointerToRelocations.GetHashCode(); + result = (result * prime) ^ _header.PointerToLineNumbers.GetHashCode(); + result = (result * prime) ^ _header.NumberOfRelocations.GetHashCode(); + result = (result * prime) ^ _header.NumberOfLineNumbers.GetHashCode(); + result = (result * prime) ^ _header.Characteristics.GetHashCode(); return result; } public byte[] GetBytes() { - Stream stream = table.Image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream, location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } public SectionCharacteristicsType GetCharacteristics() { - return (SectionCharacteristicsType)header.Characteristics; + return (SectionCharacteristicsType)_header.Characteristics; } private string GetName() { - StringBuilder builder = new StringBuilder(16); + var builder = new StringBuilder(16); - for(var i = 0; i < header.Name.Length; i++) + foreach (var c in _header.Name) { - if (header.Name[i] == '\0') + if (c == '\0') break; - builder.Append(header.Name[i]); + builder.Append(c); } return builder.ToString(); @@ -260,129 +229,47 @@ private string GetName() #region Properties - public SectionTable Table - { - get - { - return table; - } - } - - public Location Location - { - get - { - return location; - } - } - - public string Name - { - get - { - return name; - } - } - - public uint VirtualSizeOrPhysicalAddress - { - get - { - return header.VirtualSize; - } - } - - public uint VirtualAddress - { - get - { - return header.VirtualAddress; - } - } - - public uint SizeOfRawData - { - get - { - return header.SizeOfRawData; - } - } - - public uint PointerToRawData - { - get - { - return header.PointerToRawData; - } - } - - public uint PointerToRelocations - { - get - { - return header.PointerToRelocations; - } - } - - public uint PointerToLineNumbers - { - get - { - return header.PointerToLineNumbers; - } - } + public SectionTable Table { get; } - public ushort NumberOfRelocations - { - get - { - return header.NumberOfRelocations; - } - } + public Location Location { get; } - public ushort NumberOfLineNumbers - { - get - { - return header.NumberOfLineNumbers; - } - } + public string Name { get; } - public uint Characteristics - { - get - { - return header.Characteristics; - } - } + public uint VirtualSizeOrPhysicalAddress => _header.VirtualSize; + public uint VirtualAddress => _header.VirtualAddress; + public uint SizeOfRawData => _header.SizeOfRawData; + public uint PointerToRawData => _header.PointerToRawData; + public uint PointerToRelocations => _header.PointerToRelocations; + public uint PointerToLineNumbers => _header.PointerToLineNumbers; + public ushort NumberOfRelocations => _header.NumberOfRelocations; + public ushort NumberOfLineNumbers => _header.NumberOfLineNumbers; + public uint Characteristics => _header.Characteristics; #endregion - } - public sealed class SectionTable : IEnumerable, ISupportsLocation + public sealed class SectionTable : IEnumerable, ISupportsLocation, ISupportsBytes { + private readonly PortableExecutableImage _image; + private readonly SectionTableEntry[] _table; - private ExecutableImage image; - private Location location; - private SectionTableEntry[] table; - - internal SectionTable(ExecutableImage exeImage, IMAGE_SECTION_HEADER[] sectionHeaders, ulong tableOffset, ulong imageBase) + internal SectionTable(PortableExecutableImage image, IMAGE_SECTION_HEADER[] sectionHeaders, ulong tableOffset, ulong imageBase) { - uint size = (Utils.SizeOf() * sectionHeaders.Length).ToUInt32(); + _image = image; + _table = new SectionTableEntry[sectionHeaders.Length]; + + var size = (Marshal.SizeOf() * sectionHeaders.Length).ToUInt32(); - image = exeImage; - location = new Location(tableOffset,Convert.ToUInt32(tableOffset),imageBase + tableOffset,size,size); - table = new SectionTableEntry[sectionHeaders.Length]; + Location = new Location(image.GetCalculator(), tableOffset, tableOffset.ToUInt32(), imageBase + tableOffset, size, size); - ulong offset = tableOffset; + var offset = tableOffset; for(var i = 0; i < sectionHeaders.Length; i++) { - SectionTableEntry entry = new SectionTableEntry(this, sectionHeaders[i], offset, imageBase); + var entry = new SectionTableEntry(_image,this,sectionHeaders[i],offset,imageBase); - table[i] = entry; - offset += Utils.SizeOf().ToUInt32(); + _table[i] = entry; + offset += Marshal.SizeOf().ToUInt32(); } } @@ -390,17 +277,22 @@ internal SectionTable(ExecutableImage exeImage, IMAGE_SECTION_HEADER[] sectionHe public byte[] GetBytes() { - Stream stream = image.GetStream(); - byte[] buffer = Utils.ReadBytes(stream,location); + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); return buffer; } public IEnumerator GetEnumerator() { - for(var i = 0; i < table.Length; i++) + foreach (var entry in _table) { - yield return table[i]; + yield return entry; } } @@ -413,48 +305,18 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() #region Properties - public ExecutableImage Image - { - get - { - return image; - } - } - - public Location Location - { - get - { - return location; - } - } - - public int Count - { - get - { - return table.Length; - } - } - - public SectionTableEntry this[int index] - { - get - { - return table[index]; - } - } + public Location Location { get; } + public int Count => _table.Length; + public SectionTableEntry this[int index] => _table[index]; public SectionTableEntry this[string name] { get { - return table.FirstOrDefault(entry => String.Compare(name,entry.Name,StringComparison.OrdinalIgnoreCase) == 0); + return _table.FirstOrDefault(entry => string.Compare(name,entry.Name,StringComparison.OrdinalIgnoreCase) == 0); } } #endregion - } - } diff --git a/Src/Workshell.PE/Supports.cs b/Src/Workshell.PE/Supports.cs index fcfb054..2a84d01 100644 --- a/Src/Workshell.PE/Supports.cs +++ b/Src/Workshell.PE/Supports.cs @@ -1,62 +1,26 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Text; using System.Threading.Tasks; namespace Workshell.PE { - public interface ISupportsLocation { - #region Properties - Location Location - { - get; - } + Location Location { get; } #endregion - } public interface ISupportsBytes { - #region Methods byte[] GetBytes(); + Task GetBytesAsync(); #endregion - } - } diff --git a/Src/Workshell.PE/Utils.cs b/Src/Workshell.PE/Utils.cs index dc91f73..187d992 100644 --- a/Src/Workshell.PE/Utils.cs +++ b/Src/Workshell.PE/Utils.cs @@ -1,60 +1,22 @@ -#region License -// Copyright(c) 2016, Workshell Ltd -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of Workshell Ltd nor the names of its contributors -// may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED.IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#endregion - -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Text; -using System.Threading.Tasks; using Workshell.PE.Extensions; namespace Workshell.PE { - internal static class Utils { - - private static readonly DateTime UNIX_EPOCH = new DateTime(1970,1,1,0,0,0,DateTimeKind.Utc); + private static readonly DateTime UnixEpoch = new DateTime(1970,1,1,0,0,0,DateTimeKind.Utc); #region Methods - public static int SizeOf() where T : struct - { - int result = Marshal.SizeOf(typeof(T)); - - return result; - } - public static T Read(byte[] bytes) where T : struct { - IntPtr ptr = Marshal.AllocHGlobal(bytes.Length); + var ptr = Marshal.AllocHGlobal(bytes.Length); try { @@ -70,276 +32,93 @@ public static T Read(byte[] bytes) where T : struct } } - public static T Read(Stream stream) where T : struct - { - int size = SizeOf(); - - return Read(stream,size); - } - - public static T Read(Stream stream, int size) where T : struct - { - return Read(stream,size,false); - } - - public static T Read(Stream stream, int size, bool allowSmaller) where T : struct - { - byte[] buffer = new byte[size]; - int num_read = stream.Read(buffer,0,buffer.Length); - - if (!allowSmaller && num_read < size) - throw new IOException("Could not read all of structure from stream."); - - if (num_read < size) - return default(T); - - return Read(buffer); - } - public static byte ReadByte(byte[] bytes, int index) { return bytes[index]; } - public static byte ReadByte(Stream stream) - { - byte[] buffer = new byte[1]; - - stream.Read(buffer, 0, buffer.Length); - - return ReadByte(buffer, 0); - } - public static short ReadInt16(byte[] bytes) { return BitConverter.ToInt16(bytes,0); } - public static short ReadInt16(Stream stream) - { - byte[] buffer = new byte[sizeof(short)]; - - stream.Read(buffer,0,buffer.Length); - - return ReadInt16(buffer); - } - public static int ReadInt32(byte[] bytes) { return BitConverter.ToInt32(bytes,0); } - public static int ReadInt32(Stream stream) - { - byte[] buffer = new byte[sizeof(int)]; - - stream.Read(buffer,0,buffer.Length); - - return ReadInt32(buffer); - } - public static long ReadInt64(byte[] bytes) { return BitConverter.ToInt64(bytes,0); } - public static long ReadInt64(Stream stream) - { - byte[] buffer = new byte[sizeof(long)]; - - stream.Read(buffer,0,buffer.Length); - - return ReadInt64(buffer); - } - public static ushort ReadUInt16(byte[] bytes) { return BitConverter.ToUInt16(bytes,0); } - public static ushort ReadUInt16(Stream stream) - { - byte[] buffer = new byte[sizeof(ushort)]; - - stream.Read(buffer,0,buffer.Length); - - return ReadUInt16(buffer); - } - public static uint ReadUInt32(byte[] bytes) { return BitConverter.ToUInt32(bytes,0); } - public static uint ReadUInt32(Stream stream) - { - byte[] buffer = new byte[sizeof(uint)]; - - stream.Read(buffer,0,buffer.Length); - - return ReadUInt32(buffer); - } - public static ulong ReadUInt64(byte[] bytes) { return BitConverter.ToUInt64(bytes,0); } - public static ulong ReadUInt64(Stream stream) - { - byte[] buffer = new byte[sizeof(ulong)]; - - stream.Read(buffer,0,buffer.Length); - - return ReadUInt64(buffer); - } - - public static string ReadString(Stream stream) - { - StringBuilder builder = new StringBuilder(256); - - while (true) - { - int b = stream.ReadByte(); - - if (b <= 0) - break; - - builder.Append((char)b); - } - - return builder.ToString(); - } - - public static string ReadString(Stream stream, long size) - { - byte[] buffer = new byte[size]; - - stream.Read(buffer,0,buffer.Length); - - StringBuilder builder = new StringBuilder(256); - - foreach(byte b in buffer) - { - if (b == 0) - break; - - builder.Append((char)b); - } - - return builder.ToString(); - } - - public static string ReadUnicodeString(Stream stream) - { - StringBuilder builder = new StringBuilder(); - - while (true) - { - ushort value = Utils.ReadUInt16(stream); - - if (value == 0) - break; - - builder.Append((char)value); - } - - return builder.ToString(); - } - - public static string ReadUnicodeString(Stream stream, int charCount) - { - StringBuilder builder = new StringBuilder(); - - for(var i = 0; i < charCount; i++) - { - ushort value = Utils.ReadUInt16(stream); - - if (value == 0) - break; - - builder.Append((char)value); - } - - return builder.ToString(); - } - - public static byte[] ReadBytes(Stream stream, long size) - { - byte[] buffer = new byte[size]; - - stream.Read(buffer, 0, buffer.Length); - - return buffer; - } - - public static byte[] ReadBytes(Stream stream, long offset, long size) - { - byte[] buffer = new byte[size]; - - stream.Seek(offset, SeekOrigin.Begin); - stream.Read(buffer, 0, buffer.Length); - - return buffer; - } - - public static byte[] ReadBytes(Stream stream, Location location) - { - return ReadBytes(stream, location.FileOffset.ToInt64(), location.FileSize.ToInt64()); - } - public static void Write(sbyte value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); stream.WriteByte((byte)value); } public static void Write(byte value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); stream.WriteByte(value); } public static void Write(short value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); Write(buffer, stream); } public static void Write(ushort value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); Write(buffer, stream); } public static void Write(int value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); Write(buffer, stream); } public static void Write(uint value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); Write(buffer, stream); } public static void Write(long value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); Write(buffer, stream); } public static void Write(ulong value, Stream stream) { - byte[] buffer = BitConverter.GetBytes(value); + var buffer = BitConverter.GetBytes(value); Write(buffer, stream); } @@ -351,7 +130,7 @@ public static void Write(byte[] bytes, Stream stream) public static void Write(T structure, byte[] buffer, int startIndex, int count) where T : struct { - IntPtr ptr = Marshal.AllocHGlobal(count); + var ptr = Marshal.AllocHGlobal(count); try { @@ -366,31 +145,22 @@ public static void Write(T structure, byte[] buffer, int startIndex, int coun public static void Write(T structure, Stream stream) where T : struct { - int size = SizeOf(); + var size = Marshal.SizeOf(); Write(structure,stream,size); } public static void Write(T structure, Stream stream, int size) where T : struct { - byte[] buffer = new byte[size]; + var buffer = new byte[size]; Write(structure,buffer,0,buffer.Length); stream.Write(buffer,0,buffer.Length); } - public static int SkipBytes(Stream stream, int count) - { - byte[] buffer = new byte[count]; - - return stream.Read(buffer,0,buffer.Length); - } - public static DateTime ConvertTimeDateStamp(uint timeDateStamp) { - DateTime result = UNIX_EPOCH.AddSeconds(timeDateStamp); - - result += TimeZone.CurrentTimeZone.GetUtcOffset(result); + var result = UnixEpoch.AddSeconds(timeDateStamp).Add(DateTimeOffset.Now.Offset); return result; } @@ -418,33 +188,33 @@ public static bool IsNumeric(object value) public static string IntToHex(object value) { - string result = String.Empty; + var result = String.Empty; switch (Type.GetTypeCode(value.GetType())) { case TypeCode.Byte: - result = "0x" + ((byte)(value)).ToString("X2"); + result = "0x" + ((byte)value).ToString("X2"); break; case TypeCode.SByte: - result = "0x" + ((sbyte)(value)).ToString("X2"); + result = "0x" + ((sbyte)value).ToString("X2"); break; case TypeCode.UInt16: - result = "0x" + ((ushort)(value)).ToString("X4"); + result = "0x" + ((ushort)value).ToString("X4"); break; case TypeCode.Int16: - result = "0x" + ((short)(value)).ToString("X4"); + result = "0x" + ((short)value).ToString("X4"); break; case TypeCode.UInt32: - result = "0x" + ((uint)(value)).ToString("X8"); + result = "0x" + ((uint)value).ToString("X8"); break; case TypeCode.Int32: - result = "0x" + ((int)(value)).ToString("X8"); + result = "0x" + ((int)value).ToString("X8"); break; case TypeCode.UInt64: - result = "0x" + ((ulong)(value)).ToString("X16"); + result = "0x" + ((ulong)value).ToString("X16"); break; case TypeCode.Int64: - result = "0x" + ((long)(value)).ToString("X16"); + result = "0x" + ((long)value).ToString("X16"); break; default: throw new FormatException("Unknown integer value type."); @@ -485,13 +255,11 @@ public static uint LoDWord(ulong value) public static ulong MakeUInt64(uint ms, uint ls) { - ulong result = (((ulong)ms) << 32) | ls; + var result = (((ulong)ms) << 32) | ls; return result; } #endregion - } - } diff --git a/Src/Workshell.PE/Workshell.PE.csproj b/Src/Workshell.PE/Workshell.PE.csproj index cb35548..eb757c7 100644 --- a/Src/Workshell.PE/Workshell.PE.csproj +++ b/Src/Workshell.PE/Workshell.PE.csproj @@ -1,141 +1,13 @@ - - - + + - Debug - AnyCPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D} - Library - Properties - Workshell.PE - pe - v4.0 - 512 - + netstandard1.6 - - true - full - false - ..\..\Bin\Debug\ - TRACE;DEBUG;SIGNED - prompt - 4 - - - pdbonly - true - ..\..\Bin\Release\ - TRACE;SIGNED - prompt - 4 - - - true - - - Workshell.PE.snk - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + - - - \ No newline at end of file + + diff --git a/Src/Workshell.PE/Workshell.PE.nuspec b/Src/Workshell.PE/Workshell.PE.nuspec deleted file mode 100644 index a0917a2..0000000 --- a/Src/Workshell.PE/Workshell.PE.nuspec +++ /dev/null @@ -1,23 +0,0 @@ - - - - Workshell.PE - $version$ - Workshell.PE - A class library for reading the Portable Executable file format. - A full featured class library for reading the Portable Executable file format covering all major sections. - Workshell Ltd - Workshell Ltd - en-US - https://github.com/Workshell/pe - https://raw.githubusercontent.com/Workshell/pe/master/license.txt - http://img.workshell.co.uk/logo_128.png - pe executable native - - - - - - - - \ No newline at end of file diff --git a/Src/dotNET PE.2015.sln b/Src/dotNET PE.2015.sln deleted file mode 100644 index b27d2ff..0000000 --- a/Src/dotNET PE.2015.sln +++ /dev/null @@ -1,44 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workshell.PE", "Workshell.PE\Workshell.PE.csproj", "{2E173D25-1C2E-4A7B-8B37-D231324D372D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workshell.PE.Resources", "Workshell.PE.Resources\Workshell.PE.Resources.csproj", "{2B06CBF8-136A-4BEC-8624-861992139489}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debug Application", "Debug Application\Debug Application.csproj", "{BE0852C4-A347-4E12-84C3-550AE6E5636F}" - ProjectSection(ProjectDependencies) = postProject - {2E173D25-1C2E-4A7B-8B37-D231324D372D} = {2E173D25-1C2E-4A7B-8B37-D231324D372D} - {2B06CBF8-136A-4BEC-8624-861992139489} = {2B06CBF8-136A-4BEC-8624-861992139489} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PE Dump", "PE Dump\PE Dump.csproj", "{3A01212E-8461-41A0-B154-22CBA75929A3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Release|Any CPU.Build.0 = Release|Any CPU - {2B06CBF8-136A-4BEC-8624-861992139489}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2B06CBF8-136A-4BEC-8624-861992139489}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2B06CBF8-136A-4BEC-8624-861992139489}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2B06CBF8-136A-4BEC-8624-861992139489}.Release|Any CPU.Build.0 = Release|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Release|Any CPU.Build.0 = Release|Any CPU - {3A01212E-8461-41A0-B154-22CBA75929A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3A01212E-8461-41A0-B154-22CBA75929A3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3A01212E-8461-41A0-B154-22CBA75929A3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3A01212E-8461-41A0-B154-22CBA75929A3}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Src/dotNET PE.sln b/Src/dotNET PE.sln deleted file mode 100644 index 94246a3..0000000 --- a/Src/dotNET PE.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workshell.PE", "Workshell.PE\Workshell.PE.csproj", "{2E173D25-1C2E-4A7B-8B37-D231324D372D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo Application", "Demo Application\Demo Application.csproj", "{BE0852C4-A347-4E12-84C3-550AE6E5636F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E173D25-1C2E-4A7B-8B37-D231324D372D}.Release|Any CPU.Build.0 = Release|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE0852C4-A347-4E12-84C3-550AE6E5636F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Tools/nuget.exe b/Tools/nuget.exe deleted file mode 100644 index 6bb79fe..0000000 Binary files a/Tools/nuget.exe and /dev/null differ diff --git a/dotNET PE.sln b/dotNET PE.sln new file mode 100644 index 0000000..5f5512f --- /dev/null +++ b/dotNET PE.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2042 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Workshell.PE", "src\Workshell.PE\Workshell.PE.csproj", "{2DF6E85A-7269-46C6-9032-1C3A8F029AE3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Workshell.PE.Testbed", "src\Workshell.PE.Testbed\Workshell.PE.Testbed.csproj", "{D73F5FEA-7576-4EF4-9DED-07D3F8607598}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2DF6E85A-7269-46C6-9032-1C3A8F029AE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2DF6E85A-7269-46C6-9032-1C3A8F029AE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2DF6E85A-7269-46C6-9032-1C3A8F029AE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2DF6E85A-7269-46C6-9032-1C3A8F029AE3}.Release|Any CPU.Build.0 = Release|Any CPU + {D73F5FEA-7576-4EF4-9DED-07D3F8607598}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D73F5FEA-7576-4EF4-9DED-07D3F8607598}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D73F5FEA-7576-4EF4-9DED-07D3F8607598}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D73F5FEA-7576-4EF4-9DED-07D3F8607598}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D281E078-262D-4616-9157-CE1C42C0026C} + EndGlobalSection +EndGlobal diff --git a/license.txt b/license.txt deleted file mode 100644 index d738ef9..0000000 --- a/license.txt +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2016, Workshell Ltd -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Workshell Ltd nor the names of its contributors - may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/readme.md b/readme.md deleted file mode 100644 index 2c9b3ba..0000000 --- a/readme.md +++ /dev/null @@ -1,48 +0,0 @@ -# Workshell PE - -This is a class library for reading the Portable Executable file format convering all the major data sections including: - -* Core Headers (DOS, File, Optional) -* Section Table -* Debug Directory -* Relocations -* Imports -* Delayed Imports -* Exports -* Resources -* TLS -* Load Configuration -* Certificates -* .NET - -For help getting started please see the wiki. Any suggestions for improvements and ideas welcome. - -# NuGet - -Stable builds are available as NuGet packages: - -* https://www.nuget.org/packages/Workshell.PE/ -* https://www.nuget.org/packages/Workshell.PE.Resources/ - -# Simplified BSD License - -Copyright (c) 2016, Workshell Ltd -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of Workshell Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL WORKSHELL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/src/Workshell.PE.Testbed/Program.cs b/src/Workshell.PE.Testbed/Program.cs new file mode 100644 index 0000000..6b325b2 --- /dev/null +++ b/src/Workshell.PE.Testbed/Program.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +using Workshell.PE.Content; + +namespace Workshell.PE.Testbed +{ + class Program + { + static void Main(string[] args) + { + RunAsync(args).GetAwaiter().GetResult(); + } + + 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.CLRRuntimeHeader]; + var content = await dataDirectory.GetContentAsync().ConfigureAwait(false); + + } + } +} diff --git a/src/Workshell.PE.Testbed/Workshell.PE.Testbed.csproj b/src/Workshell.PE.Testbed/Workshell.PE.Testbed.csproj new file mode 100644 index 0000000..d25a904 --- /dev/null +++ b/src/Workshell.PE.Testbed/Workshell.PE.Testbed.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.1 + + + + + + + diff --git a/src/Workshell.PE/Annotations/FieldAnnotations.cs b/src/Workshell.PE/Annotations/FieldAnnotations.cs new file mode 100644 index 0000000..a87b064 --- /dev/null +++ b/src/Workshell.PE/Annotations/FieldAnnotations.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +namespace Workshell.PE.Annotations +{ + public sealed class FieldAnnotation + { + internal FieldAnnotation(string desc, int arrayLen, bool flags, string name, Type type, object value, int size) + { + Description = desc; + ArrayLength = arrayLen; + Flags = flags; + Name = name; + Type = type; + Value = value; + Size = size; + } + + #region Methods + + public override string ToString() + { + var desc = Description ?? string.Empty; + var value = (Value == null ? "(null)" : Utils.IntToHex(Value)); + var result = (Type.IsArray ? $"{desc} [{ArrayLength}]" : $"{desc} - {value}"); + + return result; + } + + #endregion + + #region Properties + + public string Description { get; } + public int ArrayLength { get; } + public bool Flags { get; } + public string Name { get; } + public Type Type { get; } + public object Value { get; } + public int Size { get; } + public bool IsArray => Type.IsArray; + public int ArraySize => (IsArray ? ArrayLength * Size : 0); + + #endregion + } + + public sealed class FieldAnnotations : IEnumerable + { + private List _list; + + internal FieldAnnotations(object annotatedObject) + { + _list = new List(); + + if (annotatedObject != null) + { + var offset = 0; + + foreach(var prop in annotatedObject.GetType().GetProperties()) + { + var attr = prop.GetCustomAttribute(); + + if (attr == null) + continue; + + var desc = attr.Description; + var name = prop.Name; + var type = prop.PropertyType; + var size = 0; + + if (type.IsArray) + { + size = Marshal.SizeOf(type.GetElementType()); + } + else + { + size = Marshal.SizeOf(type); + } + + var value = prop.GetValue(annotatedObject,null); + var annotation = new FieldAnnotation(desc,attr.ArrayLength,attr.Flags,name,type,value,size); + + _list.Add(annotation); + + offset += size; + } + } + } + + #region Static Methods + + public static FieldAnnotations Get(object annotatedObj) + { + return Get(annotatedObj,false); + } + + public static FieldAnnotations Get(object annotatedObj, bool nullEmpty) + { + var annotations = new FieldAnnotations(annotatedObj); + + if (nullEmpty && annotations.Count == 0) + return null; + + return annotations; + } + + #endregion + + #region Method + + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + + #region Properties + + public int Count => _list.Count; + public FieldAnnotation this[int index] => _list[index]; + + #endregion + } +} diff --git a/src/Workshell.PE/Content/CLR/CLRMetaDataStreamTableEntry.cs b/src/Workshell.PE/Content/CLR/CLRMetaDataStreamTableEntry.cs new file mode 100644 index 0000000..6d8d157 --- /dev/null +++ b/src/Workshell.PE/Content/CLR/CLRMetaDataStreamTableEntry.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +using Workshell.PE.Extensions; + +namespace Workshell.PE.Content +{ + public sealed class CLRMetaDataStreamTableEntry : ISupportsLocation, ISupportsBytes + { + private readonly PortableExecutableImage _image; + + internal CLRMetaDataStreamTableEntry(PortableExecutableImage image, Location location, uint offset, uint size, string name) + { + _image = image; + + Location = location; + Offset = offset; + Size = size; + Name = name; + } + + #region Methods + + public override string ToString() + { + return $"Offset: 0x{Offset:X8}, Size: {Size}, Name: {Name}"; + } + + public byte[] GetBytes() + { + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); + + return buffer; + } + + #endregion + + #region Properties + + public Location Location { get; } + public uint Offset { get; } + public uint Size { get; } + public string Name { get; } + + #endregion + } +} diff --git a/src/Workshell.PE/Content/CLR/CLRMetaDataStreams.cs b/src/Workshell.PE/Content/CLR/CLRMetaDataStreams.cs new file mode 100644 index 0000000..cc74ba2 --- /dev/null +++ b/src/Workshell.PE/Content/CLR/CLRMetaDataStreams.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Workshell.PE.Extensions; + +namespace Workshell.PE.Content +{ + public sealed class CLRMetaDataStreams : IEnumerable, ISupportsLocation, ISupportsBytes + { + private readonly PortableExecutableImage _image; + private readonly CLRMetaDataStream[] _streams; + + internal CLRMetaDataStreams(PortableExecutableImage image, Location location, CLRMetaDataStream[] streams) + { + _image = image; + _streams = streams; + + Location = location; + Count = _streams.Length; + } + + #region Static Methods + + internal static Task LoadAsync(PortableExecutableImage image, Location mdLocation, CLRMetaDataStreamTable streamTable) + { + try + { + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var streams = new CLRMetaDataStream[streamTable.Count]; + + for(var i = 0; i < streams.Length; i++) + { + var entry = streamTable[i]; + var stream = new CLRMetaDataStream(image, mdLocation, imageBase, entry); + + streams[i] = stream; + } + + uint rva = 0; + ulong va = 0; + ulong offset = 0; + ulong size = 0; + + if (streams.Length > 0) + { + var stream = streams.MinBy(s => s.Location.FileOffset); + + rva = stream.Location.RelativeVirtualAddress; + va = stream.Location.VirtualAddress; + offset = stream.Location.FileOffset; + } + + foreach (var stream in streams) + size += stream.Location.FileSize; + + var location = new Location(image.GetCalculator(), offset, rva, va, size, size); + var result = new CLRMetaDataStreams(image, location, streams); + + return Task.FromResult(result); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not load CLR meta-data streams from stream.", ex); + } + } + + #endregion + + #region Methods + + public IEnumerator GetEnumerator() + { + foreach (var strm in _streams) + yield return strm; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public byte[] GetBytes() + { + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = _image.GetStream(); + var buffer = await stream.ReadBytesAsync(Location).ConfigureAwait(false); + + return buffer; + } + + #endregion + + #region Properties + + public Location Location { get; } + public int Count { get; } + public CLRMetaDataStream this[int index] => _streams[index]; + public CLRMetaDataStream this[string name] => _streams.SingleOrDefault(strm => string.Compare(name, strm.Name, StringComparison.OrdinalIgnoreCase) == 0); + + #endregion + } +} diff --git a/src/Workshell.PE/Content/Certificate.cs b/src/Workshell.PE/Content/Certificate.cs new file mode 100644 index 0000000..f7890be --- /dev/null +++ b/src/Workshell.PE/Content/Certificate.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using Workshell.PE.Extensions; +using Workshell.PE.Native; + +namespace Workshell.PE.Content +{ + public enum CertificateType : ushort + { + X509Certificate = 0x0001, + PKCSSignedData = 0x0002, + Reserved = 0x0003, + PKCS1ModuleSign = 0x0009 + } + + public sealed class Certificate : DataContent + { + internal Certificate(PortableExecutableImage image, DataDirectory directory, Location location, WIN_CERTIFICATE cert) : base(image, directory, location) + { + Length = cert.dwLength; + Revision = cert.wRevision; + CertificateType = cert.wCertificateType; + } + + #region Static Methods + + public static async Task LoadAsync(PortableExecutableImage image) + { + if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.CertificateTable)) + return null; + + var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.CertificateTable]; + + if (DataDirectory.IsNullOrEmpty(dataDirectory)) + return null; + + var stream = image.GetStream(); + var fileOffset = dataDirectory.VirtualAddress.ToInt64(); + + stream.Seek(fileOffset, SeekOrigin.Begin); + + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var location = new Location(image.GetCalculator(), dataDirectory.VirtualAddress, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, dataDirectory.Size, dataDirectory.Size); + WIN_CERTIFICATE cert; + + try + { + cert = await stream.ReadStructAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not load certificate information from stream.", ex); + } + + return new Certificate(image, dataDirectory, location, cert); + } + + #endregion + + #region Methods + + public CertificateType GetCertificateType() + { + return (CertificateType)CertificateType; + } + + public byte[] GetCertificateData() + { + return GetCertificateDataAsync().GetAwaiter().GetResult(); + } + + public async Task GetCertificateDataAsync() + { + var offset = Location.FileOffset + Marshal.SizeOf().ToUInt32(); + var stream = Image.GetStream(); + + stream.Seek(offset.ToInt64(), SeekOrigin.Begin); + + var buffer = new byte[Length]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead == 0) + throw new PortableExecutableImageException(Image, "Could not read certificate data from stream."); + + return buffer; + } + + public X509Certificate GetCertificate() + { + return GetCertificateAsync().GetAwaiter().GetResult(); + } + + public async Task GetCertificateAsync() + { + if (CertificateType == 1 || CertificateType == 2) // X.509 or PKCS#7 + { + var data = await GetCertificateDataAsync().ConfigureAwait(false); + X509Certificate2 cert = null; + + try + { + cert = new X509Certificate2(data); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(Image, "Could not load certificate from data.", ex); + } + + return cert; + } + + return null; + } + + #endregion + + #region Properties + + public uint Length { get; } + public ushort Revision { get; } + public ushort CertificateType { get; } + + #endregion + } +} diff --git a/src/Workshell.PE/Content/DataContent.cs b/src/Workshell.PE/Content/DataContent.cs new file mode 100644 index 0000000..9898308 --- /dev/null +++ b/src/Workshell.PE/Content/DataContent.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Workshell.PE.Extensions; + +namespace Workshell.PE.Content +{ + public class DataContent : ISupportsLocation, ISupportsBytes + { + public DataContent(PortableExecutableImage image, DataDirectory directory, Location location) + { + Directory = directory; + Location = location; + Image = image; + } + + #region Methods + + public byte[] GetBytes() + { + return GetBytesAsync().GetAwaiter().GetResult(); + } + + public async Task GetBytesAsync() + { + var stream = Image.GetStream(); + var result = await stream.ReadBytesAsync(Location).ConfigureAwait(false); + + return result; + } + + #endregion + + #region Properties + + public DataDirectory Directory { get; } + public Location Location { get; } + protected PortableExecutableImage Image { get; } + + #endregion + } +} diff --git a/src/Workshell.PE/Content/LoadConfigurationDirectory.cs b/src/Workshell.PE/Content/LoadConfigurationDirectory.cs new file mode 100644 index 0000000..832b81f --- /dev/null +++ b/src/Workshell.PE/Content/LoadConfigurationDirectory.cs @@ -0,0 +1,202 @@ +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 LoadConfigurationDirectory : DataContent + { + internal LoadConfigurationDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, IMAGE_LOAD_CONFIG_DIRECTORY32 directory) : base(image, dataDirectory, location) + { + Size = directory.Size; + TimeDateStamp = directory.TimeDateStamp; + MajorVersion = directory.MajorVersion; + MinorVersion = directory.MinorVersion; + GlobalFlagsClear = directory.GlobalFlagsClear; + GlobalFlagsSet = directory.GlobalFlagsSet; + CriticalSectionDefaultTimeout = directory.CriticalSectionDefaultTimeout; + DeCommitFreeBlockThreshold = directory.DeCommitFreeBlockThreshold; + DeCommitTotalFreeThreshold = directory.DeCommitFreeBlockThreshold; + LockPrefixTable = directory.LockPrefixTable; + MaximumAllocationSize = directory.MaximumAllocationSize; + VirtualMemoryThreshold = directory.VirtualMemoryThreshold; + ProcessAffinityMask = directory.ProcessAffinityMask; + ProcessHeapFlags = directory.ProcessHeapFlags; + CSDVersion = directory.CSDVersion; + EditList = directory.EditList; + SecurityCookie = directory.SecurityCookie; + SEHandlerTable = directory.SEHandlerTable; + SEHandlerCount = directory.SEHandlerCount; + GuardCFCheckFunctionPointer = directory.GuardCFCheckFunctionPointer; + GuardCFFunctionTable = directory.GuardCFFunctionTable; + GuardCFFunctionCount = directory.GuardCFFunctionCount; + GuardFlags = directory.GuardFlags; + } + + internal LoadConfigurationDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, IMAGE_LOAD_CONFIG_DIRECTORY64 directory) : base(image, dataDirectory, location) + { + Size = directory.Size; + TimeDateStamp = directory.TimeDateStamp; + MajorVersion = directory.MajorVersion; + MinorVersion = directory.MinorVersion; + GlobalFlagsClear = directory.GlobalFlagsClear; + GlobalFlagsSet = directory.GlobalFlagsSet; + CriticalSectionDefaultTimeout = directory.CriticalSectionDefaultTimeout; + DeCommitFreeBlockThreshold = directory.DeCommitFreeBlockThreshold; + DeCommitTotalFreeThreshold = directory.DeCommitFreeBlockThreshold; + LockPrefixTable = directory.LockPrefixTable; + MaximumAllocationSize = directory.MaximumAllocationSize; + VirtualMemoryThreshold = directory.VirtualMemoryThreshold; + ProcessAffinityMask = directory.ProcessAffinityMask; + ProcessHeapFlags = directory.ProcessHeapFlags; + CSDVersion = directory.CSDVersion; + EditList = directory.EditList; + SecurityCookie = directory.SecurityCookie; + SEHandlerTable = directory.SEHandlerTable; + SEHandlerCount = directory.SEHandlerCount; + GuardCFCheckFunctionPointer = directory.GuardCFCheckFunctionPointer; + GuardCFFunctionTable = directory.GuardCFFunctionTable; + GuardCFFunctionCount = directory.GuardCFFunctionCount; + GuardFlags = directory.GuardFlags; + } + + #region Static Methods + + public static async Task LoadAsync(PortableExecutableImage image) + { + if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.LoadConfigTable)) + return null; + + var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.LoadConfigTable]; + + if (DataDirectory.IsNullOrEmpty(dataDirectory)) + return null; + + var calc = image.GetCalculator(); + var section = calc.RVAToSection(dataDirectory.VirtualAddress); + var fileOffset = calc.RVAToOffset(section, dataDirectory.VirtualAddress); + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var location = new Location(fileOffset, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, dataDirectory.Size, dataDirectory.Size, section); + var stream = image.GetStream(); + + stream.Seek(fileOffset.ToInt64(), SeekOrigin.Begin); + + LoadConfigurationDirectory directory = null; + + if (image.Is32Bit) + { + IMAGE_LOAD_CONFIG_DIRECTORY32 config; + + try + { + config = await stream.ReadStructAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not load Load Configration Directory from stream."); + } + + directory = new LoadConfigurationDirectory(image, dataDirectory, location, config); + } + else + { + IMAGE_LOAD_CONFIG_DIRECTORY64 config; + + try + { + config = await stream.ReadStructAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not load Load Configration Directory from stream.", ex); + } + + directory = new LoadConfigurationDirectory(image, dataDirectory, location, config); + } + + return directory; + } + + #endregion + + #region Properties + + [FieldAnnotation("Size")] + public uint Size { get; } + + [FieldAnnotation("Date/Time Stamp")] + public uint TimeDateStamp { get; } + + [FieldAnnotation("Major Version")] + public ushort MajorVersion { get; } + + [FieldAnnotation("Minor Version")] + public ushort MinorVersion { get; } + + [FieldAnnotation("Global Flags Clear")] + public uint GlobalFlagsClear { get; } + + [FieldAnnotation("Global Flags Set")] + public uint GlobalFlagsSet { get; } + + [FieldAnnotation("Critical Section Default Timeout")] + public uint CriticalSectionDefaultTimeout { get; } + + [FieldAnnotation("De-commit Free Block Threshold")] + public ulong DeCommitFreeBlockThreshold { get; } + + [FieldAnnotation("De-commit Total Free Threshold")] + public ulong DeCommitTotalFreeThreshold { get; } + + [FieldAnnotation("Lock Prefix Table")] + public ulong LockPrefixTable { get; } + + [FieldAnnotation("Maximum Allocation Size")] + public ulong MaximumAllocationSize { get; } + + [FieldAnnotation("Virtual Memory Threshold")] + public ulong VirtualMemoryThreshold { get; } + + [FieldAnnotation("Process Affinity Mask")] + public ulong ProcessAffinityMask { get; } + + [FieldAnnotation("Process Heap Flags")] + public uint ProcessHeapFlags { get; } + + [FieldAnnotation("CSD Version")] + public ushort CSDVersion { get; } + + [FieldAnnotation("Edit List")] + public ulong EditList { get; } + + [FieldAnnotation("Security Cookie")] + public ulong SecurityCookie { get; } + + [FieldAnnotation("SEHandler Table")] + public ulong SEHandlerTable { get; } + + [FieldAnnotation("SEHandler Count")] + public ulong SEHandlerCount { get; } + + [FieldAnnotation("Guard CF Check Function Pointer")] + public ulong GuardCFCheckFunctionPointer { get; } + + [FieldAnnotation("Guard CF Function Table")] + public ulong GuardCFFunctionTable { get; } + + [FieldAnnotation("Guard CF Function Count")] + public ulong GuardCFFunctionCount { get; } + + [FieldAnnotation("Guard Flags")] + public uint GuardFlags { get; } + + #endregion + } +} + diff --git a/src/Workshell.PE/Content/TLSDirectory.cs b/src/Workshell.PE/Content/TLSDirectory.cs new file mode 100644 index 0000000..c3867f2 --- /dev/null +++ b/src/Workshell.PE/Content/TLSDirectory.cs @@ -0,0 +1,116 @@ +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 TLSDirectory : DataContent + { + internal TLSDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, IMAGE_TLS_DIRECTORY32 directory) : base(image, dataDirectory, location) + { + StartAddress = directory.StartAddress; + EndAddress = directory.EndAddress; + AddressOfIndex = directory.AddressOfIndex; + AddressOfCallbacks = directory.AddressOfCallbacks; + SizeOfZeroFill = directory.SizeOfZeroFill; + Characteristics = directory.Characteristics; + } + + internal TLSDirectory(PortableExecutableImage image, DataDirectory dataDirectory, Location location, IMAGE_TLS_DIRECTORY64 directory) : base(image, dataDirectory, location) + { + StartAddress = directory.StartAddress; + EndAddress = directory.EndAddress; + AddressOfIndex = directory.AddressOfIndex; + AddressOfCallbacks = directory.AddressOfCallbacks; + SizeOfZeroFill = directory.SizeOfZeroFill; + Characteristics = directory.Characteristics; + } + + #region Static Methods + + public static async Task LoadAsync(PortableExecutableImage image) + { + if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.TLSTable)) + return null; + + var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.TLSTable]; + + if (DataDirectory.IsNullOrEmpty(dataDirectory)) + return null; + + var calc = image.GetCalculator(); + var section = calc.RVAToSection(dataDirectory.VirtualAddress); + var fileOffset = calc.RVAToOffset(section, dataDirectory.VirtualAddress); + var imageBase = image.NTHeaders.OptionalHeader.ImageBase; + var location = new Location(fileOffset, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, dataDirectory.Size, dataDirectory.Size, section); + var stream = image.GetStream(); + + stream.Seek(fileOffset.ToInt64(), SeekOrigin.Begin); + + TLSDirectory directory = null; + + if (image.Is32Bit) + { + IMAGE_TLS_DIRECTORY32 config; + + try + { + config = await stream.ReadStructAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not load TLS Directory from stream.", ex); + } + + directory = new TLSDirectory(image, dataDirectory, location, config); + } + else + { + IMAGE_TLS_DIRECTORY64 config; + + try + { + config = await stream.ReadStructAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(image, "Could not load TLS Directory from stream.", ex); + } + + directory = new TLSDirectory(image, dataDirectory, location, config); + } + + return directory; + } + + #endregion + + #region Properties + + [FieldAnnotation("Start Address of Raw Data")] + public ulong StartAddress { get; } + + [FieldAnnotation("End Address of Raw Data")] + public ulong EndAddress { get; } + + [FieldAnnotation("Address of Index")] + public ulong AddressOfIndex { get; } + + [FieldAnnotation("Address of Callbacks")] + public ulong AddressOfCallbacks { get; } + + [FieldAnnotation("Size of Zero Fill")] + public uint SizeOfZeroFill { get; } + + [FieldAnnotation("Characteristics")] + public uint Characteristics { get; } + + #endregion + } +} + diff --git a/src/Workshell.PE/Extensions/Enumerable.cs b/src/Workshell.PE/Extensions/Enumerable.cs new file mode 100644 index 0000000..53b56da --- /dev/null +++ b/src/Workshell.PE/Extensions/Enumerable.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Workshell.PE.Extensions +{ + internal static class EnumerableExtensions + { + public static TSource MinBy(this IEnumerable source, Func selector) + { + return source.MinBy(selector, Comparer.Default); + } + + public static TSource MinBy(this IEnumerable source, Func selector, IComparer comparer) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + if (comparer == null) + throw new ArgumentNullException(nameof(comparer)); + + using (var sourceIterator = source.GetEnumerator()) + { + if (!sourceIterator.MoveNext()) + throw new InvalidOperationException("Sequence contains no elements"); + + var min = sourceIterator.Current; + var minKey = selector(min); + + while (sourceIterator.MoveNext()) + { + var candidate = sourceIterator.Current; + var candidateProjected = selector(candidate); + + if (comparer.Compare(candidateProjected, minKey) < 0) + { + min = candidate; + minKey = candidateProjected; + } + } + + return min; + } + } + } +} diff --git a/src/Workshell.PE/Extensions/Stream.cs b/src/Workshell.PE/Extensions/Stream.cs new file mode 100644 index 0000000..8d1eaac --- /dev/null +++ b/src/Workshell.PE/Extensions/Stream.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Workshell.PE.Extensions +{ + internal static class StreamExtensions + { + #region Methods + + public static async Task ReadStructAsync(this Stream stream) where T : struct + { + var size = Marshal.SizeOf(); + + return await ReadStructAsync(stream, size).ConfigureAwait(false); + } + + public static async Task ReadStructAsync(this Stream stream, int size, bool allowSmaller = false) where T : struct + { + var buffer = new byte[size]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (!allowSmaller && numRead < size) + throw new IOException("Could not read all of structure from stream."); + + if (numRead < size) + return default(T); + + return Utils.Read(buffer); + } + + public static async Task ReadByteAsync(this Stream stream) + { + var buffer = new byte[1]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < 1) + throw new IOException("Could not read byte from stream."); + + return buffer[0]; + } + + public static async Task ReadInt16Async(this Stream stream) + { + var buffer = new byte[sizeof(short)]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < buffer.Length) + throw new IOException("Could not read int16 from stream."); + + return Utils.ReadInt16(buffer); + } + + public static async Task ReadInt32Async(this Stream stream) + { + var buffer = new byte[sizeof(int)]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < buffer.Length) + throw new IOException("Could not read int32 from stream."); + + return Utils.ReadInt32(buffer); + } + + public static async Task ReadInt64Async(this Stream stream) + { + var buffer = new byte[sizeof(long)]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < buffer.Length) + throw new IOException("Could not read int64 from stream."); + + return Utils.ReadInt64(buffer); + } + + public static async Task ReadUInt16Async(this Stream stream) + { + var buffer = new byte[sizeof(ushort)]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < buffer.Length) + throw new IOException("Could not read uint16 from stream."); + + return Utils.ReadUInt16(buffer); + } + + public static async Task ReadUInt32Async(this Stream stream) + { + var buffer = new byte[sizeof(uint)]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < buffer.Length) + throw new IOException("Could not read uint32 from stream."); + + return Utils.ReadUInt32(buffer); + } + + public static async Task ReadUInt64Async(this Stream stream) + { + var buffer = new byte[sizeof(ulong)]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + if (numRead < buffer.Length) + throw new IOException("Could not read uint64 from stream."); + + return Utils.ReadUInt64(buffer); + } + + public static async Task ReadStringAsync(this Stream stream) + { + var builder = new StringBuilder(256); + var buffer = new byte[1]; + + while (true) + { + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length); + + if (numRead < 1 || buffer[0] == 0) + break; + + builder.Append((char) buffer[0]); + } + + return builder.ToString(); + } + + public static async Task ReadStringAsync(this Stream stream, int size, bool allowSmaller = true) + { + var buffer = new byte[size]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length); + + if (!allowSmaller && numRead < buffer.Length) + throw new IOException("Could not read string from stream."); + + var builder = new StringBuilder(256); + + foreach(var b in buffer) + { + if (b == 0) + break; + + builder.Append((char)b); + } + + return builder.ToString(); + } + + public static async Task ReadUnicodeStringAsync(this Stream stream) + { + var builder = new StringBuilder(); + + while (true) + { + var value = await ReadUInt16Async(stream).ConfigureAwait(false); + + if (value == 0) + break; + + builder.Append((char)value); + } + + return builder.ToString(); + } + + public static async Task ReadUnicodeStringAsync(this Stream stream, int charCount) + { + var builder = new StringBuilder(); + + for(var i = 0; i < charCount; i++) + { + var value = await ReadUInt16Async(stream).ConfigureAwait(false); + + if (value == 0) + break; + + builder.Append((char)value); + } + + return builder.ToString(); + } + + public static async Task ReadBytesAsync(this Stream stream, int count, long offset = -1) + { + if (offset >= 0) + stream.Seek(offset, SeekOrigin.Begin); + + var buffer = new byte[count]; + var numRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + var results = new byte[numRead]; + + Array.Copy(buffer, 0, results, 0, numRead); + + return results; + } + + public static async Task ReadBytesAsync(this Stream stream, Location location) + { + return await ReadBytesAsync(stream, location.FileSize.ToInt32(), location.FileOffset.ToInt64()) + .ConfigureAwait(false); + } + + public static async Task SkipBytesAsync(this Stream stream, int count) + { + var buffer = new byte[count]; + + return await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + } + + #endregion + } +} diff --git a/src/Workshell.PE/PortableExecutableImage.cs b/src/Workshell.PE/PortableExecutableImage.cs new file mode 100644 index 0000000..2f67eca --- /dev/null +++ b/src/Workshell.PE/PortableExecutableImage.cs @@ -0,0 +1,331 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +using Workshell.PE.Extensions; +using Workshell.PE.Native; + +namespace Workshell.PE +{ + public sealed class PortableExecutableImage : IDisposable + { + private readonly Stream _stream; + private readonly bool _ownStream; + private bool _disposed; + private LocationCalculator _calc; + + private PortableExecutableImage(Stream stream, bool ownStream) + { + _stream = stream; + _ownStream = ownStream; + _disposed = false; + _calc = null; + } + + #region Static Methods + + public static PortableExecutableImage FromFile(string fileName) + { + var file = new FileStream(fileName, FileMode.Open, FileAccess.Read); + + return FromStream(file); + } + + public static async Task FromFileAsync(string fileName) + { + var file = new FileStream(fileName, FileMode.Open, FileAccess.Read); + + return await FromStreamAsync(file).ConfigureAwait(false); + } + + public static PortableExecutableImage FromStream(Stream stream, bool ownStream = true) + { + return FromStreamAsync(stream, ownStream).GetAwaiter().GetResult(); + } + + public static async Task FromStreamAsync(Stream stream, bool ownStream = true) + { + var image = new PortableExecutableImage(stream, ownStream); + + await image.LoadAsync().ConfigureAwait(false); + + return image; + } + + public static bool IsValid(string fileName) + { + var file = new FileStream(fileName, FileMode.Open, FileAccess.Read); + + return IsValid(file); + } + + public static async Task IsValidAsync(string fileName) + { + var file = new FileStream(fileName, FileMode.Open, FileAccess.Read); + + return await IsValidAsync(file).ConfigureAwait(false); + } + + public static bool IsValid(Stream stream, bool ownStream = true) + { + return IsValidAsync(stream, ownStream).GetAwaiter().GetResult(); + } + + public static async Task IsValidAsync(Stream stream, bool ownStream = true) + { + try + { + using (var image = await PortableExecutableImage.FromStreamAsync(stream, ownStream).ConfigureAwait(false)) + { + return true; + } + } + catch (PortableExecutableImageException) + { + return false; + } + } + + #endregion + + #region Methods + + public void Dispose() + { + if (!_disposed) + { + if (_ownStream) + _stream.Dispose(); + + _disposed = true; + } + } + + public LocationCalculator GetCalculator() + { + if (_calc == null) + _calc = new LocationCalculator(this); + + return _calc; + } + + public Stream GetStream() + { + return _stream; + } + + private async Task LoadAsync() + { + if (!_stream.CanSeek) + throw new PortableExecutableImageException(this, "Cannot seek in stream."); + + if (!_stream.CanRead) + throw new PortableExecutableImageException(this, "Cannot read from stream."); + + IMAGE_DOS_HEADER dosHeader; + + try + { + dosHeader = await _stream.ReadStructAsync(DOSHeader.Size).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Cannot read DOS header from stream.", ex); + } + + if (dosHeader.e_magic != DOSHeader.DOS_MAGIC_MZ) + throw new PortableExecutableImageException(this, "Incorrect magic number specified in DOS header."); + + if (dosHeader.e_lfanew == 0) + throw new PortableExecutableImageException(this, "No new header location specified in DOS header, most likely a 16-bit executable."); + + if (dosHeader.e_lfanew >= (256 * (1024 * 1024))) + throw new PortableExecutableImageException(this, "New header location specified in MS-DOS header is beyond 256mb boundary (see RtlImageNtHeaderEx)."); + + if (dosHeader.e_lfanew % 4 != 0) + throw new PortableExecutableImageException(this, "New header location specified in MS-DOS header is not properly aligned."); + + if (dosHeader.e_lfanew < DOSHeader.Size) + throw new PortableExecutableImageException(this, "New header location specified is invalid."); + + var stubOffset = DOSHeader.Size; + var stubSize = dosHeader.e_lfanew - DOSHeader.Size; + var stubRead = await _stream.SkipBytesAsync(stubSize).ConfigureAwait(false); + + if (stubRead < stubSize) + throw new PortableExecutableImageException(this, "Could not read DOS stub from stream."); + + _stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); + + var ntOffset = _stream.Position; + uint peSig; + + try + { + peSig = await _stream.ReadUInt32Async().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Could not read PE signature from stream.", ex); + } + + if (peSig != NTHeaders.PE_MAGIC_MZ) + throw new PortableExecutableImageException(this, "Incorrect PE signature found in NT Header."); + + IMAGE_FILE_HEADER fileHdr; + + try + { + fileHdr = await _stream.ReadStructAsync(FileHeader.Size).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Could not read NT Header from stream.", ex); + } + + ushort magic = 0; + + try + { + magic = await _stream.ReadUInt16Async().ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Could not read Optional Header magic number from stream.", ex); + } + + Is32Bit = (magic == (ushort)MagicType.PE32); + Is64Bit = (magic == (ushort)MagicType.PE32plus); + + if (!Is32Bit && !Is64Bit) + throw new PortableExecutableImageException(this, "Unknown PE type."); + + byte[] optionalHeaderBytes; + + try + { + var optionalHeaderSize = (Is32Bit ? Marshal.SizeOf() : Marshal.SizeOf()); + + optionalHeaderBytes = await _stream.ReadBytesAsync(optionalHeaderSize).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Could not read Optional Header from stream.", ex); + } + + IMAGE_OPTIONAL_HEADER32 optionalHeader32 = new IMAGE_OPTIONAL_HEADER32(); + IMAGE_OPTIONAL_HEADER64 optionalHeader64 = new IMAGE_OPTIONAL_HEADER64(); + var dirCount = 0; + + if (Is32Bit) + { + optionalHeader32 = Utils.Read(optionalHeaderBytes); + + dirCount = optionalHeader32.NumberOfRvaAndSizes.ToInt32(); + } + else + { + optionalHeader64 = Utils.Read(optionalHeaderBytes); + + dirCount = optionalHeader64.NumberOfRvaAndSizes.ToInt32(); + } + + var dataDirs = new IMAGE_DATA_DIRECTORY[dirCount]; + var dataDirSize = Marshal.SizeOf(); + + for (var i = 0; i < dirCount; i++) + { + try + { + dataDirs[i] = await _stream.ReadStructAsync(dataDirSize).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Could not read data directory from stream.", ex); + } + } + + var sectionTableEntrySize = Marshal.SizeOf(); + var sectionTable = new IMAGE_SECTION_HEADER[fileHdr.NumberOfSections]; + + for (var i = 0; i < fileHdr.NumberOfSections; i++) + { + try + { + sectionTable[i] = await _stream.ReadStructAsync(sectionTableEntrySize).ConfigureAwait(false); + } + catch (Exception ex) + { + throw new PortableExecutableImageException(this, "Could not read section table entry from stream.", ex); + } + } + + IsCLR = false; + + var clrIndex = (int)DataDirectoryType.CLRRuntimeHeader; + + if (clrIndex >= 0 && clrIndex <= (dataDirs.Length - 1)) + { + var clrDirectory = dataDirs[clrIndex]; + + if (clrDirectory.VirtualAddress > 0 && clrDirectory.Size > 0) + IsCLR = true; + } + + IsSigned = false; + + var certIndex = (int)DataDirectoryType.CertificateTable; + + if (certIndex >= 0 && certIndex <= (dataDirs.Length - 1)) + { + var certDirectory = dataDirs[certIndex]; + + if (certDirectory.VirtualAddress > 0 && certDirectory.Size > 0) + IsSigned = true; + } + + var imageBase = (Is32Bit ? optionalHeader32.ImageBase : optionalHeader64.ImageBase); + + DOSHeader = new DOSHeader(this, dosHeader, imageBase); + DOSStub = new DOSStub(this, stubOffset.ToUInt64(), stubSize.ToUInt32(), imageBase); + + var fileHeader = new FileHeader(this, fileHdr, DOSStub.Location.FileOffset + DOSStub.Location.FileSize + 4, imageBase); + OptionalHeader optionalHeader; + + if (Is32Bit) + { + optionalHeader = new OptionalHeader32(this, optionalHeader32, fileHeader.Location.FileOffset + fileHeader.Location.FileSize, imageBase, magic); + } + else + { + optionalHeader = new OptionalHeader64(this, optionalHeader64, fileHeader.Location.FileOffset + fileHeader.Location.FileSize, imageBase, magic); + } + + var dataDirectories = new DataDirectoryCollection(this, optionalHeader, dataDirs); + + NTHeaders = new NTHeaders(this, ntOffset.ToUInt64(), imageBase, fileHeader, optionalHeader, dataDirectories); + SectionTable = new SectionTable(this, sectionTable, NTHeaders.Location.FileOffset + NTHeaders.Location.FileSize, imageBase); + Sections = new Sections(this, SectionTable); + } + + #endregion + + #region Properties + + public bool Is32Bit { get; private set; } + public bool Is64Bit { get; private set; } + public bool IsCLR { get; private set; } + public bool IsSigned { get; private set; } + public DOSHeader DOSHeader { get; private set; } + public DOSStub DOSStub { get; private set; } + public NTHeaders NTHeaders { get; private set; } + public SectionTable SectionTable { get; private set; } + public Sections Sections { get; private set; } + + #endregion + } +} diff --git a/src/Workshell.PE/PortableExecutableImageException.cs b/src/Workshell.PE/PortableExecutableImageException.cs new file mode 100644 index 0000000..6cd0573 --- /dev/null +++ b/src/Workshell.PE/PortableExecutableImageException.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Workshell.PE +{ + public sealed class PortableExecutableImageException : Exception + { + public PortableExecutableImageException(PortableExecutableImage image) + { + Image = image; + } + + public PortableExecutableImageException(PortableExecutableImage image, string message) : base(message) + { + Image = image; + } + + public PortableExecutableImageException(PortableExecutableImage image, string message, Exception innerException) : base(message, innerException) + { + Image = image; + } + + #region Properties + + public PortableExecutableImage Image { get; } + + #endregion + } +}