├── dnlib.snk ├── Examples ├── app.config ├── Properties │ └── AssemblyInfo.cs ├── GetILAsByteArray.cs ├── Program.cs ├── Example5.cs ├── Example1.cs ├── Example2.cs └── Examples.csproj ├── src ├── DotNet │ ├── Extensions.cs │ ├── Emit │ │ ├── Extensions.cs │ │ ├── OpCodeType.cs │ │ ├── ExceptionHandlerType.cs │ │ ├── FlowControl.cs │ │ ├── InvalidMethodException.cs │ │ ├── StackBehaviour.cs │ │ ├── ExceptionHandler.cs │ │ └── OperandType.cs │ ├── Pdb │ │ ├── Managed │ │ │ ├── DbiSourceLine.cs │ │ │ ├── ModuleStreamType.cs │ │ │ ├── MsfStream.cs │ │ │ ├── DbiNamespace.cs │ │ │ ├── PdbException.cs │ │ │ ├── DbiVariable.cs │ │ │ ├── DbiDocument.cs │ │ │ └── SymbolReaderCreator.cs │ │ ├── PdbImplType.cs │ │ ├── Dss │ │ │ ├── SymbolDocumentWriter.cs │ │ │ ├── SymbolNamespace.cs │ │ │ ├── SymbolWriterCreator.cs │ │ │ ├── SymbolVariable.cs │ │ │ ├── PinnedMetaData.cs │ │ │ ├── SymbolScope.cs │ │ │ └── SymbolDocument.cs │ │ ├── SymbolWriterCreator.cs │ │ ├── SequencePoint.cs │ │ ├── PdbScope.cs │ │ └── ISymbolWriter2.cs │ ├── MD │ │ ├── HotHeapVersion.cs │ │ ├── HeapType.cs │ │ ├── StorageFlags.cs │ │ ├── MDStreamFlags.cs │ │ ├── IRowReaders.cs │ │ ├── ComImageFlags.cs │ │ ├── GuidStream.cs │ │ ├── StringsStream.cs │ │ ├── USStream.cs │ │ ├── TableInfo.cs │ │ ├── StreamHeader.cs │ │ ├── MDHeaderRuntimeVersion.cs │ │ └── BlobStream.cs │ ├── FileAttributes.cs │ ├── EventAttributes.cs │ ├── WinMDStatus.cs │ ├── IVariable.cs │ ├── ManifestResourceAttributes.cs │ ├── ModuleKind.cs │ ├── Writer │ │ ├── IHeap.cs │ │ ├── IWriterError.cs │ │ ├── Extensions.cs │ │ ├── ModuleWriterException.cs │ │ ├── ImportAddressTable.cs │ │ ├── StrongNameSignature.cs │ │ ├── WriterUtils.cs │ │ ├── RelocDirectory.cs │ │ ├── IOffsetHeap.cs │ │ ├── ChunkList.cs │ │ ├── BinaryReaderChunk.cs │ │ ├── UniqueChunkList.cs │ │ ├── StartupStub.cs │ │ ├── ByteArrayChunk.cs │ │ ├── HeapBase.cs │ │ ├── SectionSizes.cs │ │ ├── GuidHeap.cs │ │ ├── NetResources.cs │ │ ├── DebugDirectory.cs │ │ ├── PESection.cs │ │ └── ImportDirectory.cs │ ├── PropertyAttributes.cs │ ├── Resources │ │ ├── ResourceElement.cs │ │ ├── ResourceElementSet.cs │ │ ├── IResourceData.cs │ │ ├── UserResourceType.cs │ │ ├── UserResourceData.cs │ │ └── ResourceTypeCode.cs │ ├── ParamAttributes.cs │ ├── MethodSemanticsAttributes.cs │ ├── MemberMDInitializer.cs │ ├── MethodOverride.cs │ ├── GenericParamAttributes.cs │ ├── ITokenResolver.cs │ ├── PublicKeyToken.cs │ ├── NullResolver.cs │ ├── AllTypesHelper.cs │ ├── CallingConvention.cs │ ├── ICustomAttribute.cs │ ├── IDecrypters.cs │ ├── SecurityAction.cs │ ├── SerializationType.cs │ ├── RecursionCounter.cs │ ├── MethodImplAttributes.cs │ ├── PInvokeAttributes.cs │ ├── AssemblyHashAlgorithm.cs │ ├── FieldAttributes.cs │ ├── ModuleContext.cs │ ├── AssemblyAttributes.cs │ ├── PublicKey.cs │ ├── VariantType.cs │ ├── GenericParamContext.cs │ ├── ModuleCreationOptions.cs │ └── MethodAttributes.cs ├── IO │ ├── IOExtensions.cs │ ├── IFileSection.cs │ ├── FileOffset.cs │ ├── FileSection.cs │ ├── IImageStream.cs │ ├── IImageStreamCreator.cs │ ├── MemoryStreamCreator.cs │ └── BinaryReaderStream.cs ├── Utils │ ├── Extensions.cs │ ├── MFunc.cs │ ├── ILazyList.cs │ └── UserValue.cs ├── Threading │ ├── Extensions.cs │ ├── ICancellationToken.cs │ └── Lock.cs ├── ExtensionAttribute.cs ├── HandleProcessCorruptedStateExceptionsAttribute.cs ├── Settings.cs ├── Properties │ └── AssemblyInfo.cs ├── W32Resources │ ├── ResourceDirectoryEntry.cs │ └── ResourceData.cs └── PE │ ├── RVA.cs │ ├── IPEType.cs │ ├── PEExtensions.cs │ ├── ImageDosHeader.cs │ ├── Subsystem.cs │ ├── ImageDataDirectory.cs │ ├── DllCharacteristics.cs │ ├── Characteristics.cs │ ├── Machine.cs │ ├── ImageNTHeaders.cs │ └── ImageFileHeader.cs ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE.txt └── dnlib.sln /dnlib.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XenocodeRCE/dnlib/master/dnlib.snk -------------------------------------------------------------------------------- /Examples/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/DotNet/Extensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Extension methods 6 | /// 7 | public static partial class Extensions { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/IO/IOExtensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.IO { 4 | /// 5 | /// Extension methods 6 | /// 7 | public static partial class IOExtensions { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Utils/Extensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.Utils { 4 | /// 5 | /// Extension methods 6 | /// 7 | public static partial class Extensions { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/DotNet/Emit/Extensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Emit { 4 | /// 5 | /// Extension methods 6 | /// 7 | public static partial class Extensions { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Threading/Extensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.Threading { 4 | /// 5 | /// Extension methods 6 | /// 7 | public static partial class Extensions { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | */obj/ 3 | *.csproj.user 4 | *.sdf 5 | *.opensdf 6 | *.suo 7 | /Debug/ 8 | /Release/ 9 | /Examples/bin/ 10 | *.tmp_proj 11 | *.lock 12 | *.ide 13 | *.ide-shm 14 | *.ide-wal 15 | Examples/Program.cs 16 | Examples/testToInject.cs 17 | Examples/Program.cs 18 | Examples/Program.cs 19 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/DbiSourceLine.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Pdb.Managed { 4 | struct DbiSourceLine { 5 | public DbiDocument Document; 6 | public uint Offset; 7 | public uint LineBegin; 8 | public uint LineEnd; 9 | public uint ColumnBegin; 10 | public uint ColumnEnd; 11 | } 12 | } -------------------------------------------------------------------------------- /src/ExtensionAttribute.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | #pragma warning disable 1591 // XML doc warning 4 | 5 | namespace System.Runtime.CompilerServices { 6 | [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)] 7 | public sealed class ExtensionAttribute : Attribute { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/HandleProcessCorruptedStateExceptionsAttribute.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | #pragma warning disable 1591 // XML doc warning 4 | 5 | namespace System.Runtime.ExceptionServices { 6 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] 7 | sealed class HandleProcessCorruptedStateExceptionsAttribute : Attribute { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/DotNet/MD/HotHeapVersion.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.MD { 4 | /// 5 | /// Hot heap version 6 | /// 7 | public enum HotHeapVersion { 8 | /// 9 | /// CLR 2.0 (.NET 2.0 - 3.5) 10 | /// 11 | CLR20, 12 | 13 | /// 14 | /// CLR 4.0 (.NET 4.0 - 4.5) 15 | /// 16 | CLR40, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNet/Emit/OpCodeType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Emit { 4 | /// 5 | /// CIL opcode type 6 | /// 7 | public enum OpCodeType : byte { 8 | /// 9 | Annotation, 10 | /// 11 | Macro, 12 | /// 13 | Nternal, 14 | /// 15 | Objmodel, 16 | /// 17 | Prefix, 18 | /// 19 | Primitive, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Threading/ICancellationToken.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.Threading { 6 | /// 7 | /// Cancellation token interface 8 | /// 9 | public interface ICancellationToken { 10 | /// 11 | /// Throws a if the operation should be canceled 12 | /// 13 | void ThrowIfCancellationRequested(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DotNet/MD/HeapType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.MD { 4 | /// 5 | /// Heap type. The values are set in stone by MS. Don't change. 6 | /// 7 | public enum HeapType : uint { 8 | /// #Strings heap 9 | Strings = 0, 10 | /// #GUID heap 11 | Guid = 1, 12 | /// #Blob heap 13 | Blob = 2, 14 | /// #US heap 15 | US = 3, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/ModuleStreamType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Pdb.Managed { 4 | enum ModuleStreamType : uint { 5 | Symbols = 0xF1, 6 | Lines = 0xF2, 7 | StringTable = 0xF3, 8 | FileInfo = 0xF4, 9 | FrameData = 0xF5, 10 | InlineeLines = 0xF6, 11 | CrossScopeImports = 0xF7, 12 | CrossScopeExports = 0xF8, 13 | ILLines = 0xF9, 14 | FuncMDTokenMap = 0xFA, 15 | TypeMDTokenMap = 0xFB, 16 | MergedAssemblyInput = 0xFC, 17 | } 18 | } -------------------------------------------------------------------------------- /src/Settings.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib { 4 | /// 5 | /// dnlib settings 6 | /// 7 | public static class Settings { 8 | /// 9 | /// true if dnlib is thread safe. (THREAD_SAFE was defined during compilation) 10 | /// 11 | public static bool IsThreadSafe { 12 | get { 13 | #if THREAD_SAFE 14 | return true; 15 | #else 16 | return false; 17 | #endif 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DotNet/FileAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// File row flags. See CorHdr.h/CorFileFlags 8 | /// 9 | [Flags] 10 | public enum FileAttributes : uint { 11 | /// This is not a resource file 12 | ContainsMetaData = 0x0000, 13 | /// This is a resource file or other non-metadata-containing file 14 | ContainsNoMetaData = 0x0001, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNet/EventAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Event attributes, see CorHdr.h/CorEventAttr 8 | /// 9 | [Flags] 10 | public enum EventAttributes : ushort { 11 | /// event is special. Name describes how. 12 | SpecialName = 0x0200, 13 | /// Runtime(metadata internal APIs) should check name encoding. 14 | RTSpecialName = 0x0400, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Utils/MFunc.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.Utils { 4 | delegate T MFunc(); 5 | delegate U MFunc(T t); 6 | 7 | /// 8 | /// Same as Func delegate 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | public delegate V MFunc(T t, U u); 17 | } 18 | -------------------------------------------------------------------------------- /src/DotNet/WinMDStatus.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// WinMD status 6 | /// 7 | public enum WinMDStatus { 8 | /// 9 | /// This is not a WinMD file 10 | /// 11 | None, 12 | 13 | /// 14 | /// This is a pure WinMD file (not managed) 15 | /// 16 | Pure, 17 | 18 | /// 19 | /// This is a managed WinMD file (created by eg. winmdexp.exe) 20 | /// 21 | Managed, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNet/Emit/ExceptionHandlerType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.Emit { 6 | /// 7 | /// Type of exception handler. See CorHdr.h/CorExceptionFlag 8 | /// 9 | [Flags] 10 | public enum ExceptionHandlerType { 11 | /// 12 | Catch = 0x0000, 13 | /// 14 | Filter = 0x0001, 15 | /// 16 | Finally = 0x0002, 17 | /// 18 | Fault = 0x0004, 19 | /// 20 | Duplicated = 0x0008, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNet/Emit/FlowControl.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Emit { 4 | /// 5 | /// CIL opcode flow control 6 | /// 7 | public enum FlowControl { 8 | /// 9 | Branch, 10 | /// 11 | Break, 12 | /// 13 | Call, 14 | /// 15 | Cond_Branch, 16 | /// 17 | Meta, 18 | /// 19 | Next, 20 | /// 21 | Phi, 22 | /// 23 | Return, 24 | /// 25 | Throw, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/PdbImplType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Pdb { 4 | /// 5 | /// PDB implementation type 6 | /// 7 | public enum PdbImplType { 8 | /// 9 | /// Use Microsoft's COM DLL (diasymreader.dll) 10 | /// 11 | MicrosoftCOM, 12 | 13 | /// 14 | /// Use the managed PDB reader 15 | /// 16 | Managed, 17 | 18 | /// 19 | /// Use the default PDB reader 20 | /// 21 | Default = Managed, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/IO/IFileSection.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.IO { 4 | /// 5 | /// Represents a section in a file 6 | /// 7 | public interface IFileSection { 8 | /// 9 | /// Start offset of the section in the file 10 | /// 11 | FileOffset StartOffset { get; } 12 | 13 | /// 14 | /// End offset of the section in the file. This is one byte after the last 15 | /// valid offset in the section. 16 | /// 17 | FileOffset EndOffset { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DotNet/IVariable.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Interface to access a local or a parameter 6 | /// 7 | public interface IVariable { 8 | /// 9 | /// Gets the variable type 10 | /// 11 | TypeSig Type { get; } 12 | 13 | /// 14 | /// Gets the 0-based position 15 | /// 16 | int Index { get; } 17 | 18 | /// 19 | /// Gets/sets the variable name 20 | /// 21 | string Name { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNet/ManifestResourceAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// ManifestResource flags. See CorHdr.h/CorManifestResourceFlags 8 | /// 9 | [Flags] 10 | public enum ManifestResourceAttributes : uint { 11 | /// 12 | VisibilityMask = 0x0007, 13 | /// The Resource is exported from the Assembly. 14 | Public = 0x0001, 15 | /// The Resource is private to the Assembly. 16 | Private = 0x0002, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DotNet/ModuleKind.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Module kind 6 | /// 7 | public enum ModuleKind { 8 | /// 9 | /// Console UI module 10 | /// 11 | Console, 12 | 13 | /// 14 | /// Windows GUI module 15 | /// 16 | Windows, 17 | 18 | /// 19 | /// DLL module 20 | /// 21 | Dll, 22 | 23 | /// 24 | /// Netmodule (it has no assembly manifest) 25 | /// 26 | NetModule, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNet/Writer/IHeap.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Writer { 4 | /// 5 | /// .NET Heap interface 6 | /// 7 | public interface IHeap : IChunk { 8 | /// 9 | /// Gets the name of the heap 10 | /// 11 | string Name { get; } 12 | 13 | /// 14 | /// Checks whether the heap is empty 15 | /// 16 | bool IsEmpty { get; } 17 | 18 | /// 19 | /// Called when the heap should be set to read-only mode 20 | /// 21 | void SetReadOnly(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNet/MD/StorageFlags.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.MD { 6 | /// 7 | /// Storage flags found in the MD header 8 | /// 9 | [Flags] 10 | public enum StorageFlags : byte { 11 | /// 12 | /// Normal flags 13 | /// 14 | Normal = 0, 15 | 16 | /// 17 | /// More data after the header but before the streams. 18 | /// 19 | /// The CLR will fail to load the file if this flag (or any other bits) is set. 20 | ExtraData = 1, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DotNet/PropertyAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Property attributes, see CorHdr.h/CorPropertyAttr 8 | /// 9 | [Flags] 10 | public enum PropertyAttributes : ushort { 11 | /// property is special. Name describes how. 12 | SpecialName = 0x0200, 13 | /// Runtime(metadata internal APIs) should check name encoding. 14 | RTSpecialName = 0x0400, 15 | /// Property has default 16 | HasDefault = 0x1000, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Examples/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | [assembly: AssemblyTitle("dnlib.Examples")] 5 | [assembly: AssemblyDescription("dnlib examples")] 6 | [assembly: AssemblyConfiguration("")] 7 | [assembly: AssemblyCompany("")] 8 | [assembly: AssemblyProduct("dnlib.Examples")] 9 | [assembly: AssemblyCopyright("Copyright (C) 2012-2014 de4dot@gmail.com")] 10 | [assembly: AssemblyTrademark("")] 11 | [assembly: AssemblyCulture("")] 12 | [assembly: ComVisible(false)] 13 | [assembly: AssemblyVersion("1.0.0.0")] 14 | [assembly: AssemblyFileVersion("1.0.0.0")] 15 | -------------------------------------------------------------------------------- /src/DotNet/Resources/ResourceElement.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Resources { 4 | /// 5 | /// Resource element 6 | /// 7 | public sealed class ResourceElement { 8 | /// 9 | /// Name of resource 10 | /// 11 | public string Name { get; set; } 12 | 13 | /// 14 | /// Data of resource 15 | /// 16 | public IResourceData ResourceData { get; set; } 17 | 18 | /// 19 | public override string ToString() { 20 | return string.Format("N: {0}, V: {1}", Name, ResourceData); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/MsfStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using dnlib.IO; 5 | 6 | namespace dnlib.DotNet.Pdb.Managed { 7 | sealed class MsfStream { 8 | public MsfStream(IImageStream[] pages, uint length) { 9 | byte[] buf = new byte[length]; 10 | int offset = 0; 11 | foreach (var page in pages) { 12 | page.Position = 0; 13 | int len = Math.Min((int)page.Length, (int)(length - offset)); 14 | offset += page.Read(buf, offset, len); 15 | } 16 | Content = new MemoryImageStream(0, buf, 0, buf.Length); 17 | } 18 | 19 | public IImageStream Content { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/DotNet/Writer/IWriterError.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Writer { 4 | /// 5 | /// Gets notified of errors. The default handler should normally throw since the written data 6 | /// will probably be invalid. Any error can be ignored. 7 | /// 8 | public interface IWriterError { 9 | /// 10 | /// Called when an error is detected (eg. a null pointer or other invalid value). The error 11 | /// can be ignored but the written data won't be valid. 12 | /// 13 | /// Error message 14 | void Error(string message); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DotNet/ParamAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Parameter flags. See CorHdr.h/CorParamAttr 8 | /// 9 | [Flags] 10 | public enum ParamAttributes : ushort { 11 | /// Param is [In] 12 | In = 0x0001, 13 | /// Param is [out] 14 | Out = 0x0002, 15 | /// Param is optional 16 | Optional = 0x0010, 17 | 18 | /// Param has default value. 19 | HasDefault = 0x1000, 20 | /// Param has FieldMarshal. 21 | HasFieldMarshal = 0x2000, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DotNet/Writer/Extensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | 5 | namespace dnlib.DotNet.Writer { 6 | /// 7 | /// Extension methods 8 | /// 9 | public static partial class Extensions { 10 | /// 11 | /// Write zeros 12 | /// 13 | /// this 14 | /// Number of zeros 15 | public static void WriteZeros(this BinaryWriter writer, int count) { 16 | if (count <= 0x20) { 17 | for (int i = 0; i < count; i++) 18 | writer.Write((byte)0); 19 | } 20 | else 21 | writer.Write(new byte[count]); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/DbiNamespace.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | 6 | namespace dnlib.DotNet.Pdb.Managed { 7 | sealed class DbiNamespace : ISymbolNamespace { 8 | public string Namespace { get; private set; } 9 | 10 | public DbiNamespace(string ns) { 11 | Namespace = ns; 12 | } 13 | 14 | #region ISymbolNamespace 15 | 16 | public string Name { 17 | get { return Namespace; } 18 | } 19 | 20 | public ISymbolNamespace[] GetNamespaces() { 21 | throw new NotImplementedException(); 22 | } 23 | 24 | public ISymbolVariable[] GetVariables() { 25 | throw new NotImplementedException(); 26 | } 27 | 28 | #endregion 29 | } 30 | } -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Reflection; 4 | using System.Runtime.InteropServices; 5 | 6 | #if THREAD_SAFE 7 | [assembly: AssemblyTitle("dnlib (thread safe)")] 8 | #else 9 | [assembly: AssemblyTitle("dnlib")] 10 | #endif 11 | [assembly: AssemblyDescription(".NET assembly reader/writer")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("dnlib")] 15 | [assembly: AssemblyCopyright("Copyright (C) 2012-2015 de4dot@gmail.com")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | [assembly: ComVisible(false)] 19 | [assembly: AssemblyVersion("1.5.0.1500")] 20 | [assembly: AssemblyFileVersion("1.5.0.1500")] 21 | -------------------------------------------------------------------------------- /src/W32Resources/ResourceDirectoryEntry.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.W32Resources { 4 | /// 5 | /// Base class of and 6 | /// 7 | public abstract class ResourceDirectoryEntry { 8 | ResourceName name; 9 | 10 | /// 11 | /// Gets/sets the name 12 | /// 13 | public ResourceName Name { 14 | get { return name; } 15 | set { name = value; } 16 | } 17 | 18 | /// 19 | /// Constructor 20 | /// 21 | /// Name 22 | protected ResourceDirectoryEntry(ResourceName name) { 23 | this.name = name; 24 | } 25 | 26 | /// 27 | public override string ToString() { 28 | return name.ToString(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/SymbolDocumentWriter.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | 6 | namespace dnlib.DotNet.Pdb.Dss { 7 | sealed class SymbolDocumentWriter : ISymbolDocumentWriter { 8 | readonly ISymUnmanagedDocumentWriter writer; 9 | 10 | public ISymUnmanagedDocumentWriter SymUnmanagedDocumentWriter { 11 | get { return writer; } 12 | } 13 | 14 | public SymbolDocumentWriter(ISymUnmanagedDocumentWriter writer) { 15 | this.writer = writer; 16 | } 17 | 18 | public void SetCheckSum(Guid algorithmId, byte[] checkSum) { 19 | writer.SetCheckSum(algorithmId, (uint)(checkSum == null ? 0 : checkSum.Length), checkSum); 20 | } 21 | 22 | public void SetSource(byte[] source) { 23 | writer.SetSource((uint)source.Length, source); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DotNet/MethodSemanticsAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Method semantics flags, see CorHdr.h/CorMethodSemanticsAttr 8 | /// 9 | [Flags] 10 | public enum MethodSemanticsAttributes : ushort { 11 | /// No bit is set 12 | None = 0, 13 | /// Setter for property 14 | Setter = 0x0001, 15 | /// Getter for property 16 | Getter = 0x0002, 17 | /// other method for property or event 18 | Other = 0x0004, 19 | /// AddOn method for event 20 | AddOn = 0x0008, 21 | /// RemoveOn method for event 22 | RemoveOn = 0x0010, 23 | /// Fire method for event 24 | Fire = 0x0020, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/PdbException.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.Pdb.Managed { 6 | /// 7 | /// Exception that is thrown when encounters an error. 8 | /// 9 | [Serializable] 10 | public sealed class PdbException : Exception { 11 | /// 12 | /// Constructor 13 | /// 14 | /// Exception message 15 | public PdbException(string message) 16 | : base("Failed to read PDB: " + message) { 17 | } 18 | 19 | /// 20 | /// Constructor 21 | /// 22 | /// Inner exception 23 | public PdbException(Exception innerException) 24 | : base("Failed to read PDB: " + innerException.Message, innerException) { 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/PE/RVA.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.PE { 4 | /// 5 | /// Represents an RVA (relative virtual address) 6 | /// 7 | public enum RVA : uint { 8 | } 9 | 10 | partial class PEExtensions { 11 | /// 12 | /// Align up 13 | /// 14 | /// this 15 | /// Alignment 16 | public static RVA AlignUp(this RVA rva, uint alignment) { 17 | return (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); 18 | } 19 | 20 | /// 21 | /// Align up 22 | /// 23 | /// this 24 | /// Alignment 25 | public static RVA AlignUp(this RVA rva, int alignment) { 26 | return (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DotNet/MD/MDStreamFlags.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.MD { 6 | /// 7 | /// MDStream flags 8 | /// 9 | [Flags] 10 | public enum MDStreamFlags : byte { 11 | /// #Strings stream is big and requires 4 byte offsets 12 | BigStrings = 1, 13 | /// #GUID stream is big and requires 4 byte offsets 14 | BigGUID = 2, 15 | /// #Blob stream is big and requires 4 byte offsets 16 | BigBlob = 4, 17 | /// 18 | Padding = 8, 19 | /// 20 | DeltaOnly = 0x20, 21 | /// Extra data follows the row counts 22 | ExtraData = 0x40, 23 | /// Set if certain tables can contain deleted rows. The name column (if present) is set to "_Deleted" 24 | HasDelete = 0x80, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DotNet/MemberMDInitializer.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | using dnlib.Threading; 5 | 6 | namespace dnlib.DotNet { 7 | /// 8 | /// Methods to load properties to make sure they're initialized 9 | /// 10 | static class MemberMDInitializer { 11 | /// 12 | /// Read every collection element 13 | /// 14 | /// Collection element type 15 | /// Collection 16 | public static void Initialize(IEnumerable coll) { 17 | if (coll == null) 18 | return; 19 | foreach (var c in coll.GetSafeEnumerable()) { 20 | } 21 | } 22 | 23 | /// 24 | /// Load the object instance 25 | /// 26 | /// The value (ignored) 27 | public static void Initialize(object o) { 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/IO/FileOffset.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.IO { 4 | /// 5 | /// Represents a file offset 6 | /// 7 | public enum FileOffset : long { 8 | } 9 | 10 | partial class IOExtensions { 11 | /// 12 | /// Align up 13 | /// 14 | /// this 15 | /// Alignment 16 | public static FileOffset AlignUp(this FileOffset offset, uint alignment) { 17 | return (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); 18 | } 19 | 20 | /// 21 | /// Align up 22 | /// 23 | /// this 24 | /// Alignment 25 | public static FileOffset AlignUp(this FileOffset offset, int alignment) { 26 | return (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/PE/IPEType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using dnlib.IO; 4 | 5 | namespace dnlib.PE { 6 | /// 7 | /// Converts a to/from an 8 | /// 9 | interface IPEType { 10 | /// 11 | /// Converts a to an 12 | /// 13 | /// The PEInfo context 14 | /// The file offset to convert 15 | /// The RVA 16 | RVA ToRVA(PEInfo peInfo, FileOffset offset); 17 | 18 | /// 19 | /// Converts an to a 20 | /// 21 | /// The PEInfo context 22 | /// The RVA to convert 23 | /// The file offset 24 | FileOffset ToFileOffset(PEInfo peInfo, RVA rva); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Examples/GetILAsByteArray.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | 5 | class MyClass { 6 | //static void aaa(string[] args) { 7 | // //load file 8 | // ModuleDefMD mod = ModuleDefMD.Load("Target.exe"); 9 | // //grab only app types 10 | // foreach (var t in mod.GetTypes(true)) { 11 | // Console.WriteLine($"Type :{t.Name}"); 12 | // //grab only method with CilBody 13 | // foreach (var m in t.Methods(true)) { 14 | // Console.WriteLine($" Method :{m.Name}"); 15 | 16 | // Console.WriteLine($" CilBody :"); 17 | 18 | // //iterate in CilBoddy as byte[] 19 | // foreach (var item in m.Body.GetILAsByteArray()) { 20 | // Console.WriteLine(" {" + item + "} , "); 21 | // } 22 | 23 | // } 24 | // } 25 | 26 | // Console.ReadKey(); 27 | //} 28 | } -------------------------------------------------------------------------------- /src/DotNet/Writer/ModuleWriterException.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.Writer { 6 | /// 7 | /// Thrown when the module writer encounters an unrecoverable error 8 | /// 9 | [Serializable] 10 | public class ModuleWriterException : Exception { 11 | /// 12 | /// Default constructor 13 | /// 14 | public ModuleWriterException() { 15 | } 16 | 17 | /// 18 | /// Constructor 19 | /// 20 | /// Error message 21 | public ModuleWriterException(string message) 22 | : base(message) { 23 | } 24 | 25 | /// 26 | /// Constructor 27 | /// 28 | /// Error message 29 | /// Other exception 30 | public ModuleWriterException(string message, Exception innerException) 31 | : base(message, innerException) { 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNet/Emit/InvalidMethodException.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.Emit { 6 | /// 7 | /// Thrown when invalid data is detected while parsing a .NET method 8 | /// 9 | [Serializable] 10 | public class InvalidMethodException : Exception { 11 | /// 12 | /// Default constructor 13 | /// 14 | public InvalidMethodException() { 15 | } 16 | 17 | /// 18 | /// Constructor 19 | /// 20 | /// Error message 21 | public InvalidMethodException(string msg) 22 | : base(msg) { 23 | } 24 | 25 | /// 26 | /// Constructor 27 | /// 28 | /// Error message 29 | /// The inner exception or null if none 30 | public InvalidMethodException(string msg, Exception innerException) 31 | : base(msg, innerException) { 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNet/MethodOverride.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Describes which method some method implements 6 | /// 7 | public struct MethodOverride { 8 | /// 9 | /// The method body. Usually a but could be a 10 | /// 11 | public IMethodDefOrRef MethodBody; 12 | 13 | /// 14 | /// The method implements 15 | /// 16 | public IMethodDefOrRef MethodDeclaration; 17 | 18 | /// 19 | /// Constructor 20 | /// 21 | /// Method body 22 | /// The method implements 23 | public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration) { 24 | this.MethodBody = methodBody; 25 | this.MethodDeclaration = methodDeclaration; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNet/GenericParamAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Generic parameter flags. See CorHdr.h/CorGenericParamAttr 8 | /// 9 | [Flags] 10 | public enum GenericParamAttributes : ushort { 11 | /// 12 | VarianceMask = 0x0003, 13 | /// 14 | NonVariant = 0x0000, 15 | /// 16 | Covariant = 0x0001, 17 | /// 18 | Contravariant = 0x0002, 19 | 20 | /// 21 | SpecialConstraintMask = 0x001C, 22 | /// 23 | NoSpecialConstraint = 0x0000, 24 | /// type argument must be a reference type 25 | ReferenceTypeConstraint = 0x0004, 26 | /// type argument must be a value type but not Nullable 27 | NotNullableValueTypeConstraint = 0x0008, 28 | /// type argument must have a public default constructor 29 | DefaultConstructorConstraint = 0x0010, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/DotNet/Resources/ResourceElementSet.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace dnlib.DotNet.Resources { 7 | /// 8 | /// Resource element set 9 | /// 10 | public sealed class ResourceElementSet { 11 | readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); 12 | 13 | /// 14 | /// Gets the number of elements in the set 15 | /// 16 | public int Count { 17 | get { return dict.Count; } 18 | } 19 | 20 | /// 21 | /// Gets all resource elements 22 | /// 23 | public IEnumerable ResourceElements { 24 | get { return dict.Values; } 25 | } 26 | 27 | /// 28 | /// Adds a new resource to the set, overwriting any existing resource 29 | /// 30 | /// 31 | public void Add(ResourceElement elem) { 32 | dict[elem.Name] = elem; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/PE/PEExtensions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | 5 | namespace dnlib.PE { 6 | /// 7 | /// Extension methods 8 | /// 9 | public static partial class PEExtensions { 10 | /// 11 | /// Calculates a PE checksum 12 | /// 13 | /// Reader 14 | /// Length of image 15 | /// Offset of checksum 16 | /// PE checksum 17 | internal static uint CalculatePECheckSum(this BinaryReader reader, long length, long checkSumOffset) { 18 | uint checkSum = 0; 19 | for (long i = 0; i < length; i += 2) { 20 | if (i == checkSumOffset) { 21 | reader.ReadUInt32(); 22 | i += 2; 23 | continue; 24 | } 25 | checkSum += reader.ReadUInt16(); 26 | checkSum = (ushort)(checkSum + (checkSum >> 16)); 27 | } 28 | ulong cks = (ulong)checkSum + (ulong)length; 29 | return (uint)cks + (uint)(cks >> 32); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/DotNet/Resources/IResourceData.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using System.Runtime.Serialization; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.DotNet.Resources { 8 | /// 9 | /// Implemented by all resource data 10 | /// 11 | public interface IResourceData : IFileSection { 12 | /// 13 | /// Gets the type of data 14 | /// 15 | ResourceTypeCode Code { get; } 16 | 17 | /// 18 | /// Start offset of the section in the file 19 | /// 20 | new FileOffset StartOffset { get; set; } 21 | 22 | /// 23 | /// End offset of the section in the file. This is one byte after the last 24 | /// valid offset in the section. 25 | /// 26 | new FileOffset EndOffset { get; set; } 27 | 28 | /// 29 | /// Writes the data 30 | /// 31 | /// Writer 32 | /// Formatter if needed by implementer 33 | void WriteData(BinaryWriter writer, IFormatter formatter); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/DotNet/Resources/UserResourceType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Resources { 4 | /// 5 | /// User resource type 6 | /// 7 | public sealed class UserResourceType { 8 | readonly string name; 9 | readonly ResourceTypeCode code; 10 | 11 | /// 12 | /// Full name including assembly of type 13 | /// 14 | public string Name { 15 | get { return name; } 16 | } 17 | 18 | /// 19 | /// User type code 20 | /// 21 | public ResourceTypeCode Code { 22 | get { return code; } 23 | } 24 | 25 | /// 26 | /// Constructor 27 | /// 28 | /// Full name including assembly of type 29 | /// User type code 30 | public UserResourceType(string name, ResourceTypeCode code) { 31 | this.name = name; 32 | this.code = code; 33 | } 34 | 35 | /// 36 | public override string ToString() { 37 | return string.Format("{0:X2} {1}", (int)code, name); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Examples/Program.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Reflection; 7 | 8 | namespace dnlib.Examples { 9 | class Program { 10 | static void Main(string[] args) { 11 | ModuleDefMD mod = ModuleDefMD.Load("Target.exe"); 12 | foreach (var t in mod.GetTypes(true)) { 13 | Console.WriteLine($"Type :{t.Name}"); 14 | foreach (var m in t.Methods(true)) { 15 | Console.WriteLine($" Method :{m.Name}"); 16 | 17 | Console.WriteLine($" CilBody :"); 18 | 19 | foreach (var item in m.Body.GetILAsByteArray()) { 20 | Console.WriteLine(" {" + item + "} , "); 21 | } 22 | } 23 | } 24 | 25 | Console.ReadKey(); 26 | } 27 | 28 | 29 | static string testInvoke(string msg) { 30 | Console.WriteLine(msg); 31 | return "ok"; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNet/ITokenResolver.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Resolves tokens 6 | /// 7 | public interface ITokenResolver { 8 | /// 9 | /// Resolves a token 10 | /// 11 | /// The metadata token 12 | /// Generic parameter context 13 | /// A or null if is invalid 14 | IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext); 15 | } 16 | 17 | public static partial class Extensions { 18 | /// 19 | /// Resolves a token 20 | /// 21 | /// This 22 | /// The metadata token 23 | /// A or null if is invalid 24 | public static IMDTokenProvider ResolveToken(this ITokenResolver self, uint token) { 25 | return self.ResolveToken(token, new GenericParamContext()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/SymbolWriterCreator.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | 5 | namespace dnlib.DotNet.Pdb { 6 | /// 7 | /// Creates a 8 | /// 9 | public static class SymbolWriterCreator { 10 | /// 11 | /// Creates a new instance 12 | /// 13 | /// PDB file name 14 | /// A new instance 15 | public static ISymbolWriter2 Create(string pdbFileName) { 16 | return Dss.SymbolWriterCreator.Create(pdbFileName); 17 | } 18 | 19 | /// 20 | /// Creates a new instance 21 | /// 22 | /// PDB output stream 23 | /// PDB file name 24 | /// A new instance 25 | public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) { 26 | return Dss.SymbolWriterCreator.Create(pdbStream, pdbFileName); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DotNet/PublicKeyToken.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Represents a public key token 6 | /// 7 | public sealed class PublicKeyToken : PublicKeyBase { 8 | /// 9 | /// Gets the 10 | /// 11 | public override PublicKeyToken Token { 12 | get { return this; } 13 | } 14 | 15 | /// 16 | public PublicKeyToken() 17 | : base() { 18 | } 19 | 20 | /// 21 | public PublicKeyToken(byte[] data) 22 | : base(data) { 23 | } 24 | 25 | /// 26 | public PublicKeyToken(string hexString) 27 | : base(hexString) { 28 | } 29 | 30 | /// 31 | public override bool Equals(object obj) { 32 | if ((object)this == obj) 33 | return true; 34 | var other = obj as PublicKeyToken; 35 | if (other == null) 36 | return false; 37 | return Utils.Equals(Data, other.Data); 38 | } 39 | 40 | /// 41 | public override int GetHashCode() { 42 | return Utils.GetHashCode(Data); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/DotNet/NullResolver.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// A resolver that always fails 6 | /// 7 | public sealed class NullResolver : IAssemblyResolver, IResolver { 8 | /// 9 | /// The one and only instance of this type 10 | /// 11 | public static readonly NullResolver Instance = new NullResolver(); 12 | 13 | NullResolver() { 14 | } 15 | 16 | /// 17 | public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { 18 | return null; 19 | } 20 | 21 | /// 22 | public bool AddToCache(AssemblyDef asm) { 23 | return true; 24 | } 25 | 26 | /// 27 | public bool Remove(AssemblyDef asm) { 28 | return false; 29 | } 30 | 31 | /// 32 | public void Clear() { 33 | } 34 | 35 | /// 36 | public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { 37 | return null; 38 | } 39 | 40 | /// 41 | public IMemberForwarded Resolve(MemberRef memberRef) { 42 | return null; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/PE/ImageDosHeader.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using dnlib.IO; 5 | 6 | namespace dnlib.PE { 7 | /// 8 | /// Represents the IMAGE_DOS_HEADER PE section 9 | /// 10 | public sealed class ImageDosHeader : FileSection { 11 | readonly uint ntHeadersOffset; 12 | 13 | /// 14 | /// File offset of the NT headers 15 | /// 16 | public uint NTHeadersOffset { 17 | get { return ntHeadersOffset; } 18 | } 19 | 20 | /// 21 | /// Constructor 22 | /// 23 | /// PE file reader 24 | /// Verify section 25 | /// Thrown if verification fails 26 | public ImageDosHeader(IImageStream reader, bool verify) { 27 | SetStartOffset(reader); 28 | ushort sig = reader.ReadUInt16(); 29 | if (verify && sig != 0x5A4D) 30 | throw new BadImageFormatException("Invalid DOS signature"); 31 | reader.Position = (long)startOffset + 0x3C; 32 | this.ntHeadersOffset = reader.ReadUInt32(); 33 | SetEndoffset(reader); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/DotNet/AllTypesHelper.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | using dnlib.Threading; 5 | 6 | namespace dnlib.DotNet { 7 | /// 8 | /// Returns types without getting stuck in an infinite loop 9 | /// 10 | public struct AllTypesHelper { 11 | /// 12 | /// Gets a list of all types and nested types 13 | /// 14 | /// A list of types 15 | public static IEnumerable Types(IEnumerable types) { 16 | var visited = new Dictionary(); 17 | var stack = new Stack>(); 18 | if (types != null) 19 | stack.Push(types.GetSafeEnumerable().GetEnumerator()); 20 | while (stack.Count > 0) { 21 | var enumerator = stack.Pop(); 22 | while (enumerator.MoveNext()) { 23 | var type = enumerator.Current; 24 | if (visited.ContainsKey(type)) 25 | continue; 26 | visited[type] = true; 27 | yield return type; 28 | if (type.NestedTypes.Count > 0) { 29 | stack.Push(enumerator); 30 | enumerator = type.NestedTypes.GetSafeEnumerable().GetEnumerator(); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/DotNet/MD/IRowReaders.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.MD { 4 | /// 5 | /// Reads metadata table columns 6 | /// 7 | public interface IColumnReader { 8 | /// 9 | /// Reads a column 10 | /// 11 | /// The table to read from 12 | /// Table row id 13 | /// The column to read 14 | /// Result 15 | /// true if was updated, false if 16 | /// the column should be read from the original table. 17 | bool ReadColumn(MDTable table, uint rid, ColumnInfo column, out uint value); 18 | } 19 | 20 | /// 21 | /// Reads table rows 22 | /// 23 | /// Raw row 24 | public interface IRowReader where TRow : class, IRawRow { 25 | /// 26 | /// Reads a table row 27 | /// 28 | /// Row id 29 | /// The table row or null if its row should be read from the original 30 | /// table 31 | TRow ReadRow(uint rid); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/PE/Subsystem.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.PE { 4 | /// 5 | /// IMAGE_OPTIONAL_HEADER.Subsystem 6 | /// 7 | public enum Subsystem : ushort { 8 | /// Unknown subsystem. 9 | Unknown = 0, 10 | /// Image doesn't require a subsystem. 11 | Native = 1, 12 | /// Image runs in the Windows GUI subsystem. 13 | WindowsGui = 2, 14 | /// Image runs in the Windows character subsystem. 15 | WindowsCui = 3, 16 | /// image runs in the OS/2 character subsystem. 17 | Os2Cui = 5, 18 | /// image runs in the Posix character subsystem. 19 | PosixCui = 7, 20 | /// image is a native Win9x driver. 21 | NativeWindows = 8, 22 | /// Image runs in the Windows CE subsystem. 23 | WindowsCeGui = 9, 24 | /// 25 | EfiApplication = 10, 26 | /// 27 | EfiBootServiceDriver = 11, 28 | /// 29 | EfiRuntimeDriver = 12, 30 | /// 31 | EfiRom = 13, 32 | /// 33 | Xbox = 14, 34 | /// 35 | WindowsBootApplication = 16, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/DotNet/Writer/ImportAddressTable.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// Import address table chunk 10 | /// 11 | public sealed class ImportAddressTable : IChunk { 12 | FileOffset offset; 13 | RVA rva; 14 | 15 | /// 16 | /// Gets/sets the 17 | /// 18 | public ImportDirectory ImportDirectory { get; set; } 19 | 20 | /// 21 | public FileOffset FileOffset { 22 | get { return offset; } 23 | } 24 | 25 | /// 26 | public RVA RVA { 27 | get { return rva; } 28 | } 29 | 30 | /// 31 | public void SetOffset(FileOffset offset, RVA rva) { 32 | this.offset = offset; 33 | this.rva = rva; 34 | } 35 | 36 | /// 37 | public uint GetFileLength() { 38 | return 8; 39 | } 40 | 41 | /// 42 | public uint GetVirtualSize() { 43 | return GetFileLength(); 44 | } 45 | 46 | /// 47 | public void WriteTo(BinaryWriter writer) { 48 | writer.Write((uint)ImportDirectory.CorXxxMainRVA); 49 | writer.Write(0); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/DotNet/MD/ComImageFlags.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet.MD { 6 | /// 7 | /// See COMIMAGE_FLAGS_XXX in CorHdr.h in the Windows SDK 8 | /// 9 | [Flags] 10 | public enum ComImageFlags : uint { 11 | /// 12 | /// See COMIMAGE_FLAGS_ILONLY in the Windows SDK 13 | /// 14 | ILOnly = 1, 15 | 16 | /// 17 | /// See COMIMAGE_FLAGS_32BITREQUIRED in the Windows SDK 18 | /// 19 | _32BitRequired = 2, 20 | 21 | /// 22 | /// Set if a native header exists (COMIMAGE_FLAGS_IL_LIBRARY) 23 | /// 24 | ILLibrary = 4, 25 | 26 | /// 27 | /// See COMIMAGE_FLAGS_STRONGNAMESIGNED in the Windows SDK 28 | /// 29 | StrongNameSigned = 8, 30 | 31 | /// 32 | /// See COMIMAGE_FLAGS_NATIVE_ENTRYPOINT in the Windows SDK 33 | /// 34 | NativeEntryPoint = 0x10, 35 | 36 | /// 37 | /// See COMIMAGE_FLAGS_TRACKDEBUGDATA in the Windows SDK 38 | /// 39 | TrackDebugData = 0x10000, 40 | 41 | /// 42 | /// See COMIMAGE_FLAGS_32BITPREFERRED in the Windows SDK 43 | /// 44 | _32BitPreferred = 0x20000, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/DotNet/Writer/StrongNameSignature.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// Strong name signature chunk 10 | /// 11 | public sealed class StrongNameSignature : IChunk { 12 | FileOffset offset; 13 | RVA rva; 14 | int size; 15 | 16 | /// 17 | public FileOffset FileOffset { 18 | get { return offset; } 19 | } 20 | 21 | /// 22 | public RVA RVA { 23 | get { return rva; } 24 | } 25 | 26 | /// 27 | /// Constructor 28 | /// 29 | /// Size of strong name signature 30 | public StrongNameSignature(int size) { 31 | this.size = size; 32 | } 33 | 34 | /// 35 | public void SetOffset(FileOffset offset, RVA rva) { 36 | this.offset = offset; 37 | this.rva = rva; 38 | } 39 | 40 | /// 41 | public uint GetFileLength() { 42 | return (uint)this.size; 43 | } 44 | 45 | /// 46 | public uint GetVirtualSize() { 47 | return GetFileLength(); 48 | } 49 | 50 | /// 51 | public void WriteTo(BinaryWriter writer) { 52 | writer.WriteZeros(size); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/SequencePoint.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics; 4 | 5 | namespace dnlib.DotNet.Pdb { 6 | /// 7 | /// PDB sequence point 8 | /// 9 | [DebuggerDisplay("({StartLine}, {StartColumn}) - ({EndLine}, {EndColumn}) {Document.Url}")] 10 | public sealed class SequencePoint { 11 | /// 12 | /// PDB document 13 | /// 14 | public PdbDocument Document { get; set; } 15 | 16 | /// 17 | /// Start line 18 | /// 19 | public int StartLine { get; set; } 20 | 21 | /// 22 | /// Start column 23 | /// 24 | public int StartColumn { get; set; } 25 | 26 | /// 27 | /// End line 28 | /// 29 | public int EndLine { get; set; } 30 | 31 | /// 32 | /// End column 33 | /// 34 | public int EndColumn { get; set; } 35 | 36 | /// 37 | /// Clones this instance 38 | /// 39 | /// A new cloned instance 40 | public SequencePoint Clone() { 41 | return new SequencePoint() { 42 | Document = Document, 43 | StartLine = StartLine, 44 | StartColumn = StartColumn, 45 | EndLine = EndLine, 46 | EndColumn = EndColumn, 47 | }; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/DotNet/MD/GuidStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using dnlib.IO; 5 | 6 | namespace dnlib.DotNet.MD { 7 | /// 8 | /// Represents the #GUID stream 9 | /// 10 | public sealed class GuidStream : HeapStream { 11 | /// 12 | public GuidStream() { 13 | } 14 | 15 | /// 16 | public GuidStream(IImageStream imageStream, StreamHeader streamHeader) 17 | : base(imageStream, streamHeader) { 18 | } 19 | 20 | /// 21 | public override bool IsValidIndex(uint index) { 22 | return index == 0 || (index <= 0x10000000 && IsValidOffset((index - 1) * 16, 16)); 23 | } 24 | 25 | /// 26 | /// Read a 27 | /// 28 | /// Index into this stream 29 | /// A or null if is 0 or invalid 30 | public Guid? Read(uint index) { 31 | if (index == 0 || !IsValidIndex(index)) 32 | return null; 33 | #if THREAD_SAFE 34 | theLock.EnterWriteLock(); try { 35 | #endif 36 | var reader = GetReader_NoLock((index - 1) * 16); 37 | return new Guid(reader.ReadBytes(16)); 38 | #if THREAD_SAFE 39 | } finally { theLock.ExitWriteLock(); } 40 | #endif 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/DotNet/Writer/WriterUtils.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | 5 | namespace dnlib.DotNet.Writer { 6 | static class WriterUtils { 7 | public static uint WriteCompressedUInt32(this BinaryWriter writer, IWriterError helper, uint value) { 8 | if (value > 0x1FFFFFFF) { 9 | helper.Error("UInt32 value is too big and can't be compressed"); 10 | value = 0x1FFFFFFF; 11 | } 12 | writer.WriteCompressedUInt32(value); 13 | return value; 14 | } 15 | 16 | public static int WriteCompressedInt32(this BinaryWriter writer, IWriterError helper, int value) { 17 | if (value < -0x10000000) { 18 | helper.Error("Int32 value is too small and can't be compressed."); 19 | value = -0x10000000; 20 | } 21 | else if (value > 0x0FFFFFFF) { 22 | helper.Error("Int32 value is too big and can't be compressed."); 23 | value = 0x0FFFFFFF; 24 | } 25 | writer.WriteCompressedInt32(value); 26 | return value; 27 | } 28 | 29 | public static void Write(this BinaryWriter writer, IWriterError helper, UTF8String s) { 30 | if (UTF8String.IsNull(s)) { 31 | helper.Error("UTF8String is null"); 32 | s = UTF8String.Empty; 33 | } 34 | 35 | writer.WriteCompressedUInt32(helper, (uint)s.DataLength); 36 | writer.Write(s.Data); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DotNet/Writer/RelocDirectory.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// Relocations directory 10 | /// 11 | public sealed class RelocDirectory : IChunk { 12 | FileOffset offset; 13 | RVA rva; 14 | 15 | /// 16 | /// Gets/sets the 17 | /// 18 | public StartupStub StartupStub { get; set; } 19 | 20 | /// 21 | public FileOffset FileOffset { 22 | get { return offset; } 23 | } 24 | 25 | /// 26 | public RVA RVA { 27 | get { return rva; } 28 | } 29 | 30 | /// 31 | public void SetOffset(FileOffset offset, RVA rva) { 32 | this.offset = offset; 33 | this.rva = rva; 34 | } 35 | 36 | /// 37 | public uint GetFileLength() { 38 | return 12; 39 | } 40 | 41 | /// 42 | public uint GetVirtualSize() { 43 | return GetFileLength(); 44 | } 45 | 46 | /// 47 | public void WriteTo(BinaryWriter writer) { 48 | uint rva = (uint)StartupStub.RelocRVA; 49 | writer.Write(rva & ~0xFFFU); 50 | writer.Write(12); 51 | writer.Write((ushort)(0x3000 | (rva & 0xFFF))); 52 | writer.Write((ushort)0); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Examples/Example5.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using dnlib.DotNet; 4 | using dnlib.PE; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.Examples { 8 | /// 9 | /// Dumps all PE sections to disk 10 | /// 11 | public class Example5 { 12 | public static void Run() { 13 | string sectionFileName = @"c:\section{0}.bin"; 14 | 15 | // Open the current mscorlib 16 | var mod = ModuleDefMD.Load(typeof(int).Module); 17 | 18 | // Get PE image interface 19 | var peImage = mod.MetaData.PEImage; 20 | 21 | // Print some info 22 | Console.WriteLine("Machine: {0}", peImage.ImageNTHeaders.FileHeader.Machine); 23 | Console.WriteLine("Characteristics: {0}", peImage.ImageNTHeaders.FileHeader.Characteristics); 24 | 25 | Console.WriteLine("Dumping all sections"); 26 | for (int i = 0; i < peImage.ImageSectionHeaders.Count; i++) { 27 | var section = peImage.ImageSectionHeaders[i]; 28 | 29 | // Create a stream for the whole section 30 | var stream = peImage.CreateStream(section.VirtualAddress, section.SizeOfRawData); 31 | 32 | // Write the data to disk 33 | var fileName = string.Format(sectionFileName, i); 34 | Console.WriteLine("Dumping section {0} to file {1}", section.DisplayName, fileName); 35 | File.WriteAllBytes(fileName, stream.ReadAllBytes()); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DotNet/CallingConvention.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// See CorHdr.h/CorCallingConvention 8 | /// 9 | [Flags] 10 | public enum CallingConvention : byte { 11 | /// The managed calling convention 12 | Default = 0x0, 13 | /// 14 | C = 0x1, 15 | /// 16 | StdCall = 0x2, 17 | /// 18 | ThisCall = 0x3, 19 | /// 20 | FastCall = 0x4, 21 | /// 22 | VarArg = 0x5, 23 | /// 24 | Field = 0x6, 25 | /// 26 | LocalSig = 0x7, 27 | /// 28 | Property = 0x8, 29 | /// 30 | Unmanaged = 0x9, 31 | /// generic method instantiation 32 | GenericInst = 0xA, 33 | /// used ONLY for 64bit vararg PInvoke calls 34 | NativeVarArg = 0xB, 35 | 36 | /// Calling convention is bottom 4 bits 37 | Mask = 0x0F, 38 | 39 | /// Generic method 40 | Generic = 0x10, 41 | /// Method needs a 'this' parameter 42 | HasThis = 0x20, 43 | /// 'this' parameter is the first arg if set (else it's hidden) 44 | ExplicitThis = 0x40, 45 | /// Used internally by the CLR 46 | ReservedByCLR = 0x80, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DotNet/Writer/IOffsetHeap.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | 5 | namespace dnlib.DotNet.Writer { 6 | /// 7 | /// Interface to get and set raw heap data. Implemented by the offset heaps: #Strings, 8 | /// #GUID, #Blob, and #US. 9 | /// 10 | /// Type of cooked data 11 | public interface IOffsetHeap { 12 | /// 13 | /// Gets the size of the data as raw data when written to the heap 14 | /// 15 | /// The data 16 | /// Size of the data as raw data when written to the heap 17 | int GetRawDataSize(TValue data); 18 | 19 | /// 20 | /// Overrides what value should be written to the heap. 21 | /// 22 | /// Offset of value. Must match an offset returned by 23 | /// 24 | /// The new raw data. The size must match the raw size exactly. 25 | void SetRawData(uint offset, byte[] rawData); 26 | 27 | /// 28 | /// Gets all inserted raw data and their offsets. The returned array 29 | /// is owned by the caller. 30 | /// 31 | /// An enumerable of all raw data and their offsets 32 | IEnumerable> GetAllRawData(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DotNet/Emit/StackBehaviour.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Emit { 4 | /// 5 | /// CIL opcode stack behavior 6 | /// 7 | public enum StackBehaviour : byte { 8 | /// 9 | Pop0, 10 | /// 11 | Pop1, 12 | /// 13 | Pop1_pop1, 14 | /// 15 | Popi, 16 | /// 17 | Popi_pop1, 18 | /// 19 | Popi_popi, 20 | /// 21 | Popi_popi8, 22 | /// 23 | Popi_popi_popi, 24 | /// 25 | Popi_popr4, 26 | /// 27 | Popi_popr8, 28 | /// 29 | Popref, 30 | /// 31 | Popref_pop1, 32 | /// 33 | Popref_popi, 34 | /// 35 | Popref_popi_popi, 36 | /// 37 | Popref_popi_popi8, 38 | /// 39 | Popref_popi_popr4, 40 | /// 41 | Popref_popi_popr8, 42 | /// 43 | Popref_popi_popref, 44 | /// 45 | Push0, 46 | /// 47 | Push1, 48 | /// 49 | Push1_push1, 50 | /// 51 | Pushi, 52 | /// 53 | Pushi8, 54 | /// 55 | Pushr4, 56 | /// 57 | Pushr8, 58 | /// 59 | Pushref, 60 | /// 61 | Varpop, 62 | /// 63 | Varpush, 64 | /// 65 | Popref_popi_pop1, 66 | /// 67 | PopAll = 0xFF, 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | dnlib: .NET assembly library 2 | https://github.com/0xd4d/dnlib 3 | 4 | Copyright (C) 2012-2015 de4dot@gmail.com 5 | 6 | Contributors 7 | ------------ 8 | 9 | Ki, "yck1509 ", https://github.com/yck1509 10 | kiootic, "kiootic ", https://github.com/kiootic 11 | 12 | MIT LICENSE 13 | ----------- 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining 16 | a copy of this software and associated documentation files (the 17 | "Software"), to deal in the Software without restriction, including 18 | without limitation the rights to use, copy, modify, merge, publish, 19 | distribute, sublicense, and/or sell copies of the Software, and to 20 | permit persons to whom the Software is furnished to do so, subject to 21 | the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be 24 | included in all copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 29 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 30 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 31 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 32 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 33 | -------------------------------------------------------------------------------- /src/DotNet/ICustomAttribute.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | 5 | #if THREAD_SAFE 6 | using ThreadSafe = dnlib.Threading.Collections; 7 | #else 8 | using ThreadSafe = System.Collections.Generic; 9 | #endif 10 | 11 | namespace dnlib.DotNet { 12 | /// 13 | /// Custom attribute interface. Implemented by and 14 | /// 15 | /// 16 | public interface ICustomAttribute { 17 | /// 18 | /// Gets the attribute type 19 | /// 20 | ITypeDefOrRef AttributeType { get; } 21 | 22 | /// 23 | /// Gets the full name of the attribute type 24 | /// 25 | string TypeFullName { get; } 26 | 27 | /// 28 | /// Gets all named arguments (field and property values) 29 | /// 30 | ThreadSafe.IList NamedArguments { get; } 31 | 32 | /// 33 | /// true if is not empty 34 | /// 35 | bool HasNamedArguments { get; } 36 | 37 | /// 38 | /// Gets all s that are field arguments 39 | /// 40 | IEnumerable Fields { get; } 41 | 42 | /// 43 | /// Gets all s that are property arguments 44 | /// 45 | IEnumerable Properties { get; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/PE/ImageDataDirectory.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.PE { 8 | /// 9 | /// Represents the IMAGE_DATA_DIRECTORY PE section 10 | /// 11 | [DebuggerDisplay("{virtualAddress} {dataSize}")] 12 | public sealed class ImageDataDirectory : FileSection { 13 | readonly RVA virtualAddress; 14 | readonly uint dataSize; 15 | 16 | /// 17 | /// Returns the IMAGE_DATA_DIRECTORY.VirtualAddress field 18 | /// 19 | public RVA VirtualAddress { 20 | get { return virtualAddress; } 21 | } 22 | 23 | /// 24 | /// Returns the IMAGE_DATA_DIRECTORY.Size field 25 | /// 26 | public uint Size { 27 | get { return dataSize; } 28 | } 29 | 30 | /// 31 | /// Default constructor 32 | /// 33 | public ImageDataDirectory() { 34 | } 35 | 36 | /// 37 | /// Constructor 38 | /// 39 | /// PE file reader pointing to the start of this section 40 | /// Verify section 41 | /// Thrown if verification fails 42 | public ImageDataDirectory(IImageStream reader, bool verify) { 43 | SetStartOffset(reader); 44 | this.virtualAddress = (RVA)reader.ReadUInt32(); 45 | this.dataSize = reader.ReadUInt32(); 46 | SetEndoffset(reader); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/IO/FileSection.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics; 4 | 5 | namespace dnlib.IO { 6 | /// 7 | /// Base class for classes needing to implement IFileSection 8 | /// 9 | [DebuggerDisplay("O:{startOffset} L:{size} {GetType().Name}")] 10 | public class FileSection : IFileSection { 11 | /// 12 | /// The start file offset of this section 13 | /// 14 | protected FileOffset startOffset; 15 | 16 | /// 17 | /// Size of the section 18 | /// 19 | protected uint size; 20 | 21 | /// 22 | public FileOffset StartOffset { 23 | get { return startOffset; } 24 | } 25 | 26 | /// 27 | public FileOffset EndOffset { 28 | get { return startOffset + size; } 29 | } 30 | 31 | /// 32 | /// Set to 's current position 33 | /// 34 | /// The reader 35 | protected void SetStartOffset(IImageStream reader) { 36 | startOffset = (FileOffset)reader.Position; 37 | } 38 | 39 | /// 40 | /// Set according to 's current position 41 | /// 42 | /// The reader 43 | protected void SetEndoffset(IImageStream reader) { 44 | size = (uint)(reader.Position - startOffset); 45 | startOffset = reader.FileOffset + (long)startOffset; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/PE/DllCharacteristics.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.PE { 6 | /// 7 | /// IMAGE_OPTIONAL_HEADER.DllCharacteristics 8 | /// 9 | [Flags] 10 | public enum DllCharacteristics : ushort { 11 | /// 12 | Reserved1 = 0x0001, 13 | /// 14 | Reserved2 = 0x0002, 15 | /// 16 | Reserved3 = 0x0004, 17 | /// 18 | Reserved4 = 0x0008, 19 | /// 20 | Reserved5 = 0x0010, 21 | /// Image can handle a high entropy 64-bit virtual address space. 22 | HighEntropyVA = 0x0020, 23 | /// DLL can move. 24 | DynamicBase = 0x0040, 25 | /// Code Integrity Image 26 | ForceIntegrity = 0x0080, 27 | /// Image is NX compatible 28 | NxCompat = 0x0100, 29 | /// Image understands isolation and doesn't want it 30 | NoIsolation = 0x0200, 31 | /// Image does not use SEH. No SE handler may reside in this image 32 | NoSeh = 0x0400, 33 | /// Do not bind this image. 34 | NoBind = 0x0800, 35 | /// Image should execute in an AppContainer 36 | AppContainer = 0x1000, 37 | /// Driver uses WDM model 38 | WdmDriver = 0x2000, 39 | /// Image supports Control Flow Guard. 40 | GuardCf = 0x4000, 41 | /// 42 | TerminalServerAware = 0x8000, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/DotNet/IDecrypters.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | using dnlib.PE; 5 | using dnlib.DotNet.Emit; 6 | 7 | namespace dnlib.DotNet { 8 | /// 9 | /// Interface to decrypt methods 10 | /// 11 | public interface IMethodDecrypter { 12 | /// 13 | /// Gets the method's body 14 | /// 15 | /// Method rid 16 | /// The found in the method's Method row 17 | /// The method's parameters 18 | /// Generic parameter context 19 | /// Updated with the method's if this 20 | /// method returns true 21 | /// true if the method body was decrypted, false if the method isn't 22 | /// encrypted and the default body reader code should be used. 23 | bool GetMethodBody(uint rid, RVA rva, IList parameters, GenericParamContext gpContext, out MethodBody methodBody); 24 | } 25 | 26 | /// 27 | /// Interface to decrypt strings 28 | /// 29 | public interface IStringDecrypter { 30 | /// 31 | /// Reads a string 32 | /// 33 | /// String token 34 | /// A string or null if we should read it from the #US heap 35 | string ReadUserString(uint token); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/SymbolNamespace.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics.SymbolStore; 4 | 5 | namespace dnlib.DotNet.Pdb.Dss { 6 | sealed class SymbolNamespace : ISymbolNamespace { 7 | readonly ISymUnmanagedNamespace ns; 8 | 9 | public SymbolNamespace(ISymUnmanagedNamespace @namespace) { 10 | this.ns = @namespace; 11 | } 12 | 13 | public string Name { 14 | get { 15 | uint count; 16 | ns.GetName(0, out count, null); 17 | var chars = new char[count]; 18 | ns.GetName((uint)chars.Length, out count, chars); 19 | if (chars.Length == 0) 20 | return string.Empty; 21 | return new string(chars, 0, chars.Length - 1); 22 | } 23 | } 24 | 25 | public ISymbolNamespace[] GetNamespaces() { 26 | uint numNss; 27 | ns.GetNamespaces(0, out numNss, null); 28 | var unNss = new ISymUnmanagedNamespace[numNss]; 29 | ns.GetNamespaces((uint)unNss.Length, out numNss, unNss); 30 | var nss = new ISymbolNamespace[numNss]; 31 | for (uint i = 0; i < numNss; i++) 32 | nss[i] = new SymbolNamespace(unNss[i]); 33 | return nss; 34 | } 35 | 36 | public ISymbolVariable[] GetVariables() { 37 | uint numVars; 38 | ns.GetVariables(0, out numVars, null); 39 | var unVars = new ISymUnmanagedVariable[numVars]; 40 | ns.GetVariables((uint)unVars.Length, out numVars, unVars); 41 | var vars = new ISymbolVariable[numVars]; 42 | for (uint i = 0; i < numVars; i++) 43 | vars[i] = new SymbolVariable(unVars[i]); 44 | return vars; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/IO/IImageStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.IO { 4 | /// 5 | /// Interface to access part of some data 6 | /// 7 | public interface IImageStream : IBinaryReader { 8 | /// 9 | /// Returns the file offset of the stream 10 | /// 11 | FileOffset FileOffset { get; } 12 | 13 | /// 14 | /// Creates a sub stream that can access parts of this stream 15 | /// 16 | /// File offset relative to the start of this stream 17 | /// Length 18 | /// A new stream 19 | IImageStream Create(FileOffset offset, long length); 20 | } 21 | 22 | static partial class IOExtensions { 23 | /// 24 | /// Creates a stream that can access all data starting from 25 | /// 26 | /// this 27 | /// Offset relative to the beginning of the stream 28 | /// A new stream 29 | public static IImageStream Create(this IImageStream self, FileOffset offset) { 30 | return self.Create(offset, long.MaxValue); 31 | } 32 | 33 | /// 34 | /// Clones this 35 | /// 36 | /// this 37 | /// A new instance 38 | public static IImageStream Clone(this IImageStream self) { 39 | return self.Create(0, long.MaxValue); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/DbiVariable.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.DotNet.Pdb.Managed { 8 | sealed class DbiVariable : ISymbolVariable { 9 | public uint Addr1 { get; private set; } 10 | public string Name { get; private set; } 11 | public ushort Flags { get; private set; } 12 | 13 | public void Read(IImageStream stream) { 14 | Addr1 = stream.ReadUInt32(); 15 | stream.Position += 10; 16 | Flags = stream.ReadUInt16(); 17 | Name = PdbReader.ReadCString(stream); 18 | } 19 | 20 | #region ISymbolVariable 21 | 22 | public int AddressField1 { 23 | get { return (int)Addr1; } 24 | } 25 | 26 | public SymAddressKind AddressKind { 27 | get { return SymAddressKind.ILOffset; } 28 | } 29 | 30 | public object Attributes { 31 | get { 32 | const int fCompGenx = 4; 33 | const int VAR_IS_COMP_GEN = 1; 34 | if ((Flags & fCompGenx) != 0) 35 | return VAR_IS_COMP_GEN; 36 | else 37 | return 0; 38 | } 39 | } 40 | 41 | public int AddressField2 { 42 | get { throw new NotImplementedException(); } 43 | } 44 | 45 | public int AddressField3 { 46 | get { throw new NotImplementedException(); } 47 | } 48 | 49 | public int EndOffset { 50 | get { throw new NotImplementedException(); } 51 | } 52 | 53 | public byte[] GetSignature() { 54 | throw new NotImplementedException(); 55 | } 56 | 57 | public int StartOffset { 58 | get { throw new NotImplementedException(); } 59 | } 60 | 61 | #endregion 62 | } 63 | } -------------------------------------------------------------------------------- /src/IO/IImageStreamCreator.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.IO { 6 | /// 7 | /// Creates a new stream that accesses part of some data 8 | /// 9 | public interface IImageStreamCreator : IDisposable { 10 | /// 11 | /// The file name or null if data is not from a file 12 | /// 13 | string FileName { get; } 14 | 15 | /// 16 | /// Returns the total length of the original data 17 | /// 18 | long Length { get; } 19 | 20 | /// 21 | /// Creates a stream that can access only part of the data 22 | /// 23 | /// Offset within the original data 24 | /// Length of section within the original data 25 | /// A new stream 26 | IImageStream Create(FileOffset offset, long length); 27 | 28 | /// 29 | /// Creates a stream that can access all data 30 | /// 31 | /// A new stream 32 | IImageStream CreateFull(); 33 | } 34 | 35 | static partial class IOExtensions { 36 | /// 37 | /// Creates a stream that can access all data starting from 38 | /// 39 | /// this 40 | /// Offset within the original data 41 | /// A new stream 42 | public static IImageStream Create(this IImageStreamCreator self, FileOffset offset) { 43 | return self.Create(offset, long.MaxValue); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Examples/Example1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using dnlib.DotNet; 3 | 4 | namespace dnlib.Examples { 5 | // This example will open mscorlib.dll and then print out all types 6 | // in the assembly, including the number of methods, fields, properties 7 | // and events each type has. 8 | public class Example1 { 9 | public static void Run() { 10 | // Load mscorlib.dll 11 | string filename = typeof(void).Module.FullyQualifiedName; 12 | ModuleDefMD mod = ModuleDefMD.Load(filename); 13 | 14 | int totalNumTypes = 0; 15 | // mod.Types only returns non-nested types. 16 | // mod.GetTypes() returns all types, including nested types. 17 | foreach (TypeDef type in mod.GetTypes()) { 18 | totalNumTypes++; 19 | Console.WriteLine(); 20 | Console.WriteLine("Type: {0}", type.FullName); 21 | if (type.BaseType != null) 22 | Console.WriteLine(" Base type: {0}", type.BaseType.FullName); 23 | 24 | Console.WriteLine(" Methods: {0}", type.Methods.Count); 25 | Console.WriteLine(" Fields: {0}", type.Fields.Count); 26 | Console.WriteLine(" Properties: {0}", type.Properties.Count); 27 | Console.WriteLine(" Events: {0}", type.Events.Count); 28 | Console.WriteLine(" Nested types: {0}", type.NestedTypes.Count); 29 | 30 | if (type.Interfaces.Count > 0) { 31 | Console.WriteLine(" Interfaces:"); 32 | foreach (InterfaceImpl iface in type.Interfaces) 33 | Console.WriteLine(" {0}", iface.Interface.FullName); 34 | } 35 | } 36 | Console.WriteLine(); 37 | Console.WriteLine("Total number of types: {0}", totalNumTypes); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/DotNet/MD/StringsStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using dnlib.IO; 4 | 5 | namespace dnlib.DotNet.MD { 6 | /// 7 | /// Represents the #Strings stream 8 | /// 9 | public sealed class StringsStream : HeapStream { 10 | /// 11 | public StringsStream() { 12 | } 13 | 14 | /// 15 | public StringsStream(IImageStream imageStream, StreamHeader streamHeader) 16 | : base(imageStream, streamHeader) { 17 | } 18 | 19 | /// 20 | /// Reads a 21 | /// 22 | /// Offset of string 23 | /// A instance or null if invalid offset 24 | public UTF8String Read(uint offset) { 25 | if (offset >= ImageStreamLength) 26 | return null; 27 | byte[] data; 28 | #if THREAD_SAFE 29 | theLock.EnterWriteLock(); try { 30 | #endif 31 | var reader = GetReader_NoLock(offset); 32 | data = reader.ReadBytesUntilByte(0); 33 | #if THREAD_SAFE 34 | } finally { theLock.ExitWriteLock(); } 35 | #endif 36 | if (data == null) 37 | return null; 38 | return new UTF8String(data); 39 | } 40 | 41 | /// 42 | /// Reads a . The empty string is returned if 43 | /// is invalid. 44 | /// 45 | /// Offset of string 46 | /// A instance 47 | public UTF8String ReadNoNull(uint offset) { 48 | return Read(offset) ?? UTF8String.Empty; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/DotNet/SecurityAction.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Security action. See CorHdr.h/CorDeclSecurity 6 | /// 7 | public enum SecurityAction : short { 8 | /// Mask allows growth of enum. 9 | ActionMask = 0x001F, 10 | /// 11 | ActionNil = 0x0000, 12 | /// 13 | Request = 0x0001, 14 | /// 15 | Demand = 0x0002, 16 | /// 17 | Assert = 0x0003, 18 | /// 19 | Deny = 0x0004, 20 | /// 21 | PermitOnly = 0x0005, 22 | /// 23 | LinktimeCheck = 0x0006, 24 | /// 25 | LinkDemand = LinktimeCheck, 26 | /// 27 | InheritanceCheck = 0x0007, 28 | /// 29 | InheritDemand = InheritanceCheck, 30 | /// 31 | RequestMinimum = 0x0008, 32 | /// 33 | RequestOptional = 0x0009, 34 | /// 35 | RequestRefuse = 0x000A, 36 | /// Persisted grant set at prejit time 37 | PrejitGrant = 0x000B, 38 | /// Persisted grant set at prejit time 39 | PreJitGrant = PrejitGrant, 40 | /// Persisted denied set at prejit time 41 | PrejitDenied = 0x000C, 42 | /// Persisted denied set at prejit time 43 | PreJitDeny = PrejitDenied, 44 | /// 45 | NonCasDemand = 0x000D, 46 | /// 47 | NonCasLinkDemand = 0x000E, 48 | /// 49 | NonCasInheritance = 0x000F, 50 | /// Maximum legal value 51 | MaximumValue = 0x000F, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/DotNet/SerializationType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// See CorSerializationType/CorHdr.h 6 | /// 7 | enum SerializationType : byte { 8 | /// 9 | Undefined = 0, 10 | /// System.Boolean 11 | Boolean = ElementType.Boolean, 12 | /// System.Char 13 | Char = ElementType.Char, 14 | /// System.SByte 15 | I1 = ElementType.I1, 16 | /// System.Byte 17 | U1 = ElementType.U1, 18 | /// System.Int16 19 | I2 = ElementType.I2, 20 | /// System.UInt16 21 | U2 = ElementType.U2, 22 | /// System.Int32 23 | I4 = ElementType.I4, 24 | /// System.UInt32 25 | U4 = ElementType.U4, 26 | /// System.Int64 27 | I8 = ElementType.I8, 28 | /// System.UInt64 29 | U8 = ElementType.U8, 30 | /// System.Single 31 | R4 = ElementType.R4, 32 | /// System.Double 33 | R8 = ElementType.R8, 34 | /// System.String 35 | String = ElementType.String, 36 | /// Single-dimension, zero lower bound array ([]) 37 | SZArray = ElementType.SZArray, 38 | /// System.Type 39 | Type = 0x50, 40 | /// Boxed value type 41 | TaggedObject= 0x51, 42 | /// A field 43 | Field = 0x53, 44 | /// A property 45 | Property = 0x54, 46 | /// An enum 47 | Enum = 0x55, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/DotNet/Writer/ChunkList.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace dnlib.DotNet.Writer { 7 | /// 8 | /// Contains a list of s 9 | /// 10 | public class ChunkList : ChunkListBase where T : class, IChunk { 11 | /// 12 | /// Default constructor 13 | /// 14 | public ChunkList() { 15 | this.chunks = new List(); 16 | } 17 | 18 | /// 19 | /// Add a 20 | /// 21 | /// The chunk to add or null if none 22 | /// Chunk alignment 23 | public void Add(T chunk, uint alignment) { 24 | if (setOffsetCalled) 25 | throw new InvalidOperationException("SetOffset() has already been called"); 26 | if (chunk != null) 27 | chunks.Add(new Elem(chunk, alignment)); 28 | } 29 | 30 | /// 31 | /// Remove a 32 | /// 33 | /// The chunk to remove or null if none 34 | /// Alignment of the chunk, or null if the chunk cannot be removed. 35 | public uint? Remove(T chunk) { 36 | if (setOffsetCalled) 37 | throw new InvalidOperationException("SetOffset() has already been called"); 38 | if (chunk != null) { 39 | for (int i = 0; i < chunks.Count; i++) { 40 | if (chunks[i].chunk == chunk) { 41 | uint alignment = chunks[i].alignment; 42 | chunks.RemoveAt(i); 43 | return alignment; 44 | } 45 | } 46 | } 47 | return null; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/DotNet/RecursionCounter.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Recursion counter 8 | /// 9 | public struct RecursionCounter { 10 | /// 11 | /// Max recursion count. If this is reached, we won't continue, and will use a default value. 12 | /// 13 | public const int MAX_RECURSION_COUNT = 100; 14 | int counter; 15 | 16 | /// 17 | /// Gets the recursion counter 18 | /// 19 | public int Counter { 20 | get { return counter; } 21 | } 22 | 23 | /// 24 | /// Increments if it's not too high. ALL instance methods 25 | /// that can be called recursively must call this method and 26 | /// (if this method returns true) 27 | /// 28 | /// true if it was incremented and caller can continue, false if 29 | /// it was not incremented and the caller must return to its caller. 30 | public bool Increment() { 31 | if (counter >= MAX_RECURSION_COUNT) 32 | return false; 33 | counter++; 34 | return true; 35 | } 36 | 37 | /// 38 | /// Must be called before returning to caller if 39 | /// returned true. 40 | /// 41 | public void Decrement() { 42 | #if DEBUG 43 | if (counter <= 0) 44 | throw new InvalidOperationException("recursionCounter <= 0"); 45 | #endif 46 | counter--; 47 | } 48 | 49 | /// 50 | public override string ToString() { 51 | return counter.ToString(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/DotNet/MethodImplAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Method impl attributes, see CorHdr.h/CorMethodImpl 8 | /// 9 | [Flags] 10 | public enum MethodImplAttributes : ushort { 11 | /// Flags about code type. 12 | CodeTypeMask = 0x0003, 13 | /// Method impl is IL. 14 | IL = 0x0000, 15 | /// Method impl is native. 16 | Native = 0x0001, 17 | /// Method impl is OPTIL 18 | OPTIL = 0x0002, 19 | /// Method impl is provided by the runtime. 20 | Runtime = 0x0003, 21 | 22 | /// Flags specifying whether the code is managed or unmanaged. 23 | ManagedMask = 0x0004, 24 | /// Method impl is unmanaged, otherwise managed. 25 | Unmanaged = 0x0004, 26 | /// Method impl is managed. 27 | Managed = 0x0000, 28 | 29 | /// Indicates method is defined; used primarily in merge scenarios. 30 | ForwardRef = 0x0010, 31 | /// Indicates method sig is not to be mangled to do HRESULT conversion. 32 | PreserveSig = 0x0080, 33 | 34 | /// Reserved for internal use. 35 | InternalCall = 0x1000, 36 | 37 | /// Method is single threaded through the body. 38 | Synchronized = 0x0020, 39 | /// Method may not be inlined. 40 | NoInlining = 0x0008, 41 | /// Method should be inlined if possible. 42 | AggressiveInlining = 0x0100, 43 | /// Method may not be optimized. 44 | NoOptimization = 0x0040, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/SymbolWriterCreator.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.IO; 5 | 6 | namespace dnlib.DotNet.Pdb.Dss { 7 | /// 8 | /// Creates a 9 | /// 10 | public static class SymbolWriterCreator { 11 | static readonly Guid CLSID_CorSymWriter_SxS = new Guid(0x0AE2DEB0, 0xF901, 0x478B, 0xBB, 0x9F, 0x88, 0x1E, 0xE8, 0x06, 0x67, 0x88); 12 | 13 | /// 14 | /// Creates a instance 15 | /// 16 | /// A new instance 17 | public static ISymUnmanagedWriter2 CreateSymUnmanagedWriter2() { 18 | return (ISymUnmanagedWriter2)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS)); 19 | } 20 | 21 | /// 22 | /// Creates a new instance 23 | /// 24 | /// PDB file name 25 | /// A new instance 26 | public static ISymbolWriter2 Create(string pdbFileName) { 27 | if (File.Exists(pdbFileName)) 28 | File.Delete(pdbFileName); 29 | return new SymbolWriter(CreateSymUnmanagedWriter2(), pdbFileName); 30 | } 31 | 32 | /// 33 | /// Creates a new instance 34 | /// 35 | /// PDB output stream 36 | /// PDB file name 37 | /// A new instance 38 | public static ISymbolWriter2 Create(Stream pdbStream, string pdbFileName) { 39 | return new SymbolWriter(CreateSymUnmanagedWriter2(), pdbFileName, pdbStream); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/PE/Characteristics.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.PE { 6 | /// 7 | /// IMAGE_FILE_HEADER.Characteristics flags 8 | /// 9 | [Flags] 10 | public enum Characteristics : ushort { 11 | /// Relocation info stripped from file. 12 | RelocsStripped = 0x0001, 13 | /// File is executable (i.e. no unresolved externel references). 14 | ExecutableImage = 0x0002, 15 | /// Line nunbers stripped from file. 16 | LineNumsStripped = 0x0004, 17 | /// Local symbols stripped from file. 18 | LocalSymsStripped = 0x0008, 19 | /// Agressively trim working set 20 | AggressiveWsTrim = 0x0010, 21 | /// App can handle >2gb addresses 22 | LargeAddressAware = 0x0020, 23 | /// 24 | Reserved1 = 0x0040, 25 | /// Bytes of machine word are reversed. 26 | BytesReversedLo = 0x0080, 27 | /// 32 bit word machine. 28 | _32BitMachine = 0x0100, 29 | /// Debugging info stripped from file in .DBG file 30 | DebugStripped = 0x0200, 31 | /// If Image is on removable media, copy and run from the swap file. 32 | RemovableRunFromSwap= 0x0400, 33 | /// If Image is on Net, copy and run from the swap file. 34 | NetRunFromSwap = 0x0800, 35 | /// System File. 36 | System = 0x1000, 37 | /// File is a DLL. 38 | Dll = 0x2000, 39 | /// File should only be run on a UP machine 40 | UpSystemOnly = 0x4000, 41 | /// Bytes of machine word are reversed. 42 | BytesReversedHi = 0x8000, 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/DotNet/Emit/ExceptionHandler.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Emit { 4 | /// 5 | /// A CIL method exception handler 6 | /// 7 | public sealed class ExceptionHandler { 8 | /// 9 | /// First instruction of try block 10 | /// 11 | public Instruction TryStart; 12 | 13 | /// 14 | /// One instruction past the end of try block or null if it ends at the end 15 | /// of the method. 16 | /// 17 | public Instruction TryEnd; 18 | 19 | /// 20 | /// Start of filter handler or null if none. The end of filter handler is 21 | /// always . 22 | /// 23 | public Instruction FilterStart; 24 | 25 | /// 26 | /// First instruction of try handler block 27 | /// 28 | public Instruction HandlerStart; 29 | 30 | /// 31 | /// One instruction past the end of try handler block or null if it ends at the end 32 | /// of the method. 33 | /// 34 | public Instruction HandlerEnd; 35 | 36 | /// 37 | /// The catch type if is 38 | /// 39 | public ITypeDefOrRef CatchType; 40 | 41 | /// 42 | /// Type of exception handler clause 43 | /// 44 | public ExceptionHandlerType HandlerType; 45 | 46 | /// 47 | /// Default constructor 48 | /// 49 | public ExceptionHandler() { 50 | } 51 | 52 | /// 53 | /// Constructor 54 | /// 55 | /// Exception clause type 56 | public ExceptionHandler(ExceptionHandlerType handlerType) { 57 | this.HandlerType = handlerType; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/DotNet/Writer/BinaryReaderChunk.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// A chunk 10 | /// 11 | public class BinaryReaderChunk : IChunk { 12 | FileOffset offset; 13 | RVA rva; 14 | readonly IBinaryReader data; 15 | readonly uint virtualSize; 16 | 17 | /// 18 | /// Gets the data 19 | /// 20 | public IBinaryReader Data { 21 | get { return data; } 22 | } 23 | 24 | /// 25 | public FileOffset FileOffset { 26 | get { return offset; } 27 | } 28 | 29 | /// 30 | public RVA RVA { 31 | get { return rva; } 32 | } 33 | 34 | /// 35 | /// Constructor 36 | /// 37 | /// The data 38 | public BinaryReaderChunk(IBinaryReader data) 39 | : this(data, (uint)data.Length) { 40 | } 41 | 42 | /// 43 | /// Constructor 44 | /// 45 | /// The data 46 | /// Virtual size of 47 | public BinaryReaderChunk(IBinaryReader data, uint virtualSize) { 48 | this.data = data; 49 | this.virtualSize = virtualSize; 50 | } 51 | 52 | /// 53 | public void SetOffset(FileOffset offset, RVA rva) { 54 | this.offset = offset; 55 | this.rva = rva; 56 | } 57 | 58 | /// 59 | public uint GetFileLength() { 60 | return (uint)data.Length; 61 | } 62 | 63 | /// 64 | public uint GetVirtualSize() { 65 | return virtualSize; 66 | } 67 | 68 | /// 69 | public void WriteTo(BinaryWriter writer) { 70 | data.Position = 0; 71 | data.WriteTo(writer); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/DotNet/PInvokeAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// P/Invoke attributes, see CorHdr.h/CorPinvokeMap 8 | /// 9 | [Flags] 10 | public enum PInvokeAttributes : ushort { 11 | /// Pinvoke is to use the member name as specified. 12 | NoMangle = 0x0001, 13 | 14 | /// Use this mask to retrieve the CharSet information. 15 | CharSetMask = 0x0006, 16 | /// 17 | CharSetNotSpec = 0x0000, 18 | /// 19 | CharSetAnsi = 0x0002, 20 | /// 21 | CharSetUnicode = 0x0004, 22 | /// 23 | CharSetAuto = 0x0006, 24 | 25 | /// 26 | BestFitUseAssem = 0x0000, 27 | /// 28 | BestFitEnabled = 0x0010, 29 | /// 30 | BestFitDisabled = 0x0020, 31 | /// 32 | BestFitMask = 0x0030, 33 | 34 | /// 35 | ThrowOnUnmappableCharUseAssem = 0x0000, 36 | /// 37 | ThrowOnUnmappableCharEnabled = 0x1000, 38 | /// 39 | ThrowOnUnmappableCharDisabled = 0x2000, 40 | /// 41 | ThrowOnUnmappableCharMask = 0x3000, 42 | 43 | /// Information about target function. Not relevant for fields. 44 | SupportsLastError = 0x0040, 45 | 46 | /// 47 | CallConvMask = 0x0700, 48 | /// Pinvoke will use native callconv appropriate to target windows platform. 49 | CallConvWinapi = 0x0100, 50 | /// 51 | CallConvCdecl = 0x0200, 52 | /// 53 | CallConvStdcall = 0x0300, 54 | /// 55 | CallConvStdCall = CallConvStdcall, 56 | /// In M9, pinvoke will raise exception. 57 | CallConvThiscall = 0x0400, 58 | /// 59 | CallConvFastcall = 0x0500, 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/DotNet/AssemblyHashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Any ALG_CLASS_HASH type in WinCrypt.h can be used by Microsoft's CLI implementation 6 | /// 7 | public enum AssemblyHashAlgorithm : uint { 8 | /// 9 | None = 0, 10 | /// 11 | MD2 = 0x8001, 12 | /// 13 | MD4 = 0x8002, 14 | /// This is a reserved value in the CLI 15 | MD5 = 0x8003, 16 | /// The only algorithm supported by the CLI 17 | SHA1 = 0x8004, 18 | /// 19 | MAC = 0x8005, 20 | /// 21 | SSL3_SHAMD5 = 0x8008, 22 | /// 23 | HMAC = 0x8009, 24 | /// 25 | TLS1PRF = 0x800A, 26 | /// 27 | HASH_REPLACE_OWF = 0x800B, 28 | /// 29 | SHA_256 = 0x800C, 30 | /// 31 | SHA_384 = 0x800D, 32 | /// 33 | SHA_512 = 0x800E, 34 | } 35 | 36 | public static partial class Extensions { 37 | internal static string GetName(this AssemblyHashAlgorithm hashAlg) { 38 | switch (hashAlg) { 39 | case AssemblyHashAlgorithm.MD2: return null; 40 | case AssemblyHashAlgorithm.MD4: return null; 41 | case AssemblyHashAlgorithm.MD5: return "MD5"; 42 | case AssemblyHashAlgorithm.SHA1: return "SHA1"; 43 | case AssemblyHashAlgorithm.MAC: return null; 44 | case AssemblyHashAlgorithm.SSL3_SHAMD5: return null; 45 | case AssemblyHashAlgorithm.HMAC: return null; 46 | case AssemblyHashAlgorithm.TLS1PRF: return null; 47 | case AssemblyHashAlgorithm.HASH_REPLACE_OWF: return null; 48 | case AssemblyHashAlgorithm.SHA_256: return "SHA256"; 49 | case AssemblyHashAlgorithm.SHA_384: return "SHA384"; 50 | case AssemblyHashAlgorithm.SHA_512: return "SHA512"; 51 | default: return null; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/DotNet/Writer/UniqueChunkList.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using dnlib.IO; 6 | using dnlib.PE; 7 | 8 | namespace dnlib.DotNet.Writer { 9 | /// 10 | /// Re-uses existing chunks to save space 11 | /// 12 | /// Chunk type 13 | public sealed class UniqueChunkList : ChunkListBase where T : class, IChunk { 14 | Dictionary dict; 15 | 16 | /// 17 | /// Default constructor 18 | /// 19 | public UniqueChunkList() 20 | : this(EqualityComparer.Default) { 21 | } 22 | 23 | /// 24 | /// Constructor 25 | /// 26 | /// Compares the chunk type 27 | public UniqueChunkList(IEqualityComparer chunkComparer) { 28 | this.chunks = new List(); 29 | this.dict = new Dictionary(new ElemEqualityComparer(chunkComparer)); 30 | } 31 | 32 | /// 33 | public override void SetOffset(FileOffset offset, RVA rva) { 34 | dict = null; 35 | base.SetOffset(offset, rva); 36 | } 37 | 38 | /// 39 | /// Adds a if not already present 40 | /// 41 | /// The chunk to add or null if none 42 | /// Chunk alignment 43 | /// The original input if it wasn't present, or the cached one 44 | public T Add(T chunk, uint alignment) { 45 | if (setOffsetCalled) 46 | throw new InvalidOperationException("SetOffset() has already been called"); 47 | if (chunk == null) 48 | return null; 49 | var elem = new Elem(chunk, alignment); 50 | Elem other; 51 | if (dict.TryGetValue(elem, out other)) 52 | return other.chunk; 53 | dict[elem] = elem; 54 | chunks.Add(elem); 55 | return elem.chunk; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/DotNet/MD/USStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using dnlib.IO; 5 | 6 | namespace dnlib.DotNet.MD { 7 | /// 8 | /// Represents the #US stream 9 | /// 10 | public sealed class USStream : HeapStream { 11 | /// 12 | public USStream() { 13 | } 14 | 15 | /// 16 | public USStream(IImageStream imageStream, StreamHeader streamHeader) 17 | : base(imageStream, streamHeader) { 18 | } 19 | 20 | /// 21 | /// Reads a unicode string 22 | /// 23 | /// Offset of unicode string 24 | /// A string or null if is invalid 25 | public string Read(uint offset) { 26 | if (offset == 0) 27 | return string.Empty; 28 | if (!IsValidOffset(offset)) 29 | return null; 30 | #if THREAD_SAFE 31 | theLock.EnterWriteLock(); try { 32 | #endif 33 | var reader = GetReader_NoLock(offset); 34 | uint length; 35 | if (!reader.ReadCompressedUInt32(out length)) 36 | return null; 37 | if (reader.Position + length < length || reader.Position + length > reader.Length) 38 | return null; 39 | try { 40 | return reader.ReadString((int)(length / 2)); 41 | } 42 | catch (OutOfMemoryException) { 43 | throw; 44 | } 45 | catch { 46 | // It's possible that an exception is thrown when converting a char* to 47 | // a string. If so, return an empty string. 48 | return string.Empty; 49 | } 50 | #if THREAD_SAFE 51 | } finally { theLock.ExitWriteLock(); } 52 | #endif 53 | } 54 | 55 | /// 56 | /// Reads data just like , but returns an empty string if 57 | /// offset is invalid 58 | /// 59 | /// Offset of unicode string 60 | /// The string 61 | public string ReadNoNull(uint offset) { 62 | return Read(offset) ?? string.Empty; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/DotNet/MD/TableInfo.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | 6 | namespace dnlib.DotNet.MD { 7 | /// 8 | /// Info about one MD table 9 | /// 10 | [DebuggerDisplay("{rowSize} {name}")] 11 | public sealed class TableInfo { 12 | readonly Table table; 13 | int rowSize; 14 | readonly IList columns; 15 | readonly string name; 16 | 17 | /// 18 | /// Returns the table type 19 | /// 20 | public Table Table { 21 | get { return table; } 22 | } 23 | 24 | /// 25 | /// Returns the total size of a row in bytes 26 | /// 27 | public int RowSize { 28 | get { return rowSize; } 29 | internal set { rowSize = value; } 30 | } 31 | 32 | /// 33 | /// Returns all the columns 34 | /// 35 | public IList Columns { 36 | get { return columns; } 37 | } 38 | 39 | /// 40 | /// Returns the name of the table 41 | /// 42 | public string Name { 43 | get { return name; } 44 | } 45 | 46 | /// 47 | /// Constructor 48 | /// 49 | /// Table type 50 | /// Table name 51 | /// All columns 52 | public TableInfo(Table table, string name, IList columns) { 53 | this.table = table; 54 | this.name = name; 55 | this.columns = columns; 56 | } 57 | 58 | /// 59 | /// Constructor 60 | /// 61 | /// Table type 62 | /// Table name 63 | /// All columns 64 | /// Row size 65 | public TableInfo(Table table, string name, IList columns, int rowSize) { 66 | this.table = table; 67 | this.name = name; 68 | this.columns = columns; 69 | this.rowSize = rowSize; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/DotNet/Writer/StartupStub.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// Stores the instruction that jumps to _CorExeMain/_CorDllMain 10 | /// 11 | public sealed class StartupStub : IChunk { 12 | FileOffset offset; 13 | RVA rva; 14 | uint length; 15 | uint padding; 16 | 17 | /// 18 | /// Gets/sets the 19 | /// 20 | public ImportDirectory ImportDirectory { get; set; } 21 | 22 | /// 23 | /// Gets/sets the 24 | /// 25 | public PEHeaders PEHeaders { get; set; } 26 | 27 | /// 28 | public FileOffset FileOffset { 29 | get { return offset; } 30 | } 31 | 32 | /// 33 | public RVA RVA { 34 | get { return rva; } 35 | } 36 | 37 | /// 38 | /// Gets the address of the JMP instruction 39 | /// 40 | public RVA EntryPointRVA { 41 | get { return rva + padding; } 42 | } 43 | 44 | /// 45 | /// Gets the address of the operand of the JMP instruction 46 | /// 47 | public RVA RelocRVA { 48 | get { return EntryPointRVA + 2; } 49 | } 50 | 51 | /// 52 | public void SetOffset(FileOffset offset, RVA rva) { 53 | this.offset = offset; 54 | this.rva = rva; 55 | 56 | padding = rva.AlignUp(4) - rva + 2; 57 | length = padding + 6; 58 | } 59 | 60 | /// 61 | public uint GetFileLength() { 62 | return length; 63 | } 64 | 65 | /// 66 | public uint GetVirtualSize() { 67 | return GetFileLength(); 68 | } 69 | 70 | /// 71 | public void WriteTo(BinaryWriter writer) { 72 | writer.WriteZeros((int)padding); 73 | writer.Write((byte)0xFF); 74 | writer.Write((byte)0x25); 75 | writer.Write((uint)PEHeaders.ImageBase + (uint)ImportDirectory.IatCorXxxMainRVA); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/DotNet/Resources/UserResourceData.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using System.Runtime.Serialization; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.DotNet.Resources { 8 | /// 9 | /// Base class of all user data 10 | /// 11 | public abstract class UserResourceData : IResourceData { 12 | readonly UserResourceType type; 13 | 14 | /// 15 | /// Full name including assembly of type 16 | /// 17 | public string TypeName { 18 | get { return type.Name; } 19 | } 20 | 21 | /// 22 | /// User type code 23 | /// 24 | public ResourceTypeCode Code { 25 | get { return type.Code; } 26 | } 27 | 28 | /// 29 | public FileOffset StartOffset { get; set; } 30 | 31 | /// 32 | public FileOffset EndOffset { get; set; } 33 | 34 | /// 35 | /// Constructor 36 | /// 37 | /// User resource type 38 | public UserResourceData(UserResourceType type) { 39 | this.type = type; 40 | } 41 | 42 | /// 43 | public abstract void WriteData(BinaryWriter writer, IFormatter formatter); 44 | } 45 | 46 | /// 47 | /// Binary data 48 | /// 49 | public sealed class BinaryResourceData : UserResourceData { 50 | byte[] data; 51 | 52 | /// 53 | /// Gets the raw data 54 | /// 55 | public byte[] Data { 56 | get { return data; } 57 | } 58 | 59 | /// 60 | /// Constructor 61 | /// 62 | /// User resource type 63 | /// Raw serialized data 64 | public BinaryResourceData(UserResourceType type, byte[] data) 65 | : base(type) { 66 | this.data = data; 67 | } 68 | 69 | /// 70 | public override void WriteData(BinaryWriter writer, IFormatter formatter) { 71 | writer.Write(data); 72 | } 73 | 74 | /// 75 | public override string ToString() { 76 | return string.Format("Binary: Length: {0}", data.Length); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/DotNet/Emit/OperandType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using dnlib.DotNet.MD; 4 | 5 | namespace dnlib.DotNet.Emit { 6 | /// 7 | /// CIL opcode operand type 8 | /// 9 | public enum OperandType : byte { 10 | /// 4-byte relative instruction offset 11 | InlineBrTarget, 12 | /// 4-byte field token ( or ) 13 | InlineField, 14 | /// int32 15 | InlineI, 16 | /// int64 17 | InlineI8, 18 | /// 4-byte method token (, 19 | /// or ) 20 | InlineMethod, 21 | /// No operand 22 | InlineNone, 23 | /// Never used 24 | InlinePhi, 25 | /// 64-bit real 26 | InlineR, 27 | /// 28 | NOT_USED_8, 29 | /// 4-byte method sig token () 30 | InlineSig, 31 | /// 4-byte string token (0x70xxxxxx) 32 | InlineString, 33 | /// 4-byte count N followed by N 4-byte relative instruction offsets 34 | InlineSwitch, 35 | /// 4-byte token (, , 36 | /// , , , 37 | /// or ) 38 | InlineTok, 39 | /// 4-byte type token (, or 40 | /// ) 41 | InlineType, 42 | /// 2-byte param/local index 43 | InlineVar, 44 | /// 1-byte relative instruction offset 45 | ShortInlineBrTarget, 46 | /// 1-byte sbyte () or byte (the rest) 47 | ShortInlineI, 48 | /// 32-bit real 49 | ShortInlineR, 50 | /// 1-byte param/local index 51 | ShortInlineVar, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/DotNet/Writer/ByteArrayChunk.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// Stores a byte array 10 | /// 11 | public sealed class ByteArrayChunk : IChunk { 12 | readonly byte[] array; 13 | FileOffset offset; 14 | RVA rva; 15 | 16 | /// 17 | public FileOffset FileOffset { 18 | get { return offset; } 19 | } 20 | 21 | /// 22 | public RVA RVA { 23 | get { return rva; } 24 | } 25 | 26 | /// 27 | /// Gets the data 28 | /// 29 | public byte[] Data { 30 | get { return array; } 31 | } 32 | 33 | /// 34 | /// Constructor 35 | /// 36 | /// The data. It will be owned by this instance and can't be modified by 37 | /// other code if this instance is inserted as a key in a dictionary (because 38 | /// return value will be different if you modify the array). If 39 | /// it's never inserted as a key in a dictionary, then the contents can be modified, 40 | /// but shouldn't be resized after has been called. 41 | public ByteArrayChunk(byte[] array) { 42 | this.array = array ?? new byte[0]; 43 | } 44 | 45 | /// 46 | public void SetOffset(FileOffset offset, RVA rva) { 47 | this.offset = offset; 48 | this.rva = rva; 49 | } 50 | 51 | /// 52 | public uint GetFileLength() { 53 | return (uint)array.Length; 54 | } 55 | 56 | /// 57 | public uint GetVirtualSize() { 58 | return GetFileLength(); 59 | } 60 | 61 | /// 62 | public void WriteTo(BinaryWriter writer) { 63 | writer.Write(array); 64 | } 65 | 66 | /// 67 | public override int GetHashCode() { 68 | return Utils.GetHashCode(array); 69 | } 70 | 71 | /// 72 | public override bool Equals(object obj) { 73 | var other = obj as ByteArrayChunk; 74 | return other != null && Utils.Equals(array, other.array); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/PE/Machine.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.PE { 4 | /// 5 | /// IMAGE_FILE_HEADER.Machine enum 6 | /// 7 | public enum Machine : ushort { 8 | /// Unknown machine 9 | Unknown = 0, 10 | /// x86 11 | I386 = 0x014C, 12 | /// MIPS little-endian, 0x160 big-endian 13 | R3000 = 0x0162, 14 | /// MIPS little-endian 15 | R4000 = 0x0166, 16 | /// MIPS little-endian 17 | R10000 = 0x0168, 18 | /// MIPS little-endian WCE v2 19 | WCEMIPSV2 = 0x0169, 20 | /// Alpha_AXP 21 | ALPHA = 0x0184, 22 | /// SH3 little-endian 23 | SH3 = 0x01A2, 24 | /// 25 | SH3DSP = 0x01A3, 26 | /// SH3E little-endian 27 | SH3E = 0x01A4, 28 | /// SH4 little-endian 29 | SH4 = 0x01A6, 30 | /// SH5 31 | SH5 = 0x01A8, 32 | /// ARM Little-Endian 33 | ARM = 0x01C0, 34 | /// ARM Thumb/Thumb-2 Little-Endian 35 | THUMB = 0x01C2, 36 | /// ARM Thumb-2 Little-Endian 37 | ARMNT = 0x01C4, 38 | /// 39 | AM33 = 0x01D3, 40 | /// IBM PowerPC Little-Endian 41 | POWERPC = 0x01F0, 42 | /// 43 | POWERPCFP = 0x01F1, 44 | /// IA-64 45 | IA64 = 0x0200, 46 | /// 47 | MIPS16 = 0x0266, 48 | /// 49 | ALPHA64 = 0x0284, 50 | /// 51 | MIPSFPU = 0x0366, 52 | /// 53 | MIPSFPU16 = 0x0466, 54 | /// Infineon 55 | TRICORE = 0x0520, 56 | /// 57 | CEF = 0x0CEF, 58 | /// EFI Byte Code 59 | EBC = 0x0EBC, 60 | /// x64 61 | AMD64 = 0x8664, 62 | /// M32R little-endian 63 | M32R = 0x9041, 64 | /// 65 | ARM64 = 0xAA64, 66 | /// 67 | CEE = 0xC0EE, 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/SymbolVariable.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics.SymbolStore; 4 | 5 | namespace dnlib.DotNet.Pdb.Dss { 6 | sealed class SymbolVariable : ISymbolVariable { 7 | readonly ISymUnmanagedVariable variable; 8 | 9 | public SymbolVariable(ISymUnmanagedVariable variable) { 10 | this.variable = variable; 11 | } 12 | 13 | public int AddressField1 { 14 | get { 15 | uint result; 16 | variable.GetAddressField1(out result); 17 | return (int)result; 18 | } 19 | } 20 | 21 | public int AddressField2 { 22 | get { 23 | uint result; 24 | variable.GetAddressField2(out result); 25 | return (int)result; 26 | } 27 | } 28 | 29 | public int AddressField3 { 30 | get { 31 | uint result; 32 | variable.GetAddressField3(out result); 33 | return (int)result; 34 | } 35 | } 36 | 37 | public SymAddressKind AddressKind { 38 | get { 39 | uint result; 40 | variable.GetAddressKind(out result); 41 | return (SymAddressKind)result; 42 | } 43 | } 44 | 45 | public object Attributes { 46 | get { 47 | uint result; 48 | variable.GetAttributes(out result); 49 | return (int)result; 50 | } 51 | } 52 | 53 | public int EndOffset { 54 | get { 55 | uint result; 56 | variable.GetEndOffset(out result); 57 | return (int)result; 58 | } 59 | } 60 | 61 | public string Name { 62 | get { 63 | uint count; 64 | variable.GetName(0, out count, null); 65 | var chars = new char[count]; 66 | variable.GetName((uint)chars.Length, out count, chars); 67 | if (chars.Length == 0) 68 | return string.Empty; 69 | return new string(chars, 0, chars.Length - 1); 70 | } 71 | } 72 | 73 | public int StartOffset { 74 | get { 75 | uint result; 76 | variable.GetStartOffset(out result); 77 | return (int)result; 78 | } 79 | } 80 | 81 | public byte[] GetSignature() { 82 | uint bufSize; 83 | variable.GetSignature(0, out bufSize, null); 84 | var buffer = new byte[bufSize]; 85 | variable.GetSignature((uint)buffer.Length, out bufSize, buffer); 86 | return buffer; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/PdbScope.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics; 4 | using dnlib.DotNet.Emit; 5 | using dnlib.Threading; 6 | 7 | #if THREAD_SAFE 8 | using ThreadSafe = dnlib.Threading.Collections; 9 | #else 10 | using ThreadSafe = System.Collections.Generic; 11 | #endif 12 | 13 | namespace dnlib.DotNet.Pdb { 14 | /// 15 | /// A PDB scope 16 | /// 17 | [DebuggerDisplay("{Start} - {End}")] 18 | public sealed class PdbScope { 19 | readonly ThreadSafe.IList scopes = ThreadSafeListCreator.Create(); 20 | readonly ThreadSafe.IList locals = ThreadSafeListCreator.Create(); 21 | readonly ThreadSafe.IList namespaces = ThreadSafeListCreator.Create(); 22 | 23 | /// 24 | /// Gets/sets the first instruction 25 | /// 26 | public Instruction Start { get; set; } 27 | 28 | /// 29 | /// Gets/sets the last instruction. It's null if it ends at the end of the method. 30 | /// 31 | public Instruction End { get; set; } 32 | 33 | /// 34 | /// Gets all child scopes 35 | /// 36 | public ThreadSafe.IList Scopes { 37 | get { return scopes; } 38 | } 39 | 40 | /// 41 | /// true if is not empty 42 | /// 43 | public bool HasScopes { 44 | get { return scopes.Count > 0; } 45 | } 46 | 47 | /// 48 | /// Gets all locals in this scope 49 | /// 50 | public ThreadSafe.IList Variables { 51 | get { return locals; } 52 | } 53 | 54 | /// 55 | /// true if is not empty 56 | /// 57 | public bool HasVariables { 58 | get { return locals.Count > 0; } 59 | } 60 | 61 | /// 62 | /// Gets all namespaces 63 | /// 64 | public ThreadSafe.IList Namespaces { 65 | get { return namespaces; } 66 | } 67 | 68 | /// 69 | /// true if is not empty 70 | /// 71 | public bool HasNamespaces { 72 | get { return namespaces.Count > 0; } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/PinnedMetaData.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Runtime.InteropServices; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.DotNet.Pdb.Dss { 8 | /// 9 | /// Pins a metadata stream in memory 10 | /// 11 | sealed class PinnedMetaData : IDisposable { 12 | GCHandle gcHandle; 13 | readonly IImageStream stream; 14 | readonly byte[] streamData; 15 | readonly IntPtr address; 16 | 17 | /// 18 | /// Gets the address 19 | /// 20 | public IntPtr Address { 21 | get { return address; } 22 | } 23 | 24 | /// 25 | /// Gets the size 26 | /// 27 | public int Size { 28 | get { return (int)stream.Length; } 29 | } 30 | 31 | /// 32 | /// Constructor 33 | /// 34 | /// Metadata stream 35 | public PinnedMetaData(IImageStream stream) { 36 | this.stream = stream; 37 | 38 | var umStream = stream as UnmanagedMemoryImageStream; 39 | if (umStream != null) { 40 | this.address = umStream.StartAddress; 41 | GC.SuppressFinalize(this); // no GCHandle so finalizer isn't needed 42 | } 43 | else { 44 | var memStream = stream as MemoryImageStream; 45 | if (memStream != null) { 46 | this.streamData = memStream.DataArray; 47 | this.gcHandle = GCHandle.Alloc(this.streamData, GCHandleType.Pinned); 48 | this.address = new IntPtr(this.gcHandle.AddrOfPinnedObject().ToInt64() + memStream.DataOffset); 49 | } 50 | else { 51 | this.streamData = stream.ReadAllBytes(); 52 | this.gcHandle = GCHandle.Alloc(this.streamData, GCHandleType.Pinned); 53 | this.address = this.gcHandle.AddrOfPinnedObject(); 54 | } 55 | } 56 | } 57 | 58 | ~PinnedMetaData() { 59 | Dispose(false); 60 | } 61 | 62 | public void Dispose() { 63 | Dispose(true); 64 | GC.SuppressFinalize(this); 65 | } 66 | 67 | void Dispose(bool disposing) { 68 | if (gcHandle.IsAllocated) { 69 | try { 70 | gcHandle.Free(); 71 | } 72 | catch (InvalidOperationException) { 73 | } 74 | } 75 | if (disposing) 76 | stream.Dispose(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/DotNet/FieldAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Field flags, see CorHdr.h/CorFieldAttr 8 | /// 9 | [Flags] 10 | public enum FieldAttributes : ushort { 11 | /// member access mask - Use this mask to retrieve accessibility information. 12 | FieldAccessMask = 0x0007, 13 | /// Member not referenceable. 14 | PrivateScope = 0x0000, 15 | /// Member not referenceable. 16 | CompilerControlled = PrivateScope, 17 | /// Accessible only by the parent type. 18 | Private = 0x0001, 19 | /// Accessible by sub-types only in this Assembly. 20 | FamANDAssem = 0x0002, 21 | /// Accessibly by anyone in the Assembly. 22 | Assembly = 0x0003, 23 | /// Accessible only by type and sub-types. 24 | Family = 0x0004, 25 | /// Accessibly by sub-types anywhere, plus anyone in assembly. 26 | FamORAssem = 0x0005, 27 | /// Accessibly by anyone who has visibility to this scope. 28 | Public = 0x0006, 29 | 30 | /// Defined on type, else per instance. 31 | Static = 0x0010, 32 | /// Field may only be initialized, not written to after init. 33 | InitOnly = 0x0020, 34 | /// Value is compile time constant. 35 | Literal = 0x0040, 36 | /// Field does not have to be serialized when type is remoted. 37 | NotSerialized = 0x0080, 38 | 39 | /// field is special. Name describes how. 40 | SpecialName = 0x0200, 41 | 42 | /// Implementation is forwarded through pinvoke. 43 | PinvokeImpl = 0x2000, 44 | 45 | /// Runtime(metadata internal APIs) should check name encoding. 46 | RTSpecialName = 0x0400, 47 | /// Field has marshalling information. 48 | HasFieldMarshal = 0x1000, 49 | /// Field has default. 50 | HasDefault = 0x8000, 51 | /// Field has RVA. 52 | HasFieldRVA = 0x0100, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Utils/ILazyList.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using dnlib.Threading; 6 | 7 | #if THREAD_SAFE 8 | using ThreadSafe = dnlib.Threading.Collections; 9 | #else 10 | using ThreadSafe = System.Collections.Generic; 11 | #endif 12 | 13 | namespace dnlib.Utils { 14 | /// 15 | /// Interface to access a lazily initialized list 16 | /// 17 | /// Type to store in list 18 | public interface ILazyList : ThreadSafe.IList { 19 | /// 20 | /// Checks whether an element at has been initialized. 21 | /// 22 | /// Index of element 23 | /// true if the element has been initialized, false otherwise 24 | bool IsInitialized(int index); 25 | 26 | /// 27 | /// Checks whether an element at has been initialized. 28 | /// 29 | /// Index of element 30 | /// true if the element has been initialized, false otherwise 31 | bool IsInitialized_NoLock(int index); 32 | 33 | /// 34 | /// Gets all initialized elements 35 | /// 36 | /// true if the list should be cleared before returning, 37 | /// false if the list should not cleared. 38 | List GetInitializedElements(bool clearList); 39 | } 40 | 41 | public static partial class Extensions { 42 | /// 43 | /// Disposes all initialized elements 44 | /// 45 | /// Element type 46 | /// this 47 | public static void DisposeAll(this ILazyList list) where TValue : IDisposable { 48 | list.ExecuteLocked(null, (tsList, arg) => { 49 | for (int i = 0; i < list.Count_NoLock(); i++) { 50 | if (list.IsInitialized_NoLock(i)) { 51 | var elem = list.Get_NoLock(i); 52 | if (elem != null) 53 | elem.Dispose(); 54 | } 55 | } 56 | return null; 57 | }); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/DotNet/MD/StreamHeader.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics; 5 | using System.Text; 6 | using dnlib.IO; 7 | 8 | namespace dnlib.DotNet.MD { 9 | /// 10 | /// A metadata stream header 11 | /// 12 | [DebuggerDisplay("O:{offset} L:{streamSize} {name}")] 13 | public sealed class StreamHeader : FileSection { 14 | readonly uint offset; 15 | readonly uint streamSize; 16 | readonly string name; 17 | 18 | /// 19 | /// The offset of the stream relative to the start of the MetaData header 20 | /// 21 | public uint Offset { 22 | get { return offset; } 23 | } 24 | 25 | /// 26 | /// The size of the stream 27 | /// 28 | public uint StreamSize { 29 | get { return streamSize; } 30 | } 31 | 32 | /// 33 | /// The name of the stream 34 | /// 35 | public string Name { 36 | get { return name; } 37 | } 38 | 39 | /// 40 | /// Constructor 41 | /// 42 | /// PE file reader pointing to the start of this section 43 | /// Verify section 44 | /// Thrown if verification fails 45 | public StreamHeader(IImageStream reader, bool verify) { 46 | SetStartOffset(reader); 47 | this.offset = reader.ReadUInt32(); 48 | this.streamSize = reader.ReadUInt32(); 49 | this.name = ReadString(reader, 32, verify); 50 | SetEndoffset(reader); 51 | if (verify && offset + size < offset) 52 | throw new BadImageFormatException("Invalid stream header"); 53 | } 54 | 55 | static string ReadString(IImageStream reader, int maxLen, bool verify) { 56 | var origPos = reader.Position; 57 | var sb = new StringBuilder(maxLen); 58 | int i; 59 | for (i = 0; i < maxLen; i++) { 60 | byte b = reader.ReadByte(); 61 | if (b == 0) 62 | break; 63 | sb.Append((char)b); 64 | } 65 | if (verify && i == maxLen) 66 | throw new BadImageFormatException("Invalid stream name string"); 67 | if (i != maxLen) 68 | reader.Position = origPos + ((i + 1 + 3) & ~3); 69 | return sb.ToString(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/DotNet/ModuleContext.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Threading; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// context 8 | /// 9 | public class ModuleContext { 10 | IAssemblyResolver assemblyResolver; 11 | IResolver resolver; 12 | 13 | /// 14 | /// Gets/sets the assembly resolver. This is never null. 15 | /// 16 | public IAssemblyResolver AssemblyResolver { 17 | get { 18 | if (assemblyResolver == null) 19 | Interlocked.CompareExchange(ref assemblyResolver, NullResolver.Instance, null); 20 | return assemblyResolver; 21 | } 22 | set { assemblyResolver = value; } 23 | } 24 | 25 | /// 26 | /// Gets/sets the resolver. This is never null. 27 | /// 28 | public IResolver Resolver { 29 | get { 30 | if (resolver == null) 31 | Interlocked.CompareExchange(ref resolver, NullResolver.Instance, null); 32 | return resolver; 33 | } 34 | set { resolver = value; } 35 | } 36 | 37 | /// 38 | /// Default constructor 39 | /// 40 | public ModuleContext() { 41 | } 42 | 43 | /// 44 | /// Constructor 45 | /// 46 | /// Assembly resolver or null 47 | public ModuleContext(IAssemblyResolver assemblyResolver) 48 | : this(assemblyResolver, new Resolver(assemblyResolver)) { 49 | } 50 | 51 | /// 52 | /// Constructor 53 | /// 54 | /// Type/method/field resolver or null 55 | public ModuleContext(IResolver resolver) 56 | : this(null, resolver) { 57 | } 58 | 59 | /// 60 | /// Constructor 61 | /// 62 | /// Assembly resolver or null 63 | /// Type/method/field resolver or null 64 | public ModuleContext(IAssemblyResolver assemblyResolver, IResolver resolver) { 65 | this.assemblyResolver = assemblyResolver; 66 | this.resolver = resolver; 67 | if (resolver == null && assemblyResolver != null) 68 | this.resolver = new Resolver(assemblyResolver); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/DotNet/AssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Assembly flags from Assembly.Flags column. 8 | /// 9 | /// See CorHdr.h/CorAssemblyFlags 10 | [Flags] 11 | public enum AssemblyAttributes : uint { 12 | /// No flags set 13 | None = 0, 14 | 15 | /// The assembly ref holds the full (unhashed) public key. 16 | PublicKey = 1, 17 | 18 | /// Processor Architecture unspecified 19 | PA_None = 0x0000, 20 | /// Processor Architecture: neutral (PE32) 21 | PA_MSIL = 0x0010, 22 | /// Processor Architecture: x86 (PE32) 23 | PA_x86 = 0x0020, 24 | /// Processor Architecture: Itanium (PE32+) 25 | PA_IA64 = 0x0030, 26 | /// Processor Architecture: AMD X64 (PE32+) 27 | PA_AMD64 = 0x0040, 28 | /// Processor Architecture: ARM (PE32) 29 | PA_ARM = 0x0050, 30 | /// applies to any platform but cannot run on any (e.g. reference assembly), should not have "specified" set 31 | PA_NoPlatform = 0x0070, 32 | /// Propagate PA flags to AssemblyRef record 33 | PA_Specified = 0x0080, 34 | /// Bits describing the processor architecture 35 | PA_Mask = 0x0070, 36 | /// Bits describing the PA incl. Specified 37 | PA_FullMask = 0x00F0, 38 | /// NOT A FLAG, shift count in PA flags <--> index conversion 39 | PA_Shift = 0x0004, 40 | 41 | /// From "DebuggableAttribute". 42 | EnableJITcompileTracking = 0x8000, 43 | /// From "DebuggableAttribute". 44 | DisableJITcompileOptimizer = 0x4000, 45 | 46 | /// The assembly can be retargeted (at runtime) to an assembly from a different publisher. 47 | Retargetable = 0x0100, 48 | 49 | /// 50 | ContentType_Default = 0x0000, 51 | /// 52 | ContentType_WindowsRuntime = 0x0200, 53 | /// Bits describing ContentType 54 | ContentType_Mask = 0x0E00, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Threading/Lock.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Threading; 5 | 6 | namespace dnlib.Threading { 7 | #if THREAD_SAFE 8 | [Serializable] 9 | class LockException : Exception { 10 | public LockException() { 11 | } 12 | 13 | public LockException(string msg) 14 | : base(msg) { 15 | } 16 | } 17 | 18 | /// 19 | /// Simple class using and 20 | /// and just like ReaderWriterLockSlim it prevents recursive locks. It doesn't support 21 | /// multiple readers. A reader lock is the same as a writer lock. 22 | /// 23 | class Lock { 24 | readonly object lockObj; 25 | int recurseCount; 26 | 27 | /// 28 | /// Creates a new instance of this class 29 | /// 30 | /// 31 | public static Lock Create() { 32 | return new Lock(); 33 | } 34 | 35 | /// 36 | /// Constructor 37 | /// 38 | Lock() { 39 | this.lockObj = new object(); 40 | this.recurseCount = 0; 41 | } 42 | 43 | /// 44 | /// Enter read mode 45 | /// 46 | public void EnterReadLock() { 47 | Monitor.Enter(lockObj); 48 | if (recurseCount != 0) { 49 | Monitor.Exit(lockObj); 50 | throw new LockException("Recursive locks aren't supported"); 51 | } 52 | recurseCount++; 53 | } 54 | 55 | /// 56 | /// Exit read mode 57 | /// 58 | public void ExitReadLock() { 59 | if (recurseCount <= 0) 60 | throw new LockException("Too many exit lock method calls"); 61 | recurseCount--; 62 | Monitor.Exit(lockObj); 63 | } 64 | 65 | /// 66 | /// Enter write mode 67 | /// 68 | public void EnterWriteLock() { 69 | Monitor.Enter(lockObj); 70 | if (recurseCount != 0) { 71 | Monitor.Exit(lockObj); 72 | throw new LockException("Recursive locks aren't supported"); 73 | } 74 | recurseCount--; 75 | } 76 | 77 | /// 78 | /// Exit write mode 79 | /// 80 | public void ExitWriteLock() { 81 | if (recurseCount >= 0) 82 | throw new LockException("Too many exit lock method calls"); 83 | recurseCount++; 84 | Monitor.Exit(lockObj); 85 | } 86 | } 87 | #endif 88 | } 89 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/DbiDocument.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | using dnlib.IO; 6 | 7 | namespace dnlib.DotNet.Pdb.Managed { 8 | sealed class DbiDocument : ISymbolDocument { 9 | public string URL { get; private set; } 10 | public Guid Language { get; private set; } 11 | public Guid LanguageVendor { get; private set; } 12 | public Guid DocumentType { get; private set; } 13 | public Guid CheckSumAlgorithmId { get; private set; } 14 | public byte[] CheckSum { get; private set; } 15 | 16 | public DbiDocument(string url) { 17 | URL = url; 18 | DocumentType = SymDocumentType.Text; 19 | } 20 | 21 | public void Read(IImageStream stream) { 22 | stream.Position = 0; 23 | Language = new Guid(stream.ReadBytes(0x10)); 24 | LanguageVendor = new Guid(stream.ReadBytes(0x10)); 25 | DocumentType = new Guid(stream.ReadBytes(0x10)); 26 | CheckSumAlgorithmId = new Guid(stream.ReadBytes(0x10)); 27 | 28 | var len = stream.ReadInt32(); 29 | if (stream.ReadUInt32() != 0) 30 | throw new PdbException("Unexpected value"); 31 | 32 | CheckSum = stream.ReadBytes(len); 33 | } 34 | 35 | #region ISymbolDocument 36 | 37 | Guid ISymbolDocument.CheckSumAlgorithmId { 38 | get { return CheckSumAlgorithmId; } 39 | } 40 | 41 | Guid ISymbolDocument.DocumentType { 42 | get { return DocumentType; } 43 | } 44 | 45 | byte[] ISymbolDocument.GetCheckSum() { 46 | return CheckSum; 47 | } 48 | 49 | Guid ISymbolDocument.Language { 50 | get { return Language; } 51 | } 52 | 53 | Guid ISymbolDocument.LanguageVendor { 54 | get { return LanguageVendor; } 55 | } 56 | 57 | string ISymbolDocument.URL { 58 | get { return URL; } 59 | } 60 | 61 | int ISymbolDocument.FindClosestLine(int line) { 62 | throw new NotImplementedException(); 63 | } 64 | 65 | byte[] ISymbolDocument.GetSourceRange(int startLine, int startColumn, int endLine, int endColumn) { 66 | throw new NotImplementedException(); 67 | } 68 | 69 | bool ISymbolDocument.HasEmbeddedSource { 70 | get { throw new NotImplementedException(); } 71 | } 72 | 73 | int ISymbolDocument.SourceLength { 74 | get { throw new NotImplementedException(); } 75 | } 76 | 77 | #endregion 78 | } 79 | } -------------------------------------------------------------------------------- /src/DotNet/Resources/ResourceTypeCode.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.Resources { 4 | /// 5 | /// Type of resource 6 | /// 7 | public enum ResourceTypeCode { 8 | /// 9 | /// null 10 | /// 11 | Null = 0, 12 | 13 | /// 14 | /// 15 | /// 16 | String = 1, 17 | 18 | /// 19 | /// 20 | /// 21 | Boolean = 2, 22 | 23 | /// 24 | /// 25 | /// 26 | Char = 3, 27 | 28 | /// 29 | /// 30 | /// 31 | Byte = 4, 32 | 33 | /// 34 | /// 35 | /// 36 | SByte = 5, 37 | 38 | /// 39 | /// 40 | /// 41 | Int16 = 6, 42 | 43 | /// 44 | /// 45 | /// 46 | UInt16 = 7, 47 | 48 | /// 49 | /// 50 | /// 51 | Int32 = 8, 52 | 53 | /// 54 | /// 55 | /// 56 | UInt32 = 9, 57 | 58 | /// 59 | /// 60 | /// 61 | Int64 = 0x0A, 62 | 63 | /// 64 | /// 65 | /// 66 | UInt64 = 0x0B, 67 | 68 | /// 69 | /// 70 | /// 71 | Single = 0x0C, 72 | 73 | /// 74 | /// 75 | /// 76 | Double = 0x0D, 77 | 78 | /// 79 | /// 80 | /// 81 | Decimal = 0x0E, 82 | 83 | /// 84 | /// 85 | /// 86 | DateTime = 0x0F, 87 | 88 | /// 89 | /// 90 | /// 91 | TimeSpan = 0x10, 92 | 93 | /// 94 | /// array 95 | /// 96 | ByteArray = 0x20, 97 | 98 | /// 99 | /// 100 | /// 101 | Stream = 0x21, 102 | 103 | /// 104 | /// Start of user types 105 | /// 106 | UserTypes = 0x40, 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/DotNet/Writer/HeapBase.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using dnlib.IO; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// Base class of most heaps 10 | /// 11 | public abstract class HeapBase : IHeap { 12 | internal const uint ALIGNMENT = 4; 13 | FileOffset offset; 14 | RVA rva; 15 | 16 | /// 17 | /// true if has been called 18 | /// 19 | protected bool isReadOnly; 20 | 21 | /// 22 | public FileOffset FileOffset { 23 | get { return offset; } 24 | } 25 | 26 | /// 27 | public RVA RVA { 28 | get { return rva; } 29 | } 30 | 31 | /// 32 | public abstract string Name { get; } 33 | 34 | /// 35 | public bool IsEmpty { 36 | get { return GetRawLength() <= 1; } 37 | } 38 | 39 | /// 40 | /// true if offsets require 4 bytes instead of 2 bytes. 41 | /// 42 | public bool IsBig { 43 | get { return GetFileLength() > 0xFFFF; } 44 | } 45 | 46 | /// 47 | public void SetReadOnly() { 48 | isReadOnly = true; 49 | } 50 | 51 | /// 52 | public virtual void SetOffset(FileOffset offset, RVA rva) { 53 | this.offset = offset; 54 | this.rva = rva; 55 | } 56 | 57 | /// 58 | public uint GetFileLength() { 59 | return Utils.AlignUp(GetRawLength(), ALIGNMENT); 60 | } 61 | 62 | /// 63 | public uint GetVirtualSize() { 64 | return GetFileLength(); 65 | } 66 | 67 | /// 68 | /// Gets the raw length of the heap 69 | /// 70 | /// Raw length of the heap 71 | public abstract uint GetRawLength(); 72 | 73 | /// 74 | public void WriteTo(BinaryWriter writer) { 75 | WriteToImpl(writer); 76 | writer.WriteZeros((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength())); 77 | } 78 | 79 | /// 80 | /// Writes all data to at its current location. 81 | /// 82 | /// Destination 83 | protected abstract void WriteToImpl(BinaryWriter writer); 84 | 85 | /// 86 | public override string ToString() { 87 | return Name; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/SymbolScope.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics.SymbolStore; 4 | 5 | namespace dnlib.DotNet.Pdb.Dss { 6 | sealed class SymbolScope : ISymbolScope { 7 | readonly ISymUnmanagedScope scope; 8 | 9 | public SymbolScope(ISymUnmanagedScope scope) { 10 | this.scope = scope; 11 | } 12 | 13 | public int EndOffset { 14 | get { 15 | uint result; 16 | scope.GetEndOffset(out result); 17 | return (int)result; 18 | } 19 | } 20 | 21 | public ISymbolMethod Method { 22 | get { 23 | ISymUnmanagedMethod method; 24 | scope.GetMethod(out method); 25 | return method == null ? null : new SymbolMethod(method); 26 | } 27 | } 28 | 29 | public ISymbolScope Parent { 30 | get { 31 | ISymUnmanagedScope parentScope; 32 | scope.GetParent(out parentScope); 33 | return parentScope == null ? null : new SymbolScope(parentScope); 34 | } 35 | } 36 | 37 | public int StartOffset { 38 | get { 39 | uint result; 40 | scope.GetStartOffset(out result); 41 | return (int)result; 42 | } 43 | } 44 | 45 | public ISymbolScope[] GetChildren() { 46 | uint numScopes; 47 | scope.GetChildren(0, out numScopes, null); 48 | var unScopes = new ISymUnmanagedScope[numScopes]; 49 | scope.GetChildren((uint)unScopes.Length, out numScopes, unScopes); 50 | var scopes = new ISymbolScope[numScopes]; 51 | for (uint i = 0; i < numScopes; i++) 52 | scopes[i] = new SymbolScope(unScopes[i]); 53 | return scopes; 54 | } 55 | 56 | public ISymbolVariable[] GetLocals() { 57 | uint numVars; 58 | scope.GetLocals(0, out numVars, null); 59 | var unVars = new ISymUnmanagedVariable[numVars]; 60 | scope.GetLocals((uint)unVars.Length, out numVars, unVars); 61 | var vars = new ISymbolVariable[numVars]; 62 | for (uint i = 0; i < numVars; i++) 63 | vars[i] = new SymbolVariable(unVars[i]); 64 | return vars; 65 | } 66 | 67 | public ISymbolNamespace[] GetNamespaces() { 68 | uint numNss; 69 | scope.GetNamespaces(0, out numNss, null); 70 | var unNss = new ISymUnmanagedNamespace[numNss]; 71 | scope.GetNamespaces((uint)unNss.Length, out numNss, unNss); 72 | var nss = new ISymbolNamespace[numNss]; 73 | for (uint i = 0; i < numNss; i++) 74 | nss[i] = new SymbolNamespace(unNss[i]); 75 | return nss; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/DotNet/Writer/SectionSizes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Collections.Generic; 4 | using dnlib.Utils; 5 | 6 | namespace dnlib.DotNet.Writer { 7 | struct SectionSizeInfo { 8 | /// 9 | /// Length of section 10 | /// 11 | public readonly uint length; 12 | 13 | /// 14 | /// Section characteristics 15 | /// 16 | public readonly uint characteristics; 17 | 18 | /// 19 | /// Constructor 20 | /// 21 | /// Length of section 22 | /// Section characteristics 23 | public SectionSizeInfo(uint length, uint characteristics) { 24 | this.length = length; 25 | this.characteristics = characteristics; 26 | } 27 | } 28 | 29 | /// 30 | /// Calculates the optional header section sizes 31 | /// 32 | struct SectionSizes { 33 | public readonly uint SizeOfHeaders; 34 | public readonly uint SizeOfImage; 35 | public readonly uint BaseOfData, BaseOfCode; 36 | public readonly uint SizeOfCode, SizeOfInitdData, SizeOfUninitdData; 37 | 38 | public SectionSizes(uint fileAlignment, uint sectionAlignment, uint headerLen, MFunc> getSectionSizeInfos) { 39 | SizeOfHeaders = Utils.AlignUp(headerLen, fileAlignment); 40 | SizeOfImage = Utils.AlignUp(SizeOfHeaders, sectionAlignment); 41 | BaseOfData = 0; 42 | BaseOfCode = 0; 43 | SizeOfCode = 0; 44 | SizeOfInitdData = 0; 45 | SizeOfUninitdData = 0; 46 | foreach (var section in getSectionSizeInfos()) { 47 | uint sectAlignedVs = Utils.AlignUp(section.length, sectionAlignment); 48 | uint fileAlignedVs = Utils.AlignUp(section.length, fileAlignment); 49 | 50 | bool isCode = (section.characteristics & 0x20) != 0; 51 | bool isInitdData = (section.characteristics & 0x40) != 0; 52 | bool isUnInitdData = (section.characteristics & 0x80) != 0; 53 | 54 | if (BaseOfCode == 0 && isCode) 55 | BaseOfCode = SizeOfImage; 56 | if (BaseOfData == 0 && (isInitdData || isUnInitdData)) 57 | BaseOfData = SizeOfImage; 58 | if (isCode) 59 | SizeOfCode += fileAlignedVs; 60 | if (isInitdData) 61 | SizeOfInitdData += fileAlignedVs; 62 | if (isUnInitdData) 63 | SizeOfUninitdData += fileAlignedVs; 64 | 65 | SizeOfImage += sectAlignedVs; 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/DotNet/MD/MDHeaderRuntimeVersion.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet.MD { 4 | /// 5 | /// Version strings found in the meta data header 6 | /// 7 | public static class MDHeaderRuntimeVersion { 8 | /// 9 | /// MS CLR 1.0 version string (.NET 1.0) 10 | /// 11 | public const string MS_CLR_10 = "v1.0.3705"; 12 | 13 | /// 14 | /// MS CLR 1.0 version string (.NET 1.0). This is an incorrect version that shouldn't be used. 15 | /// 16 | public const string MS_CLR_10_X86RETAIL = "v1.x86ret"; 17 | 18 | /// 19 | /// MS CLR 1.0 version string (.NET 1.0). This is an incorrect version that shouldn't be used. 20 | /// 21 | public const string MS_CLR_10_RETAIL = "retail"; 22 | 23 | /// 24 | /// MS CLR 1.0 version string (.NET 1.0). This is an incorrect version that shouldn't be used. 25 | /// 26 | public const string MS_CLR_10_COMPLUS = "COMPLUS"; 27 | 28 | /// 29 | /// MS CLR 1.1 version string (.NET 1.1) 30 | /// 31 | public const string MS_CLR_11 = "v1.1.4322"; 32 | 33 | /// 34 | /// MS CLR 2.0 version string (.NET 2.0-3.5) 35 | /// 36 | public const string MS_CLR_20 = "v2.0.50727"; 37 | 38 | /// 39 | /// MS CLR 4.0 version string (.NET 4.0-4.5) 40 | /// 41 | public const string MS_CLR_40 = "v4.0.30319"; 42 | 43 | /// 44 | /// MS CLR 1.0 any version 45 | /// 46 | public const string MS_CLR_10_PREFIX = "v1.0"; 47 | 48 | /// 49 | /// MS CLR 1.0 any version 50 | /// 51 | public const string MS_CLR_10_PREFIX_X86RETAIL = "v1.x86"; 52 | 53 | /// 54 | /// MS CLR 1.1 any version 55 | /// 56 | public const string MS_CLR_11_PREFIX = "v1.1"; 57 | 58 | /// 59 | /// MS CLR 2.0 any version 60 | /// 61 | public const string MS_CLR_20_PREFIX = "v2.0"; 62 | 63 | /// 64 | /// MS CLR 4.0 any version 65 | /// 66 | public const string MS_CLR_40_PREFIX = "v4.0"; 67 | 68 | /// 69 | /// ECMA 2002 version string 70 | /// 71 | public const string ECMA_2002 = "Standard CLI 2002"; 72 | 73 | /// 74 | /// ECMA 2005 version string 75 | /// 76 | public const string ECMA_2005 = "Standard CLI 2005"; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/DotNet/PublicKey.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using dnlib.Threading; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Represents a public key 8 | /// 9 | public sealed class PublicKey : PublicKeyBase { 10 | const AssemblyHashAlgorithm DEFAULT_ALGORITHM = AssemblyHashAlgorithm.SHA1; 11 | PublicKeyToken publicKeyToken; 12 | #if THREAD_SAFE 13 | readonly Lock theLock = Lock.Create(); 14 | #endif 15 | 16 | /// 17 | /// Gets the 18 | /// 19 | public override PublicKeyToken Token { 20 | get { 21 | #if THREAD_SAFE 22 | theLock.EnterWriteLock(); try { 23 | #endif 24 | if (publicKeyToken == null && !IsNullOrEmpty_NoLock) 25 | publicKeyToken = AssemblyHash.CreatePublicKeyToken(data); 26 | return publicKeyToken; 27 | #if THREAD_SAFE 28 | } finally { theLock.ExitWriteLock(); } 29 | #endif 30 | } 31 | } 32 | 33 | /// 34 | public override byte[] Data { 35 | get { 36 | #if THREAD_SAFE 37 | theLock.EnterReadLock(); try { 38 | #endif 39 | return data; 40 | #if THREAD_SAFE 41 | } finally { theLock.ExitReadLock(); } 42 | #endif 43 | } 44 | set { 45 | #if THREAD_SAFE 46 | theLock.EnterWriteLock(); try { 47 | #endif 48 | if (data == value) 49 | return; 50 | data = value; 51 | publicKeyToken = null; 52 | #if THREAD_SAFE 53 | } finally { theLock.ExitWriteLock(); } 54 | #endif 55 | } 56 | } 57 | 58 | /// 59 | /// Default constructor 60 | /// 61 | public PublicKey() { 62 | } 63 | 64 | /// 65 | /// Constructor 66 | /// 67 | /// Public key data 68 | public PublicKey(byte[] data) 69 | : base(data) { 70 | } 71 | 72 | /// 73 | /// Constructor 74 | /// 75 | /// Public key data as a hex string or the string "null" 76 | /// to set public key data to null 77 | public PublicKey(string hexString) 78 | : base(hexString) { 79 | } 80 | 81 | /// 82 | public override bool Equals(object obj) { 83 | if ((object)this == obj) 84 | return true; 85 | var other = obj as PublicKey; 86 | if (other == null) 87 | return false; 88 | return Utils.Equals(Data, other.Data); 89 | } 90 | 91 | /// 92 | public override int GetHashCode() { 93 | return Utils.GetHashCode(Data); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/DotNet/Writer/GuidHeap.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// #GUID heap 10 | /// 11 | public sealed class GuidHeap : HeapBase, IOffsetHeap { 12 | readonly List guids = new List(); 13 | Dictionary userRawData; 14 | 15 | /// 16 | public override string Name { 17 | get { return "#GUID"; } 18 | } 19 | 20 | /// 21 | /// Adds a guid to the #GUID heap 22 | /// 23 | /// The guid 24 | /// The index of the guid in the #GUID heap 25 | public uint Add(Guid? guid) { 26 | if (isReadOnly) 27 | throw new ModuleWriterException("Trying to modify #GUID when it's read-only"); 28 | if (guid == null) 29 | return 0; 30 | 31 | // The number of GUIDs will almost always be 1 so there's no need for a dictionary. 32 | // The only table that contains GUIDs is the Module table, and it has three GUID 33 | // columns. Only one of them (Mvid) is normally set and the others are null. 34 | int index = guids.IndexOf(guid.Value); 35 | if (index >= 0) 36 | return (uint)index + 1; 37 | 38 | guids.Add(guid.Value); 39 | return (uint)guids.Count; 40 | } 41 | 42 | /// 43 | public override uint GetRawLength() { 44 | return (uint)guids.Count * 16; 45 | } 46 | 47 | /// 48 | protected override void WriteToImpl(BinaryWriter writer) { 49 | uint offset = 0; 50 | foreach (var guid in guids) { 51 | byte[] rawData; 52 | if (userRawData == null || !userRawData.TryGetValue(offset, out rawData)) 53 | rawData = guid.ToByteArray(); 54 | writer.Write(rawData); 55 | offset += 16; 56 | } 57 | } 58 | 59 | /// 60 | public int GetRawDataSize(Guid data) { 61 | return 16; 62 | } 63 | 64 | /// 65 | public void SetRawData(uint offset, byte[] rawData) { 66 | if (rawData == null || rawData.Length != 16) 67 | throw new ArgumentException("Invalid size of GUID raw data"); 68 | if (userRawData == null) 69 | userRawData = new Dictionary(); 70 | userRawData[offset] = rawData; 71 | } 72 | 73 | /// 74 | public IEnumerable> GetAllRawData() { 75 | uint offset = 0; 76 | foreach (var guid in guids) { 77 | yield return new KeyValuePair(offset, guid.ToByteArray()); 78 | offset += 16; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/W32Resources/ResourceData.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.IO; 5 | using System.Threading; 6 | using dnlib.IO; 7 | 8 | namespace dnlib.W32Resources { 9 | /// 10 | /// A resource blob 11 | /// 12 | public sealed class ResourceData : ResourceDirectoryEntry, IDisposable { 13 | IBinaryReader reader; 14 | uint codePage; 15 | uint reserved; 16 | 17 | /// 18 | /// Gets/sets the data reader. This instance owns the reader. 19 | /// 20 | public IBinaryReader Data { 21 | get { return reader; } 22 | set { 23 | var oldValue = Interlocked.Exchange(ref reader, value); 24 | if (oldValue != value && oldValue != null) 25 | oldValue.Dispose(); 26 | } 27 | } 28 | 29 | /// 30 | /// Gets/sets the code page 31 | /// 32 | public uint CodePage { 33 | get { return codePage; } 34 | set { codePage = value; } 35 | } 36 | 37 | /// 38 | /// Gets/sets the reserved field 39 | /// 40 | public uint Reserved { 41 | get { return reserved; } 42 | set { reserved = value; } 43 | } 44 | 45 | /// 46 | /// Constructor 47 | /// 48 | /// Name 49 | public ResourceData(ResourceName name) 50 | : base(name) { 51 | } 52 | 53 | /// 54 | /// Constructor 55 | /// 56 | /// Raw data. This instance owns this reader. 57 | /// Name 58 | public ResourceData(ResourceName name, IBinaryReader reader) 59 | : base(name) { 60 | this.reader = reader; 61 | } 62 | 63 | /// 64 | /// Constructor 65 | /// 66 | /// Raw data. This instance owns this reader. 67 | /// Name 68 | /// Code page 69 | /// Reserved value 70 | public ResourceData(ResourceName name, IBinaryReader reader, uint codePage, uint reserved) 71 | : base(name) { 72 | this.reader = reader; 73 | this.codePage = codePage; 74 | this.reserved = reserved; 75 | } 76 | 77 | /// 78 | /// Gets the data as a . It shares the file position with 79 | /// 80 | public Stream ToDataStream() { 81 | return Data.CreateStream(); 82 | } 83 | 84 | /// 85 | public void Dispose() { 86 | var oldValue = Interlocked.Exchange(ref reader, null); 87 | if (oldValue != null) 88 | oldValue.Dispose(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/IO/MemoryStreamCreator.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics; 5 | using System.IO; 6 | 7 | namespace dnlib.IO { 8 | /// 9 | /// Creates s to partially access a byte[] 10 | /// 11 | /// 12 | [DebuggerDisplay("byte[]: O:{dataOffset} L:{dataLength} {theFileName}")] 13 | sealed class MemoryStreamCreator : IImageStreamCreator { 14 | byte[] data; 15 | int dataOffset; 16 | int dataLength; 17 | string theFileName; 18 | 19 | /// 20 | /// The file name 21 | /// 22 | public string FileName { 23 | get { return theFileName; } 24 | set { theFileName = value; } 25 | } 26 | 27 | /// 28 | public long Length { 29 | get { return dataLength; } 30 | } 31 | 32 | /// 33 | /// Constructor 34 | /// 35 | /// The data 36 | public MemoryStreamCreator(byte[] data) 37 | : this(data, 0, data.Length) { 38 | } 39 | 40 | /// 41 | /// Constructor 42 | /// 43 | /// The data 44 | /// Start offset in 45 | /// Length of data starting from 46 | /// If one of the args is invalid 47 | public MemoryStreamCreator(byte[] data, int offset, int length) { 48 | if (offset < 0) 49 | throw new ArgumentOutOfRangeException("offset"); 50 | if (length < 0 || offset + length < offset) 51 | throw new ArgumentOutOfRangeException("length"); 52 | if (offset + length > data.Length) 53 | throw new ArgumentOutOfRangeException("length"); 54 | this.data = data; 55 | this.dataOffset = offset; 56 | this.dataLength = length; 57 | } 58 | 59 | /// 60 | public IImageStream Create(FileOffset offset, long length) { 61 | if (offset < 0 || length < 0) 62 | return MemoryImageStream.CreateEmpty(); 63 | 64 | int offs = (int)Math.Min((long)dataLength, (long)offset); 65 | int len = (int)Math.Min((long)dataLength - offs, length); 66 | return new MemoryImageStream(offset, data, dataOffset + offs, len); 67 | } 68 | 69 | /// 70 | public IImageStream CreateFull() { 71 | return new MemoryImageStream(0, data, dataOffset, dataLength); 72 | } 73 | 74 | /// 75 | public void Dispose() { 76 | data = null; 77 | dataOffset = 0; 78 | dataLength = 0; 79 | theFileName = null; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /dnlib.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dnlib", "src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples", "Examples\Examples.csproj", "{F27E72B5-C4BD-40BF-AD19-4C8A99B55872}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|Mixed Platforms = Debug|Mixed Platforms 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|Mixed Platforms = Release|Mixed Platforms 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 21 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 22 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|x86.ActiveCfg = Debug|Any CPU 23 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 26 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|Mixed Platforms.Build.0 = Release|Any CPU 27 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|x86.ActiveCfg = Release|Any CPU 28 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Any CPU.ActiveCfg = Debug|x86 29 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 30 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|Mixed Platforms.Build.0 = Debug|x86 31 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.ActiveCfg = Debug|x86 32 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Debug|x86.Build.0 = Debug|x86 33 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Any CPU.ActiveCfg = Release|x86 34 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.ActiveCfg = Release|x86 35 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|Mixed Platforms.Build.0 = Release|x86 36 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.ActiveCfg = Release|x86 37 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872}.Release|x86.Build.0 = Release|x86 38 | EndGlobalSection 39 | GlobalSection(SolutionProperties) = preSolution 40 | HideSolutionNode = FALSE 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /src/PE/ImageNTHeaders.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using dnlib.IO; 5 | 6 | namespace dnlib.PE { 7 | /// 8 | /// Represents the IMAGE_NT_HEADERS PE section 9 | /// 10 | public sealed class ImageNTHeaders : FileSection { 11 | readonly uint signature; 12 | readonly ImageFileHeader imageFileHeader; 13 | readonly IImageOptionalHeader imageOptionalHeader; 14 | 15 | /// 16 | /// Returns the IMAGE_NT_HEADERS.Signature field 17 | /// 18 | public uint Signature { 19 | get { return signature; } 20 | } 21 | 22 | /// 23 | /// Returns the IMAGE_NT_HEADERS.FileHeader field 24 | /// 25 | public ImageFileHeader FileHeader { 26 | get { return imageFileHeader; } 27 | } 28 | 29 | /// 30 | /// Returns the IMAGE_NT_HEADERS.OptionalHeader field 31 | /// 32 | public IImageOptionalHeader OptionalHeader { 33 | get { return imageOptionalHeader; } 34 | } 35 | 36 | /// 37 | /// Constructor 38 | /// 39 | /// PE file reader pointing to the start of this section 40 | /// Verify section 41 | /// Thrown if verification fails 42 | public ImageNTHeaders(IImageStream reader, bool verify) { 43 | SetStartOffset(reader); 44 | this.signature = reader.ReadUInt32(); 45 | if (verify && this.signature != 0x4550) 46 | throw new BadImageFormatException("Invalid NT headers signature"); 47 | this.imageFileHeader = new ImageFileHeader(reader, verify); 48 | this.imageOptionalHeader = CreateImageOptionalHeader(reader, verify); 49 | SetEndoffset(reader); 50 | } 51 | 52 | /// 53 | /// Creates an IImageOptionalHeader 54 | /// 55 | /// PE file reader pointing to the start of the optional header 56 | /// Verify section 57 | /// The created IImageOptionalHeader 58 | /// Thrown if verification fails 59 | IImageOptionalHeader CreateImageOptionalHeader(IImageStream reader, bool verify) { 60 | ushort magic = reader.ReadUInt16(); 61 | reader.Position -= 2; 62 | switch (magic) { 63 | case 0x010B: return new ImageOptionalHeader32(reader, imageFileHeader.SizeOfOptionalHeader, verify); 64 | case 0x020B: return new ImageOptionalHeader64(reader, imageFileHeader.SizeOfOptionalHeader, verify); 65 | default: throw new BadImageFormatException("Invalid optional header magic"); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/DotNet/VariantType.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Variant type (VT_XXX in the Windows SDK) 6 | /// 7 | public enum VariantType : uint { 8 | /// 9 | Empty = 0, 10 | /// 11 | None = 0, 12 | /// 13 | Null = 1, 14 | /// 15 | I2 = 2, 16 | /// 17 | I4 = 3, 18 | /// 19 | R4 = 4, 20 | /// 21 | R8 = 5, 22 | /// 23 | CY = 6, 24 | /// 25 | Date = 7, 26 | /// 27 | BStr = 8, 28 | /// 29 | Dispatch = 9, 30 | /// 31 | Error = 10, 32 | /// 33 | Bool = 11, 34 | /// 35 | Variant = 12, 36 | /// 37 | Unknown = 13, 38 | /// 39 | Decimal = 14, 40 | /// 41 | I1 = 16, 42 | /// 43 | UI1 = 17, 44 | /// 45 | UI2 = 18, 46 | /// 47 | UI4 = 19, 48 | /// 49 | I8 = 20, 50 | /// 51 | UI8 = 21, 52 | /// 53 | Int = 22, 54 | /// 55 | UInt = 23, 56 | /// 57 | Void = 24, 58 | /// 59 | HResult = 25, 60 | /// 61 | Ptr = 26, 62 | /// 63 | SafeArray = 27, 64 | /// 65 | CArray = 28, 66 | /// 67 | UserDefined = 29, 68 | /// 69 | LPStr = 30, 70 | /// 71 | LPWStr = 31, 72 | /// 73 | Record = 36, 74 | /// 75 | IntPtr = 37, 76 | /// 77 | UIntPtr = 38, 78 | /// 79 | FileTime = 64, 80 | /// 81 | Blob = 65, 82 | /// 83 | Stream = 66, 84 | /// 85 | Storage = 67, 86 | /// 87 | StreamedObject = 68, 88 | /// 89 | StoredObject = 69, 90 | /// 91 | BlobObject = 70, 92 | /// 93 | CF = 71, 94 | /// 95 | CLSID = 72, 96 | /// 97 | VersionedStream = 73, 98 | /// 99 | BStrBlob = 0x0FFF, 100 | /// 101 | Vector = 0x1000, 102 | /// 103 | Array = 0x2000, 104 | /// 105 | ByRef = 0x4000, 106 | /// 107 | Reserved = 0x8000, 108 | /// 109 | Illegal = 0xFFFF, 110 | /// 111 | IllegalMasked = 0x0FFF, 112 | /// 113 | TypeMask = 0x0FFF, 114 | /// This wasn't present in the blob 115 | NotInitialized = 0xFFFFFFFF, 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/DotNet/MD/BlobStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using dnlib.IO; 4 | 5 | namespace dnlib.DotNet.MD { 6 | /// 7 | /// Represents the #Blob stream 8 | /// 9 | public sealed class BlobStream : HeapStream { 10 | static readonly byte[] noData = new byte[0]; 11 | 12 | /// 13 | public BlobStream() { 14 | } 15 | 16 | /// 17 | public BlobStream(IImageStream imageStream, StreamHeader streamHeader) 18 | : base(imageStream, streamHeader) { 19 | } 20 | 21 | /// 22 | /// Reads data 23 | /// 24 | /// Offset of data 25 | /// The data or null if invalid offset 26 | public byte[] Read(uint offset) { 27 | // The CLR has a special check for offset 0. It always interprets it as 28 | // 0-length data, even if that first byte isn't 0 at all. 29 | if (offset == 0) 30 | return noData; 31 | #if THREAD_SAFE 32 | theLock.EnterWriteLock(); try { 33 | #endif 34 | IImageStream reader; 35 | int size = GetReader_NoLock(offset, out reader); 36 | if (size < 0) 37 | return null; 38 | return reader.ReadBytes(size); 39 | #if THREAD_SAFE 40 | } finally { theLock.ExitWriteLock(); } 41 | #endif 42 | } 43 | 44 | /// 45 | /// Reads data just like , but returns an empty array if 46 | /// offset is invalid 47 | /// 48 | /// Offset of data 49 | /// The data 50 | public byte[] ReadNoNull(uint offset) { 51 | return Read(offset) ?? noData; 52 | } 53 | 54 | /// 55 | /// Creates a new sub stream of the #Blob stream that can access one blob 56 | /// 57 | /// Offset of blob 58 | /// A new stream 59 | public IImageStream CreateStream(uint offset) { 60 | #if THREAD_SAFE 61 | theLock.EnterWriteLock(); try { 62 | #endif 63 | IImageStream reader; 64 | int size = GetReader_NoLock(offset, out reader); 65 | if (size < 0) 66 | return MemoryImageStream.CreateEmpty(); 67 | return reader.Create((FileOffset)reader.Position, size); 68 | #if THREAD_SAFE 69 | } finally { theLock.ExitWriteLock(); } 70 | #endif 71 | } 72 | 73 | int GetReader_NoLock(uint offset, out IImageStream reader) { 74 | reader = null; 75 | if (!IsValidOffset(offset)) 76 | return -1; 77 | reader = GetReader_NoLock(offset); 78 | uint length; 79 | if (!reader.ReadCompressedUInt32(out length)) 80 | return -1; 81 | if (reader.Position + length < length || reader.Position + length > reader.Length) 82 | return -1; 83 | 84 | return (int)length; // length <= 0x1FFFFFFF so this cast does not make it negative 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Dss/SymbolDocument.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | 6 | namespace dnlib.DotNet.Pdb.Dss { 7 | sealed class SymbolDocument : ISymbolDocument { 8 | readonly ISymUnmanagedDocument document; 9 | 10 | public ISymUnmanagedDocument SymUnmanagedDocument { 11 | get { return document; } 12 | } 13 | 14 | public SymbolDocument(ISymUnmanagedDocument document) { 15 | this.document = document; 16 | } 17 | 18 | public Guid CheckSumAlgorithmId { 19 | get { 20 | Guid guid; 21 | document.GetCheckSumAlgorithmId(out guid); 22 | return guid; 23 | } 24 | } 25 | 26 | public Guid DocumentType { 27 | get { 28 | Guid guid; 29 | document.GetDocumentType(out guid); 30 | return guid; 31 | } 32 | } 33 | 34 | public bool HasEmbeddedSource { 35 | get { 36 | bool result; 37 | document.HasEmbeddedSource(out result); 38 | return result; 39 | } 40 | } 41 | 42 | public Guid Language { 43 | get { 44 | Guid guid; 45 | document.GetLanguage(out guid); 46 | return guid; 47 | } 48 | } 49 | 50 | public Guid LanguageVendor { 51 | get { 52 | Guid guid; 53 | document.GetLanguageVendor(out guid); 54 | return guid; 55 | } 56 | } 57 | 58 | public int SourceLength { 59 | get { 60 | uint result; 61 | document.GetSourceLength(out result); 62 | return (int)result; 63 | } 64 | } 65 | 66 | public string URL { 67 | get { 68 | uint count; 69 | document.GetURL(0, out count, null); 70 | var chars = new char[count]; 71 | document.GetURL((uint)chars.Length, out count, chars); 72 | if (chars.Length == 0) 73 | return string.Empty; 74 | return new string(chars, 0, chars.Length - 1); 75 | } 76 | } 77 | 78 | public int FindClosestLine(int line) { 79 | uint result; 80 | document.FindClosestLine((uint)line, out result); 81 | return (int)result; 82 | } 83 | 84 | public byte[] GetCheckSum() { 85 | uint bufSize; 86 | document.GetCheckSum(0, out bufSize, null); 87 | var buffer = new byte[bufSize]; 88 | document.GetCheckSum((uint)buffer.Length, out bufSize, buffer); 89 | return buffer; 90 | } 91 | 92 | public byte[] GetSourceRange(int startLine, int startColumn, int endLine, int endColumn) { 93 | uint bufSize; 94 | document.GetSourceRange((uint)startLine, (uint)startColumn, (uint)endLine, (uint)endColumn, 0, out bufSize, null); 95 | var buffer = new byte[bufSize]; 96 | document.GetSourceRange((uint)startLine, (uint)startColumn, (uint)endLine, (uint)endColumn, (uint)buffer.Length, out bufSize, buffer); 97 | return buffer; 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/DotNet/GenericParamContext.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | namespace dnlib.DotNet { 4 | /// 5 | /// Generic parameter context 6 | /// 7 | public struct GenericParamContext { 8 | /// 9 | /// Type context 10 | /// 11 | public readonly TypeDef Type; 12 | 13 | /// 14 | /// Method context 15 | /// 16 | public readonly MethodDef Method; 17 | 18 | /// 19 | /// true if and are both null 20 | /// 21 | public bool IsEmpty { 22 | get { return Type == null && Method == null; } 23 | } 24 | 25 | /// 26 | /// Creates a new instance and initializes the 27 | /// field to 's 28 | /// and the field to . 29 | /// 30 | /// Method 31 | /// A new instance 32 | public static GenericParamContext Create(MethodDef method) { 33 | if (method == null) 34 | return new GenericParamContext(); 35 | return new GenericParamContext(method.DeclaringType, method); 36 | } 37 | 38 | /// 39 | /// Creates a new instance and initializes the 40 | /// field to and the field 41 | /// to null 42 | /// 43 | /// Type 44 | /// A new instance 45 | public static GenericParamContext Create(TypeDef type) { 46 | return new GenericParamContext(type); 47 | } 48 | 49 | /// 50 | /// Constructor 51 | /// 52 | /// Type context 53 | public GenericParamContext(TypeDef type) { 54 | this.Type = type; 55 | this.Method = null; 56 | } 57 | 58 | /// 59 | /// Constructor. The field is set to null and NOT to 60 | /// 's . Use 61 | /// if you want that behavior. 62 | /// 63 | /// Method context 64 | public GenericParamContext(MethodDef method) { 65 | this.Type = null; 66 | this.Method = method; 67 | } 68 | 69 | /// 70 | /// Constructor 71 | /// 72 | /// Type context 73 | /// Method context 74 | public GenericParamContext(TypeDef type, MethodDef method) { 75 | this.Type = type; 76 | this.Method = method; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/DotNet/ModuleCreationOptions.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics.SymbolStore; 4 | using dnlib.IO; 5 | using dnlib.DotNet.Pdb; 6 | 7 | namespace dnlib.DotNet { 8 | /// 9 | /// creation options 10 | /// 11 | public sealed class ModuleCreationOptions { 12 | internal static readonly ModuleCreationOptions Default = new ModuleCreationOptions(); 13 | 14 | /// 15 | /// Module context 16 | /// 17 | public ModuleContext Context { get; set; } 18 | 19 | /// 20 | /// Set this if you want to decide how to create the PDB symbol reader. You don't need to 21 | /// initialize or . 22 | /// 23 | public CreateSymbolReaderDelegate CreateSymbolReader { get; set; } 24 | 25 | /// 26 | /// Which PDB reader to use. Default is . 27 | /// 28 | public PdbImplType PdbImplementation { get; set; } 29 | 30 | /// 31 | /// Set it to A) the path (string) of the PDB file, B) the data (byte[]) of the PDB file or 32 | /// C) to an of the PDB data. The will 33 | /// be owned by the module. You don't need to initialize 34 | /// or 35 | /// 36 | public object PdbFileOrData { get; set; } 37 | 38 | /// 39 | /// If true, will load the PDB file from disk if present. You don't need to 40 | /// initialize or . 41 | /// 42 | public bool TryToLoadPdbFromDisk { get; set; } 43 | 44 | /// 45 | /// corlib assembly reference to use or null if the default one from the opened 46 | /// module should be used. 47 | /// 48 | public AssemblyRef CorLibAssemblyRef { get; set; } 49 | 50 | /// 51 | /// Default constructor 52 | /// 53 | public ModuleCreationOptions() { 54 | this.PdbImplementation = PdbImplType.Default; 55 | } 56 | 57 | /// 58 | /// Constructor 59 | /// 60 | /// Module context 61 | public ModuleCreationOptions(ModuleContext context) { 62 | this.Context = context; 63 | this.PdbImplementation = PdbImplType.Default; 64 | } 65 | } 66 | 67 | /// 68 | /// Creates a 69 | /// 70 | /// Module 71 | /// A instance for (and now owned by) 72 | /// or null. 73 | public delegate ISymbolReader CreateSymbolReaderDelegate(ModuleDefMD module); 74 | } 75 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/Managed/SymbolReaderCreator.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | using System.IO; 6 | using System.Security; 7 | using dnlib.IO; 8 | 9 | namespace dnlib.DotNet.Pdb.Managed { 10 | /// 11 | /// Creates a instance 12 | /// 13 | public static class SymbolReaderCreator { 14 | /// 15 | /// Creates a new instance 16 | /// 17 | /// Path to assembly 18 | /// A new instance or null if there's no PDB 19 | /// file. 20 | public static ISymbolReader CreateFromAssemblyFile(string assemblyFileName) { 21 | return Create(Path.ChangeExtension(assemblyFileName, "pdb")); 22 | } 23 | 24 | /// 25 | /// Creates a new instance 26 | /// 27 | /// Path to PDB file 28 | /// A new instance or null if there's no PDB 29 | /// file on disk. 30 | public static ISymbolReader Create(string pdbFileName) { 31 | return Create(OpenImageStream(pdbFileName)); 32 | } 33 | 34 | /// 35 | /// Creates a new instance 36 | /// 37 | /// PDB file data 38 | /// A new instance or null. 39 | public static ISymbolReader Create(byte[] pdbData) { 40 | return Create(MemoryImageStream.Create(pdbData)); 41 | } 42 | 43 | /// 44 | /// Creates a new instance 45 | /// 46 | /// PDB file stream which is now owned by this method 47 | /// A new instance or null. 48 | public static ISymbolReader Create(IImageStream pdbStream) { 49 | if (pdbStream == null) 50 | return null; 51 | try { 52 | var pdbReader = new PdbReader(); 53 | pdbReader.Read(pdbStream); 54 | return pdbReader; 55 | } 56 | catch (IOException) { 57 | } 58 | catch (UnauthorizedAccessException) { 59 | } 60 | catch (SecurityException) { 61 | } 62 | finally { 63 | if (pdbStream != null) 64 | pdbStream.Dispose(); 65 | } 66 | return null; 67 | } 68 | 69 | static IImageStream OpenImageStream(string fileName) { 70 | try { 71 | if (!File.Exists(fileName)) 72 | return null; 73 | return ImageStreamCreator.CreateImageStream(fileName); 74 | } 75 | catch (IOException) { 76 | } 77 | catch (UnauthorizedAccessException) { 78 | } 79 | catch (SecurityException) { 80 | } 81 | return null; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/DotNet/MethodAttributes.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | 5 | namespace dnlib.DotNet { 6 | /// 7 | /// Method attributes, see CorHdr.h/CorMethodAttr 8 | /// 9 | [Flags] 10 | public enum MethodAttributes : ushort { 11 | /// member access mask - Use this mask to retrieve accessibility information. 12 | MemberAccessMask = 0x0007, 13 | /// Member not referenceable. 14 | PrivateScope = 0x0000, 15 | /// Member not referenceable. 16 | CompilerControlled = PrivateScope, 17 | /// Accessible only by the parent type. 18 | Private = 0x0001, 19 | /// Accessible by sub-types only in this Assembly. 20 | FamANDAssem = 0x0002, 21 | /// Accessibly by anyone in the Assembly. 22 | Assembly = 0x0003, 23 | /// Accessible only by type and sub-types. 24 | Family = 0x0004, 25 | /// Accessibly by sub-types anywhere, plus anyone in assembly. 26 | FamORAssem = 0x0005, 27 | /// Accessibly by anyone who has visibility to this scope. 28 | Public = 0x0006, 29 | 30 | /// Defined on type, else per instance. 31 | Static = 0x0010, 32 | /// Method may not be overridden. 33 | Final = 0x0020, 34 | /// Method virtual. 35 | Virtual = 0x0040, 36 | /// Method hides by name+sig, else just by name. 37 | HideBySig = 0x0080, 38 | 39 | /// vtable layout mask - Use this mask to retrieve vtable attributes. 40 | VtableLayoutMask = 0x0100, 41 | /// The default. 42 | ReuseSlot = 0x0000, 43 | /// Method always gets a new slot in the vtable. 44 | NewSlot = 0x0100, 45 | 46 | /// Overridability is the same as the visibility. 47 | CheckAccessOnOverride = 0x0200, 48 | /// Method does not provide an implementation. 49 | Abstract = 0x0400, 50 | /// Method is special. Name describes how. 51 | SpecialName = 0x0800, 52 | 53 | /// Implementation is forwarded through pinvoke. 54 | PinvokeImpl = 0x2000, 55 | /// Implementation is forwarded through pinvoke. 56 | PInvokeImpl = PinvokeImpl, 57 | /// Managed method exported via thunk to unmanaged code. 58 | UnmanagedExport = 0x0008, 59 | 60 | /// Runtime should check name encoding. 61 | RTSpecialName = 0x1000, 62 | /// Method has security associate with it. 63 | HasSecurity = 0x4000, 64 | /// Method calls another method containing security code. 65 | RequireSecObject = 0x8000, 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/DotNet/Writer/NetResources.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using dnlib.IO; 7 | using dnlib.PE; 8 | 9 | namespace dnlib.DotNet.Writer { 10 | /// 11 | /// .NET resources 12 | /// 13 | public sealed class NetResources : IChunk { 14 | readonly List resources = new List(); 15 | readonly uint alignment; 16 | uint length; 17 | bool setOffsetCalled; 18 | FileOffset offset; 19 | RVA rva; 20 | 21 | /// 22 | public FileOffset FileOffset { 23 | get { return offset; } 24 | } 25 | 26 | /// 27 | public RVA RVA { 28 | get { return rva; } 29 | } 30 | 31 | /// 32 | /// Gets offset of next resource. This offset is relative to the start of 33 | /// the .NET resources and is always aligned. 34 | /// 35 | public uint NextOffset { 36 | get { return length; } 37 | } 38 | 39 | /// 40 | /// Constructor 41 | /// 42 | /// Alignment of all resources 43 | public NetResources(uint alignment) { 44 | this.alignment = alignment; 45 | } 46 | 47 | /// 48 | /// Adds a resource 49 | /// 50 | /// The resource data 51 | /// The resource data 52 | public ByteArrayChunk Add(IImageStream stream) { 53 | if (setOffsetCalled) 54 | throw new InvalidOperationException("SetOffset() has already been called"); 55 | var rawData = stream.ReadAllBytes(); 56 | length = Utils.AlignUp(length + 4 + (uint)rawData.Length, alignment); 57 | var data = new ByteArrayChunk(rawData); 58 | resources.Add(data); 59 | return data; 60 | } 61 | 62 | /// 63 | public void SetOffset(FileOffset offset, RVA rva) { 64 | setOffsetCalled = true; 65 | this.offset = offset; 66 | this.rva = rva; 67 | foreach (var resource in resources) { 68 | resource.SetOffset(offset + 4, rva + 4); 69 | uint len = 4 + resource.GetFileLength(); 70 | offset = (offset + len).AlignUp(alignment); 71 | rva = (rva + len).AlignUp(alignment); 72 | } 73 | } 74 | 75 | /// 76 | public uint GetFileLength() { 77 | return length; 78 | } 79 | 80 | /// 81 | public uint GetVirtualSize() { 82 | return GetFileLength(); 83 | } 84 | 85 | /// 86 | public void WriteTo(BinaryWriter writer) { 87 | RVA rva2 = rva; 88 | foreach (var resourceData in resources) { 89 | writer.Write(resourceData.GetFileLength()); 90 | resourceData.VerifyWriteTo(writer); 91 | rva2 += 4 + resourceData.GetFileLength(); 92 | int padding = (int)rva2.AlignUp(alignment) - (int)rva2; 93 | writer.WriteZeros(padding); 94 | rva2 += (uint)padding; 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/PE/ImageFileHeader.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using dnlib.IO; 5 | 6 | namespace dnlib.PE { 7 | /// 8 | /// Represents the IMAGE_FILE_HEADER PE section 9 | /// 10 | public sealed class ImageFileHeader : FileSection { 11 | readonly Machine machine; 12 | readonly ushort numberOfSections; 13 | readonly uint timeDateStamp; 14 | readonly uint pointerToSymbolTable; 15 | readonly uint numberOfSymbols; 16 | readonly ushort sizeOfOptionalHeader; 17 | readonly Characteristics characteristics; 18 | 19 | /// 20 | /// Returns the IMAGE_FILE_HEADER.Machine field 21 | /// 22 | public Machine Machine { 23 | get { return machine; } 24 | } 25 | 26 | /// 27 | /// Returns the IMAGE_FILE_HEADER.NumberOfSections field 28 | /// 29 | public int NumberOfSections { 30 | get { return numberOfSections; } 31 | } 32 | 33 | /// 34 | /// Returns the IMAGE_FILE_HEADER.TimeDateStamp field 35 | /// 36 | public uint TimeDateStamp { 37 | get { return timeDateStamp; } 38 | } 39 | 40 | /// 41 | /// Returns the IMAGE_FILE_HEADER.PointerToSymbolTable field 42 | /// 43 | public uint PointerToSymbolTable { 44 | get { return pointerToSymbolTable; } 45 | } 46 | 47 | /// 48 | /// Returns the IMAGE_FILE_HEADER.NumberOfSymbols field 49 | /// 50 | public uint NumberOfSymbols { 51 | get { return numberOfSymbols; } 52 | } 53 | 54 | /// 55 | /// Returns the IMAGE_FILE_HEADER.SizeOfOptionalHeader field 56 | /// 57 | public uint SizeOfOptionalHeader { 58 | get { return sizeOfOptionalHeader; } 59 | } 60 | 61 | /// 62 | /// Returns the IMAGE_FILE_HEADER.Characteristics field 63 | /// 64 | public Characteristics Characteristics { 65 | get { return characteristics; } 66 | } 67 | 68 | /// 69 | /// Constructor 70 | /// 71 | /// PE file reader pointing to the start of this section 72 | /// Verify section 73 | /// Thrown if verification fails 74 | public ImageFileHeader(IImageStream reader, bool verify) { 75 | SetStartOffset(reader); 76 | this.machine = (Machine)reader.ReadUInt16(); 77 | this.numberOfSections = reader.ReadUInt16(); 78 | this.timeDateStamp = reader.ReadUInt32(); 79 | this.pointerToSymbolTable = reader.ReadUInt32(); 80 | this.numberOfSymbols = reader.ReadUInt32(); 81 | this.sizeOfOptionalHeader = reader.ReadUInt16(); 82 | this.characteristics = (Characteristics)reader.ReadUInt16(); 83 | SetEndoffset(reader); 84 | if (verify && this.sizeOfOptionalHeader == 0) 85 | throw new BadImageFormatException("Invalid SizeOfOptionalHeader"); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Examples/Example2.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | 4 | namespace dnlib.Examples { 5 | public class Example2 { 6 | // This will open the current assembly, add a new class and method to it, 7 | // and then save the assembly to disk. 8 | public static void Run() { 9 | // Open the current module 10 | ModuleDefMD mod = ModuleDefMD.Load(typeof(Example2).Module); 11 | 12 | // Create a new public class that derives from System.Object 13 | TypeDef type1 = new TypeDefUser("My.Namespace", "MyType", 14 | mod.CorLibTypes.Object.TypeDefOrRef); 15 | type1.Attributes = TypeAttributes.Public | TypeAttributes.AutoLayout | 16 | TypeAttributes.Class | TypeAttributes.AnsiClass; 17 | // Make sure to add it to the module or any other type in the module. This is 18 | // not a nested type, so add it to mod.Types. 19 | mod.Types.Add(type1); 20 | 21 | // Create a public static System.Int32 field called MyField 22 | FieldDef field1 = new FieldDefUser("MyField", 23 | new FieldSig(mod.CorLibTypes.Int32), 24 | FieldAttributes.Public | FieldAttributes.Static); 25 | // Add it to the type we created earlier 26 | type1.Fields.Add(field1); 27 | 28 | // Add a static method that adds both inputs and the static field 29 | // and returns the result 30 | MethodImplAttributes methImplFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; 31 | MethodAttributes methFlags = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot; 32 | MethodDef meth1 = new MethodDefUser("MyMethod", 33 | MethodSig.CreateStatic(mod.CorLibTypes.Int32, mod.CorLibTypes.Int32, mod.CorLibTypes.Int32), 34 | methImplFlags, methFlags); 35 | type1.Methods.Add(meth1); 36 | 37 | // Create the CIL method body 38 | CilBody body = new CilBody(); 39 | meth1.Body = body; 40 | // Name the 1st and 2nd args a and b, respectively 41 | meth1.ParamDefs.Add(new ParamDefUser("a", 1)); 42 | meth1.ParamDefs.Add(new ParamDefUser("b", 2)); 43 | 44 | // Create a local. We don't really need it but let's add one anyway 45 | Local local1 = new Local(mod.CorLibTypes.Int32); 46 | body.Variables.Add(local1); 47 | 48 | // Add the instructions, and use the useless local 49 | body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction()); 50 | body.Instructions.Add(OpCodes.Ldarg_1.ToInstruction()); 51 | body.Instructions.Add(OpCodes.Add.ToInstruction()); 52 | body.Instructions.Add(OpCodes.Ldsfld.ToInstruction(field1)); 53 | body.Instructions.Add(OpCodes.Add.ToInstruction()); 54 | body.Instructions.Add(OpCodes.Stloc.ToInstruction(local1)); 55 | body.Instructions.Add(OpCodes.Ldloc.ToInstruction(local1)); 56 | body.Instructions.Add(OpCodes.Ret.ToInstruction()); 57 | 58 | // Save the assembly to a file on disk 59 | mod.Write(@"C:\saved-assembly.dll"); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Utils/UserValue.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.Diagnostics; 4 | using dnlib.Threading; 5 | 6 | namespace dnlib.Utils { 7 | /// 8 | /// Lazily returns the original value if the user hasn't overwritten the value 9 | /// 10 | /// Value type 11 | [DebuggerDisplay("{value}")] 12 | struct UserValue { 13 | #if THREAD_SAFE 14 | Lock theLock; 15 | #endif 16 | MFunc readOriginalValue; 17 | TValue value; 18 | bool isUserValue; 19 | bool isValueInitialized; 20 | 21 | #if THREAD_SAFE 22 | /// 23 | /// Sets the lock that protects the data 24 | /// 25 | public Lock Lock { 26 | set { theLock = value; } 27 | } 28 | #endif 29 | 30 | /// 31 | /// Set a delegate instance that will return the original value 32 | /// 33 | public MFunc ReadOriginalValue { 34 | set { readOriginalValue = value; } 35 | } 36 | 37 | /// 38 | /// Gets/sets the value 39 | /// 40 | /// The getter returns the original value if the value hasn't been initialized. 41 | public TValue Value { 42 | get { 43 | #if THREAD_SAFE 44 | if (theLock != null) theLock.EnterWriteLock(); try { 45 | #endif 46 | if (!isValueInitialized) { 47 | value = readOriginalValue(); 48 | readOriginalValue = null; 49 | isValueInitialized = true; 50 | } 51 | return value; 52 | #if THREAD_SAFE 53 | } finally { if (theLock != null) theLock.ExitWriteLock(); } 54 | #endif 55 | } 56 | set { 57 | #if THREAD_SAFE 58 | if (theLock != null) theLock.EnterWriteLock(); try { 59 | #endif 60 | this.value = value; 61 | readOriginalValue = null; 62 | isUserValue = true; 63 | isValueInitialized = true; 64 | #if THREAD_SAFE 65 | } finally { if (theLock != null) theLock.ExitWriteLock(); } 66 | #endif 67 | } 68 | } 69 | 70 | /// 71 | /// Returns true if the value has been initialized 72 | /// 73 | public bool IsValueInitialized { 74 | #if THREAD_SAFE 75 | get { 76 | if (theLock != null) 77 | theLock.EnterReadLock(); 78 | try { 79 | return isValueInitialized; 80 | } 81 | finally { if (theLock != null) theLock.ExitReadLock(); } 82 | } 83 | #else 84 | get { return isValueInitialized; } 85 | #endif 86 | } 87 | 88 | /// 89 | /// Returns true if the value was set by the user 90 | /// 91 | public bool IsUserValue { 92 | #if THREAD_SAFE 93 | get { 94 | if (theLock != null) 95 | theLock.EnterReadLock(); 96 | try { 97 | return isUserValue; 98 | } 99 | finally { if (theLock != null) theLock.ExitReadLock(); } 100 | } 101 | #else 102 | get { return isUserValue; } 103 | #endif 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/DotNet/Writer/DebugDirectory.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.IO; 5 | using dnlib.DotNet.Pdb; 6 | using dnlib.IO; 7 | using dnlib.PE; 8 | 9 | namespace dnlib.DotNet.Writer { 10 | /// 11 | /// Debug directory chunk 12 | /// 13 | public sealed class DebugDirectory : IChunk { 14 | FileOffset offset; 15 | RVA rva; 16 | bool dontWriteAnything; 17 | uint length; 18 | internal IMAGE_DEBUG_DIRECTORY debugDirData; 19 | uint timeDateStamp; 20 | byte[] data; 21 | 22 | /// 23 | /// Size of 24 | /// 25 | public const int HEADER_SIZE = 28; 26 | 27 | /// 28 | /// Gets/sets the time date stamp that should be written. This should be the same time date 29 | /// stamp that is written to the PE header. 30 | /// 31 | public uint TimeDateStamp { 32 | get { return timeDateStamp; } 33 | set { timeDateStamp = value; } 34 | } 35 | 36 | /// 37 | /// Gets/sets the raw debug data 38 | /// 39 | public byte[] Data { 40 | get { return data; } 41 | set { data = value; } 42 | } 43 | 44 | /// 45 | /// Set it to true if eg. the PDB file couldn't be created. If true, the size 46 | /// of this chunk will be 0. 47 | /// 48 | public bool DontWriteAnything { 49 | get { return dontWriteAnything; } 50 | set { 51 | if (length != 0) 52 | throw new InvalidOperationException("SetOffset() has already been called"); 53 | dontWriteAnything = value; 54 | } 55 | } 56 | 57 | /// 58 | public FileOffset FileOffset { 59 | get { return offset; } 60 | } 61 | 62 | /// 63 | public RVA RVA { 64 | get { return rva; } 65 | } 66 | 67 | /// 68 | public void SetOffset(FileOffset offset, RVA rva) { 69 | this.offset = offset; 70 | this.rva = rva; 71 | 72 | length = HEADER_SIZE; 73 | if (data != null) // Could be null if dontWriteAnything is true 74 | length += (uint)data.Length; 75 | } 76 | 77 | /// 78 | public uint GetFileLength() { 79 | if (dontWriteAnything) 80 | return 0; 81 | return length; 82 | } 83 | 84 | /// 85 | public uint GetVirtualSize() { 86 | return GetFileLength(); 87 | } 88 | 89 | /// 90 | public void WriteTo(BinaryWriter writer) { 91 | if (dontWriteAnything) 92 | return; 93 | 94 | writer.Write(debugDirData.Characteristics); 95 | writer.Write(timeDateStamp); 96 | writer.Write(debugDirData.MajorVersion); 97 | writer.Write(debugDirData.MinorVersion); 98 | writer.Write(debugDirData.Type); 99 | writer.Write(debugDirData.SizeOfData); 100 | writer.Write((uint)rva + HEADER_SIZE); 101 | writer.Write((uint)offset + HEADER_SIZE); 102 | writer.Write(data); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Examples/Examples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {F27E72B5-C4BD-40BF-AD19-4C8A99B55872} 9 | Exe 10 | Properties 11 | dnlib.Examples 12 | dnlib.Examples 13 | v4.6 14 | 512 15 | 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | true 27 | false 28 | 29 | 30 | x86 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | false 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {FDFC1237-143F-4919-8318-4926901F4639} 54 | dnlib 55 | 56 | 57 | 58 | 59 | 60 | 61 | 68 | -------------------------------------------------------------------------------- /src/DotNet/Pdb/ISymbolWriter2.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.Diagnostics.SymbolStore; 5 | using dnlib.DotNet.Writer; 6 | 7 | namespace dnlib.DotNet.Pdb { 8 | /// 9 | /// IMAGE_DEBUG_DIRECTORY 10 | /// 11 | public struct IMAGE_DEBUG_DIRECTORY { 12 | #pragma warning disable 1591 13 | public uint Characteristics; 14 | public uint TimeDateStamp; 15 | public ushort MajorVersion; 16 | public ushort MinorVersion; 17 | public uint Type; 18 | public uint SizeOfData; 19 | public uint AddressOfRawData; 20 | public uint PointerToRawData; 21 | #pragma warning restore 1591 22 | } 23 | 24 | /// 25 | /// Implements and adds a few extra methods we need that are part of 26 | /// ISymUnmanagedWriter and ISymUnmanagedWriter2 but not present in 27 | /// . 28 | /// 29 | public interface ISymbolWriter2 : ISymbolWriter, IDisposable { 30 | /// 31 | /// Same as except that this method has an 32 | /// extra that specifies the size of all the arrays. 33 | /// 34 | /// Document 35 | /// Size of the arrays 36 | /// Offsets 37 | /// Start lines 38 | /// Start columns 39 | /// End lines 40 | /// End columns 41 | void DefineSequencePoints(ISymbolDocumentWriter document, uint arraySize, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns); 42 | 43 | /// 44 | /// Gets debug info. See ISymUnmanagedWriter.GetDebugInfo() 45 | /// 46 | /// Updated by writer 47 | /// Debug data for the symbol store 48 | byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY pIDD); 49 | 50 | /// 51 | /// Define a local. See ISymUnmanagedWriter2.DefineLocalVariable2() 52 | /// 53 | /// Name 54 | /// Attributes 55 | /// Signature token 56 | /// Address kind 57 | /// Address #1 58 | /// Address #2 59 | /// Address #3 60 | /// Start offset 61 | /// End offset 62 | void DefineLocalVariable2(string name, uint attributes, uint sigToken, uint addrKind, uint addr1, uint addr2, uint addr3, uint startOffset, uint endOffset); 63 | 64 | /// 65 | /// Initializes this instance. This must be called before any other method. 66 | /// 67 | /// Metadata 68 | void Initialize(MetaData metaData); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/DotNet/Writer/PESection.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using System.Text; 5 | using dnlib.PE; 6 | 7 | namespace dnlib.DotNet.Writer { 8 | /// 9 | /// A PE section 10 | /// 11 | public sealed class PESection : ChunkList { 12 | string name; 13 | uint characteristics; 14 | 15 | /// 16 | /// Gets the name 17 | /// 18 | public string Name { 19 | get { return name; } 20 | set { name = value; } 21 | } 22 | 23 | /// 24 | /// Gets the Characteristics 25 | /// 26 | public uint Characteristics { 27 | get { return characteristics; } 28 | set { characteristics = value; } 29 | } 30 | 31 | /// 32 | /// true if this is a code section 33 | /// 34 | public bool IsCode { 35 | get { return (characteristics & 0x20) != 0; } 36 | } 37 | 38 | /// 39 | /// true if this is an initialized data section 40 | /// 41 | public bool IsInitializedData { 42 | get { return (characteristics & 0x40) != 0; } 43 | } 44 | 45 | /// 46 | /// true if this is an uninitialized data section 47 | /// 48 | public bool IsUninitializedData { 49 | get { return (characteristics & 0x80) != 0; } 50 | } 51 | 52 | /// 53 | /// Constructor 54 | /// 55 | /// Section name 56 | /// Section characteristics 57 | public PESection(string name, uint characteristics) { 58 | this.name = name; 59 | this.characteristics = characteristics; 60 | } 61 | 62 | /// 63 | /// Writes the section header to at its current position. 64 | /// Returns aligned virtual size (aligned to ) 65 | /// 66 | /// Writer 67 | /// File alignment 68 | /// Section alignment 69 | /// Current 70 | public uint WriteHeaderTo(BinaryWriter writer, uint fileAlignment, uint sectionAlignment, uint rva) { 71 | uint vs = GetVirtualSize(); 72 | uint fileLen = GetFileLength(); 73 | uint alignedVs = Utils.AlignUp(vs, sectionAlignment); 74 | uint rawSize = Utils.AlignUp(fileLen, fileAlignment); 75 | uint dataOffset = (uint)FileOffset; 76 | 77 | writer.Write(Encoding.UTF8.GetBytes(Name + "\0\0\0\0\0\0\0\0"), 0, 8); 78 | writer.Write(vs); // VirtualSize 79 | writer.Write((uint)rva); // VirtualAddress 80 | writer.Write(rawSize); // SizeOfRawData 81 | writer.Write(dataOffset); // PointerToRawData 82 | writer.Write(0); // PointerToRelocations 83 | writer.Write(0); // PointerToLinenumbers 84 | writer.Write((ushort)0); // NumberOfRelocations 85 | writer.Write((ushort)0); // NumberOfLinenumbers 86 | writer.Write(Characteristics); 87 | 88 | return alignedVs; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/IO/BinaryReaderStream.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System; 4 | using System.IO; 5 | 6 | namespace dnlib.IO { 7 | /// 8 | /// A class that can be used when you have a 9 | /// but must use a 10 | /// 11 | sealed class BinaryReaderStream : Stream { 12 | IBinaryReader reader; 13 | readonly bool ownsReader; 14 | 15 | /// 16 | /// Constructor 17 | /// 18 | /// Reader. This instance does NOT own this reader. 19 | public BinaryReaderStream(IBinaryReader reader) 20 | : this(reader, false) { 21 | } 22 | 23 | /// 24 | /// Constructor 25 | /// 26 | /// Reader 27 | /// true if this instance owns 28 | public BinaryReaderStream(IBinaryReader reader, bool ownsReader) { 29 | this.reader = reader; 30 | this.ownsReader = ownsReader; 31 | } 32 | 33 | /// 34 | public override bool CanRead { 35 | get { return true; } 36 | } 37 | 38 | /// 39 | public override bool CanSeek { 40 | get { return true; } 41 | } 42 | 43 | /// 44 | public override bool CanWrite { 45 | get { return false; } 46 | } 47 | 48 | /// 49 | public override void Flush() { 50 | } 51 | 52 | /// 53 | public override long Length { 54 | get { return reader.Length; } 55 | } 56 | 57 | /// 58 | public override long Position { 59 | get { return reader.Position; } 60 | set { reader.Position = value; } 61 | } 62 | 63 | /// 64 | public override int Read(byte[] buffer, int offset, int count) { 65 | return reader.Read(buffer, offset, count); 66 | } 67 | 68 | /// 69 | public override int ReadByte() { 70 | try { 71 | return reader.ReadByte(); 72 | } 73 | catch (IOException) { 74 | return -1; 75 | } 76 | } 77 | 78 | /// 79 | public override long Seek(long offset, SeekOrigin origin) { 80 | switch (origin) { 81 | case SeekOrigin.Begin: Position = offset; break; 82 | case SeekOrigin.Current:Position += offset; break; 83 | case SeekOrigin.End: Position = Length + offset; break; 84 | } 85 | return Position; 86 | } 87 | 88 | /// 89 | public override void SetLength(long value) { 90 | throw new NotImplementedException(); 91 | } 92 | 93 | /// 94 | public override void Write(byte[] buffer, int offset, int count) { 95 | throw new NotImplementedException(); 96 | } 97 | 98 | /// 99 | protected override void Dispose(bool disposing) { 100 | if (disposing) { 101 | var r = reader; 102 | if (ownsReader && r != null) 103 | r.Dispose(); 104 | reader = null; 105 | } 106 | base.Dispose(disposing); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/DotNet/Writer/ImportDirectory.cs: -------------------------------------------------------------------------------- 1 | // dnlib: See LICENSE.txt for more info 2 | 3 | using System.IO; 4 | using System.Text; 5 | using dnlib.IO; 6 | using dnlib.PE; 7 | 8 | namespace dnlib.DotNet.Writer { 9 | /// 10 | /// Import directory chunk 11 | /// 12 | public sealed class ImportDirectory : IChunk { 13 | FileOffset offset; 14 | RVA rva; 15 | bool isExeFile; 16 | uint length; 17 | RVA importLookupTableRVA; 18 | RVA corXxxMainRVA; 19 | RVA mscoreeDllRVA; 20 | int stringsPadding; 21 | 22 | /// 23 | /// Gets/sets the 24 | /// 25 | public ImportAddressTable ImportAddressTable { get; set; } 26 | 27 | /// 28 | /// Gets the RVA of _CorDllMain/_CorExeMain in the import lookup table 29 | /// 30 | public RVA CorXxxMainRVA { 31 | get { return corXxxMainRVA; } 32 | } 33 | 34 | /// 35 | /// Gets RVA of _CorExeMain/_CorDllMain in the IAT 36 | /// 37 | public RVA IatCorXxxMainRVA { 38 | get { return ImportAddressTable.RVA; } 39 | } 40 | 41 | /// 42 | /// Gets/sets a value indicating whether this is a EXE or a DLL file 43 | /// 44 | public bool IsExeFile { 45 | get { return isExeFile; } 46 | set { isExeFile = value; } 47 | } 48 | 49 | /// 50 | public FileOffset FileOffset { 51 | get { return offset; } 52 | } 53 | 54 | /// 55 | public RVA RVA { 56 | get { return rva; } 57 | } 58 | 59 | const uint STRINGS_ALIGNMENT = 16; 60 | 61 | /// 62 | public void SetOffset(FileOffset offset, RVA rva) { 63 | this.offset = offset; 64 | this.rva = rva; 65 | 66 | length = 0x28; 67 | importLookupTableRVA = rva + length; 68 | length += 8; 69 | 70 | stringsPadding = (int)(rva.AlignUp(STRINGS_ALIGNMENT) - rva); 71 | length += (uint)stringsPadding; 72 | corXxxMainRVA = rva + length; 73 | length += 0xE; 74 | mscoreeDllRVA = rva + length; 75 | length += 0xC; 76 | length++; 77 | } 78 | 79 | /// 80 | public uint GetFileLength() { 81 | return length; 82 | } 83 | 84 | /// 85 | public uint GetVirtualSize() { 86 | return GetFileLength(); 87 | } 88 | 89 | /// 90 | public void WriteTo(BinaryWriter writer) { 91 | writer.Write((uint)importLookupTableRVA); 92 | writer.Write(0); // DateTimeStamp 93 | writer.Write(0); // ForwarderChain 94 | writer.Write((uint)mscoreeDllRVA); // Name 95 | writer.Write((uint)ImportAddressTable.RVA); 96 | writer.Write(0UL); 97 | writer.Write(0UL); 98 | writer.Write(0); 99 | 100 | // ImportLookupTable 101 | writer.Write((uint)corXxxMainRVA); 102 | writer.Write(0); 103 | 104 | writer.WriteZeros(stringsPadding); 105 | writer.Write((ushort)0); 106 | writer.Write(Encoding.UTF8.GetBytes(IsExeFile ? "_CorExeMain\0" : "_CorDllMain\0")); 107 | writer.Write(Encoding.UTF8.GetBytes("mscoree.dll\0")); 108 | 109 | writer.Write((byte)0); 110 | } 111 | } 112 | } 113 | --------------------------------------------------------------------------------