예제 #1
0
        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);
        }
예제 #2
0
        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);
        }