private DevirtualisationContext CreateDevirtualisationContext(DevirtualisationOptions options) { string workingDirectory = Path.GetDirectoryName(options.InputFile); // Open target PE. Logger.Log(Tag, $"Opening target file {options.InputFile}..."); var peFile = PEFile.FromFile(options.InputFile); // Create #Koi stream aware metadata reader. var streamReader = options.OverrideKoiStreamData ? new DefaultMetadataStreamReader() : (IMetadataStreamReader) new KoiVmAwareStreamReader(options.KoiStreamName, Logger); var peImage = PEImage.FromFile(peFile, new PEReaderParameters { MetadataStreamReader = streamReader }); var metadata = peImage.DotNetDirectory?.Metadata; if (metadata is null) { throw new BadImageFormatException("Assembly does not contain a valid .NET header."); } // If custom koi stream data was provided, inject it. KoiStream koiStream; if (!options.OverrideKoiStreamData) { koiStream = metadata.GetStream <KoiStream>() ?? throw new DevirtualisationException( "Koi stream was not found in the target PE. This could be because the input file is " + "not protected with KoiVM, or the metadata stream uses a name that is different " + "from the one specified in the input parameters."); } else { string path = Path.IsPathRooted(options.KoiStreamDataFile) ? options.KoiStreamDataFile : Path.Combine(workingDirectory, options.KoiStreamDataFile); Logger.Log(Tag, $"Opening external Koi stream data file {path}..."); var contents = File.ReadAllBytes(path); // Replace original koi stream if it existed. koiStream = new KoiStream(options.KoiStreamName, new DataSegment(contents), Logger); } // Ignore invalid / encrypted method bodies when specified. var moduleReadParameters = new ModuleReaderParameters(workingDirectory, options.IgnoreInvalidMD ? (IErrorListener)ThrowErrorListener.Instance : EmptyErrorListener.Instance); var module = ModuleDefinition.FromImage(peImage, moduleReadParameters); var runtimeModule = ResolveRuntimeModule(options, module); koiStream.ResolutionContext = module; return(new DevirtualisationContext(options, module, runtimeModule, koiStream, Logger)); }
/// <summary> /// Reads a .NET module from the provided input file. /// </summary> /// <param name="filePath">The file path to the input executable to load.</param> /// <param name="readerParameters">The parameters to use while reading the module.</param> /// <returns>The module.</returns> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception> public static ModuleDefinition FromFile(string filePath, ModuleReaderParameters readerParameters) => FromImage(PEImage.FromFile(filePath), readerParameters);
/// <summary> /// Reads a .NET module from the provided input buffer. /// </summary> /// <param name="buffer">The raw contents of the executable file to load.</param> /// <param name="readerParameters">The parameters to use while reading the module.</param> /// <returns>The module.</returns> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception> public static ModuleDefinition FromBytes(byte[] buffer, ModuleReaderParameters readerParameters) => FromImage(PEImage.FromBytes(buffer), readerParameters);
/// <summary> /// Initializes a .NET module from a PE image. /// </summary> /// <param name="peImage">The image containing the .NET metadata.</param> /// <param name="readerParameters">The parameters to use while reading the module.</param> /// <returns>The module.</returns> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET data directory.</exception> public static ModuleDefinition FromImage(IPEImage peImage, ModuleReaderParameters readerParameters) => new SerializedModuleDefinition(peImage, readerParameters);
/// <summary> /// Reads a .NET module from an input stream. /// </summary> /// <param name="reader">The input stream pointing at the beginning of the executable to load.</param> /// <param name="mode">Indicates the input PE is mapped or unmapped.</param> /// <param name="readerParameters">The parameters to use while reading the module.</param> /// <returns>The module.</returns> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception> public static ModuleDefinition FromReader(IBinaryStreamReader reader, PEMappingMode mode, ModuleReaderParameters readerParameters) => FromFile(PEFile.FromReader(reader, mode));
/// <summary> /// Reads a .NET module from the provided input file. /// </summary> /// <param name="file">The portable executable file to load.</param> /// <param name="readerParameters">The parameters to use while reading the module.</param> /// <returns>The module.</returns> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception> public static ModuleDefinition FromFile(IPEFile file, ModuleReaderParameters readerParameters) => FromImage(PEImage.FromFile(file), readerParameters);
/// <summary> /// Initializes a .NET assembly from a PE image. /// </summary> /// <param name="peImage">The image containing the .NET metadata.</param> /// <param name="readerParameters">The parameters to use while reading the assembly.</param> /// <returns>The module.</returns> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET metadata directory.</exception> public static AssemblyDefinition FromImage(IPEImage peImage, ModuleReaderParameters readerParameters) => ModuleDefinition.FromImage(peImage, readerParameters).Assembly ?? throw new BadImageFormatException("The provided PE image does not contain an assembly manifest.");