/// <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="readParameters">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, ModuleReadParameters readParameters) { var module = FromImage(PEImage.FromFile(filePath), readParameters); module.FilePath = filePath; return(module); }
/// <summary> /// Initializes a .NET assembly from a PE image. /// </summary> /// <param name="peImage">The image containing the .NET metadata.</param> /// <param name="readParameters">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, ModuleReadParameters readParameters) => ModuleDefinition.FromImage(peImage, readParameters).Assembly ?? throw new BadImageFormatException("The provided PE image does not contain an assembly manifest.");
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(peFile) : (IMetadataStreamReader) new KoiVmAwareStreamReader(peFile, options.KoiStreamName, Logger); var peImage = PEImage.FromFile(peFile, new PEReadParameters(peFile) { 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 ModuleReadParameters(workingDirectory) { MethodBodyReader = new DefaultMethodBodyReader { ThrowOnInvalidMethodBody = !options.IgnoreInvalidMethodBodies } }; var module = ModuleDefinition.FromImage(peImage, moduleReadParameters); var runtimeModule = ResolveRuntimeModule(options, module); koiStream.ResolutionContext = module; return(new DevirtualisationContext(options, module, runtimeModule, koiStream, Logger)); }
/// <summary> /// Initializes a .NET module from a PE image. /// </summary> /// <param name="peImage">The image containing the .NET metadata.</param> /// <param name="readParameters">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, ModuleReadParameters readParameters) => new SerializedModuleDefinition(peImage, readParameters);