public override int Invoke(IEnumerable <string> arguments) { List <string> extra = Options.Parse(arguments); if (showHelp) { Options.WriteOptionDescriptions(CommandSet.Out); return((int)ErrorNumber.HelpRequested); } MainClass.PrintCopyright(); if (MainClass.Debug) { DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; } if (MainClass.Verbose) { DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; } Statistics.AddCommand("analyze"); if (extra.Count > 1) { DicConsole.ErrorWriteLine("Too many arguments."); return((int)ErrorNumber.UnexpectedArgumentCount); } if (extra.Count == 0) { DicConsole.ErrorWriteLine("Missing input image."); return((int)ErrorNumber.MissingArgument); } inputFile = extra[0]; DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Analyze command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Analyze command", "--filesystems={0}", searchForFilesystems); DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Analyze command", "--partitions={0}", searchForPartitions); DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } Encoding encoding = null; if (encodingName != null) { try { encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); } } catch (ArgumentException) { DicConsole.ErrorWriteLine("Specified encoding is not supported."); return((int)ErrorNumber.EncodingUnknown); } } PluginBase plugins = GetPluginBase.Instance; bool checkraw = false; try { IMediaImage imageFormat = ImageFormat.Detect(inputFilter); if (imageFormat == null) { DicConsole.WriteLine("Image format not identified, not proceeding with analysis."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); } else { DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); } DicConsole.WriteLine(); try { if (!imageFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } if (MainClass.Verbose) { ImageInfo.PrintImageInfo(imageFormat); DicConsole.WriteLine(); } Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMedia(imageFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); DicConsole.DebugWriteLine("Analyze command", "Stack trace: {0}", ex.StackTrace); return((int)ErrorNumber.CannotOpenFormat); } List <string> idPlugins; IFilesystem plugin; string information; if (searchForPartitions) { List <Partition> partitions = Core.Partitions.GetAll(imageFormat); Core.Partitions.AddSchemesToStats(partitions); if (partitions.Count == 0) { DicConsole.DebugWriteLine("Analyze command", "No partitions found"); if (!searchForFilesystems) { DicConsole.WriteLine("No partitions founds, not searching for filesystems"); return((int)ErrorNumber.NothingFound); } checkraw = true; } else { DicConsole.WriteLine("{0} partitions found.", partitions.Count); for (int i = 0; i < partitions.Count; i++) { DicConsole.WriteLine(); DicConsole.WriteLine("Partition {0}:", partitions[i].Sequence); DicConsole.WriteLine("Partition name: {0}", partitions[i].Name); DicConsole.WriteLine("Partition type: {0}", partitions[i].Type); DicConsole.WriteLine("Partition start: sector {0}, byte {1}", partitions[i].Start, partitions[i].Offset); DicConsole.WriteLine("Partition length: {0} sectors, {1} bytes", partitions[i].Length, partitions[i].Size); DicConsole.WriteLine("Partition scheme: {0}", partitions[i].Scheme); DicConsole.WriteLine("Partition description:"); DicConsole.WriteLine(partitions[i].Description); if (!searchForFilesystems) { continue; } DicConsole.WriteLine("Identifying filesystem on partition"); Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.PluginsList.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); plugin.GetInformation(imageFormat, partitions[i], out information, encoding); DicConsole.Write(information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } else { plugins.PluginsList.TryGetValue(idPlugins[0], out plugin); if (plugin == null) { continue; } DicConsole.WriteLine($"Identified by {plugin.Name}."); plugin.GetInformation(imageFormat, partitions[i], out information, encoding); DicConsole.Write("{0}", information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } } if (checkraw) { Partition wholePart = new Partition { Name = "Whole device", Length = imageFormat.Info.Sectors, Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize }; Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.PluginsList.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); plugin.GetInformation(imageFormat, wholePart, out information, encoding); DicConsole.Write(information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } else { plugins.PluginsList.TryGetValue(idPlugins[0], out plugin); if (plugin != null) { DicConsole.WriteLine($"Identified by {plugin.Name}."); plugin.GetInformation(imageFormat, wholePart, out information, encoding); DicConsole.Write(information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } } catch (Exception ex) { DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); DicConsole.DebugWriteLine("Analyze command", ex.StackTrace); return((int)ErrorNumber.UnexpectedException); } return((int)ErrorNumber.NoError); }
public override int Invoke(IEnumerable <string> arguments) { List <string> extra = Options.Parse(arguments); if (showHelp) { Options.WriteOptionDescriptions(CommandSet.Out); return((int)ErrorNumber.HelpRequested); } MainClass.PrintCopyright(); if (MainClass.Debug) { DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; } if (MainClass.Verbose) { DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; } Statistics.AddCommand("extract-files"); if (extra.Count > 1) { DicConsole.ErrorWriteLine("Too many arguments."); return((int)ErrorNumber.UnexpectedArgumentCount); } if (extra.Count == 0) { DicConsole.ErrorWriteLine("Missing input image."); return((int)ErrorNumber.MissingArgument); } inputFile = extra[0]; DicConsole.DebugWriteLine("Extract-Files command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Extract-Files command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Extract-Files command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Extract-Files command", "--options={0}", pluginOptions); DicConsole.DebugWriteLine("Extract-Files command", "--output={0}", outputDir); DicConsole.DebugWriteLine("Extract-Files command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", extractXattrs); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); Dictionary <string, string> parsedOptions = Core.Options.Parse(pluginOptions); DicConsole.DebugWriteLine("Extract-Files command", "Parsed options:"); foreach (KeyValuePair <string, string> parsedOption in parsedOptions) { DicConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value); } parsedOptions.Add("debug", MainClass.Debug.ToString()); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } Encoding encoding = null; if (encodingName != null) { try { encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); } } catch (ArgumentException) { DicConsole.ErrorWriteLine("Specified encoding is not supported."); return((int)ErrorNumber.EncodingUnknown); } } PluginBase plugins = GetPluginBase.Instance; try { IMediaImage imageFormat = ImageFormat.Detect(inputFilter); if (imageFormat == null) { DicConsole.WriteLine("Image format not identified, not proceeding with analysis."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); } else { DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); } if (outputDir == null) { DicConsole.WriteLine("Output directory missing."); return((int)ErrorNumber.MissingArgument); } if (Directory.Exists(outputDir) || File.Exists(outputDir)) { DicConsole.ErrorWriteLine("Destination exists, aborting."); return((int)ErrorNumber.DestinationExists); } Directory.CreateDirectory(outputDir); try { if (!imageFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } DicConsole.DebugWriteLine("Extract-Files command", "Correctly opened image file."); DicConsole.DebugWriteLine("Extract-Files command", "Image without headers is {0} bytes.", imageFormat.Info.ImageSize); DicConsole.DebugWriteLine("Extract-Files command", "Image has {0} sectors.", imageFormat.Info.Sectors); DicConsole.DebugWriteLine("Extract-Files command", "Image identifies disk type as {0}.", imageFormat.Info.MediaType); Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMedia(imageFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); return((int)ErrorNumber.CannotOpenFormat); } List <Partition> partitions = Core.Partitions.GetAll(imageFormat); Core.Partitions.AddSchemesToStats(partitions); List <string> idPlugins; IReadOnlyFilesystem plugin; Errno error; if (partitions.Count == 0) { DicConsole.DebugWriteLine("Extract-Files command", "No partitions found"); } else { DicConsole.WriteLine("{0} partitions found.", partitions.Count); for (int i = 0; i < partitions.Count; i++) { DicConsole.WriteLine(); DicConsole.WriteLine("Partition {0}:", partitions[i].Sequence); DicConsole.WriteLine("Identifying filesystem on partition"); Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin .GetType() .GetConstructor(Type.EmptyTypes) ?.Invoke(new object[] { }); error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } } else { plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin); DicConsole.WriteLine($"Identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin .GetType().GetConstructor(Type.EmptyTypes) ?.Invoke(new object[] { }); error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } } Partition wholePart = new Partition { Name = "Whole device", Length = imageFormat.Info.Sectors, Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize }; Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin .GetType().GetConstructor(Type.EmptyTypes) ?.Invoke(new object[] { }); error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } } else { plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin); DicConsole.WriteLine($"Identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }); error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } catch (Exception ex) { DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); DicConsole.DebugWriteLine("Extract-Files command", ex.StackTrace); return((int)ErrorNumber.UnexpectedException); } return((int)ErrorNumber.NoError); }