Пример #1
0
        static void MainExtract(string[] args)
        {
            var rom = new Z64Rom(new Rom(args[0]));

            foreach (var file in rom.Files.Select((f, i) => new { f, i }))
            {
                File.WriteAllBytes(string.Format("{0:0000} {1}", file.i, file.f.Name), file.f.Contents.ToArray());
            }
        }
Пример #2
0
        static void MainReal(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;

            var extra = _operatingModes.Parse(args);

            switch (_mode)
            {
            case Mode.ShowHelp:
                Console.Error.WriteLine(
                    typeof(Program)
                    .GetFields(BindingFlags.NonPublic | BindingFlags.Static)
                    .Where(f => f.FieldType == typeof(OptionSet))
                    .Select(f => f.GetValue(null) as OptionSet)
                    .Select(x =>
                {
                    var ms = new MemoryStream();

                    using (var sw = new StreamWriter(ms))
                        x.WriteOptionDescriptions(sw);

                    return(Encoding.UTF8.GetString(ms.ToArray()));
                })
                    .Join(Environment.NewLine.Dup(3))
                    );
                break;

            case Mode.Signatures:
            {
                var files = _signatureOptions.Parse(extra);
                var sigs  = new SignatureDatabase(SignaturesOptions.DatabasePath);

                var action =
                    SignaturesOptions.SlowMode
                            ? new Func <IEnumerable <InstructionWithPc>, IReadOnlyList <SignatureMatch> >(sigs.IdentifySlow)
                            : (x => sigs.Identify(x, SignaturesOptions.Verify));

                var results = files
                              .Select(f => action(
                                          SignaturesOptions.MemDump
                                ? File.ReadAllBytes(f).ToInstructions().WithPc(0x80000000)
                                : new Rom(f).GetExecutable()
                                          ))
                              .First();

                if (!SignaturesOptions.ShortMode)
                {
                    Console.WriteLine(JsonConvert.SerializeObject(
                                          !SignaturesOptions.UseHexAddrs
                                ? (results as object)
                                : results
                                          .Select(x => new
                        {
                            Start = string.Format("{0:X8}", x.Start),
                            x.Size,
                            Matches = x.Matches.Select(y => new
                            {
                                y.Name,
                                Symbols = y.Symbols
                                          .Select(z => new { Key = string.Format("{0:X8}", z.Key), z.Value })
                                          .ToDictionary(a => a.Key, a => a.Value)
                            })
                        }),
                                          SignaturesOptions.IndentJson ? Formatting.Indented : Formatting.None
                                          ));
                }
                else
                {
                    Console.WriteLine(
                        string.Join(
                            Environment.NewLine,
                            results
                            .ToShortForm(SignaturesOptions.ShowAll)
                            .Select(g => string.Format("0x{0:x8},{1}", g.Key, string.Join("|", g.Value)))
                            )
                        );
                }
            }
            break;

            case Mode.ImportSignatures:
                var arFiles = _importSignatureOptions.Parse(extra);
                var stats   = SignatureDatabase.ImportArchiveToDatabase(
                    SignaturesOptions.DatabasePath, SignaturesOptions.CleanDatabase, arFiles.ToArray()
                    );

                Console.Error.WriteLine("{0} imported, {1} variants already present, {2} archives already present", stats.CountImported, stats.CountExisting, stats.ArchivesExisting);

                break;

            case Mode.Zelda64:
            {
                var files = _zelda64Modes.Parse(extra);

                switch (_zeldaMode)
                {
                case ZeldaMode.Extract:
                    MainExtract(files.ToArray());
                    break;

                case ZeldaMode.DisassembleOverlay:
                    MainDis(files.ToArray());
                    break;

                case ZeldaMode.DisassembleAllOverlays:
                    var rom  = new Rom(files[0]);
                    var zrom = new Z64Rom(rom);

                    foreach (var o in zrom.Overlays)
                    {
                        var p   = o.File.Name;
                        var ovl = new Overlay(o.VmaStart, o.File.Contents, _overlayOptions);

                        Directory.CreateDirectory(p);

                        File.WriteAllLines(
                            Path.Combine(p, $"{o.File.Name}.S"),
                            ovl.Disassemble(DisassemblyOptions.DebugPc)
                            );

                        File.WriteAllText(
                            Path.Combine(p, "conf.ld"),
                            ovl.LinkerScript
                            );

                        File.WriteAllText(
                            Path.Combine(p, "Makefile"),
                            OverlayCreator.GenerateMakefileForOvl(AppContext.BaseDirectory, o.File.Name, o.VmaStart)
                            );

                        File.WriteAllBytes(
                            Path.Combine(p, $"{o.File.Name}.ovl.orig"),
                            o.File.Contents.ToArray()
                            );
                    }
                    break;

                case ZeldaMode.GenerateOverlayRelocs:
                    Console.WriteLine(
                        OverlayCreator.CreateCSourceFromOverlayRelocations(
                            "__relocations",
                            OverlayCreator.GetOverlayRelocationsFromElf(File.ReadAllBytes(files[0]))
                            )
                        );
                    break;

                case ZeldaMode.DumpRelocations:
                    Console.WriteLine(
                        string.Join(
                            Environment.NewLine,
                            new[]
                        {
                            "ID      Sec. loc   Abs. addr    Sym value   Type        Section       Disassembly",
                            //"    0  [0x0000001C/0x808FDEAC] (0x8090EE50) R_MIPS_HI16 .text         lui         $at,0x8091"
                        }.Concat(
                                LoadOverlay(files)
                                .Relocations
                                .Select((x, i) => string.Format("{0,5}  {1}", i, x))
                                )
                            )
                        );
                    break;
                }
            }
            break;

            case Mode.EucJpStrings:
            {
                var files = _eucJpOptions.Parse(extra);

                var data = files
                           .Select(x => new { x, data = File.ReadAllBytes(x) })
                           .Select(x => new
                    {
                        x.x,
                        strings = EucJp.ExtractEucJpStrings(x.data, EucJp.AsciiColorCode, EucJp.UnknownExtraChars)
                                  .Where(y => !EucJpOptions.MinStringLength.HasValue || y.String.Length >= EucJpOptions.MinStringLength.Value)
                                  .Where(y => !EucJpOptions.OnlyForeign || y.ContainsEucJpCharacters)
                                  .Select(y => y.String)
                    });

                if (!EucJpOptions.Json)
                {
                    foreach (var x in data.Select(y => y.strings))
                    {
                        Console.WriteLine(x);
                    }
                }
                else
                {
                    Console.WriteLine(
                        JsonConvert.SerializeObject(
                            data.Select(x => new { Filename = x.x, Strings = x.strings }),
                            Formatting.Indented
                            )
                        );
                }
            }
            break;

            case Mode.AsmPatch:
            {
                _asmPatchOptions.Parse(extra);

                var assembled = BuildAsmPatch();

                if (!AsmPatchOptions.Gameshark)
                {
                    byte[] input = ApplyAssembledInstructionsToRom(
                        assembled,
                        AsmPatchOptions.InputRom,
                        AsmPatchOptions.OutputRom
                        );

                    DumpAssembledValues(assembled);

                    Console.Error.WriteLine("Patched {0} bytes.", assembled.Length * 4);

                    if (string.IsNullOrWhiteSpace(AsmPatchOptions.BsdiffPath))
                    {
                        break;
                    }

                    using (var patchOutput = File.OpenWrite(AsmPatchOptions.BsdiffPath))
                        deltaq.BsDiff.BsDiff.Create(File.ReadAllBytes(AsmPatchOptions.InputRom), input, patchOutput);

                    Console.Error.WriteLine("`{0}` of size {1} bytes created.", AsmPatchOptions.BsdiffPath, new FileInfo(AsmPatchOptions.BsdiffPath).Length);
                }
                else
                {
                    var codes = assembled
                                .SelectMany(x => new[]