Esempio n. 1
0
        public void TestCharacterDetection()
        {
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x09 }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x0A }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x0D }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x20 }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0x20 }, 0).IsEucJp);

            for (byte i = 0x0E; i < 0x20; i++)
            {
                Assert.IsFalse(EucJp.IsValidChar(new byte[] { i }, 0).IsValid);
            }

            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x21 }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x7E }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0x7F }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0x7e }, 0).IsEucJp);

            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x8E, 0xA1 }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x8E, 0xDF }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0x8E, 0xE0 }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x8E, 0xDF }, 0).IsEucJp);

            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0xA1, 0xA1 }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0xFE, 0xFE }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0xFF, 0xFE }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0xFE, 0xFF }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0xFE, 0xFE }, 0).IsEucJp);

            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x8F, 0xA1, 0xA1 }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x8F, 0xFE, 0xFE }, 0).IsValid);
            Assert.IsFalse(EucJp.IsValidChar(new byte[] { 0x8F, 0xFF, 0xFF }, 0).IsValid);
            Assert.IsTrue(EucJp.IsValidChar(new byte[] { 0x8F, 0xFE, 0xFE }, 0).IsEucJp);
        }
Esempio n. 2
0
        public void TestStringExtraction()
        {
            var source = new byte[]
            {
                // from map select
                0x36, 0x37, 0x3A, 0x8D, 0x8E, 0xD6, 0x8E, 0xB3, 0x8E, 0xBE, 0x8E, 0xB2, 0x8E, 0xC9, 0x8E, 0xB7,
                0x8E, 0xC9, 0x20, 0x8C, 0x8E, 0xC0, 0x8E, 0xDE, 0x8E, 0xDD, 0x8E, 0xBC, 0x8E, 0xDE, 0x8E, 0xAE,
                0x8E, 0xDD, 0x20, 0x8E, 0xCE, 0x8E, 0xDE, 0x8E, 0xBD, 0x00, 0x00, 0x00, 0x36, 0x38, 0x3A, 0x8C,
                0x8E, 0xC4, 0x8E, 0xDE, 0x8E, 0xC4, 0x8E, 0xDE, 0x8E, 0xDD, 0x8E, 0xBA, 0x8E, 0xDE, 0x20, 0x8E,
                0xC0, 0x8E, 0xDE, 0x8E, 0xDD, 0x8E, 0xBC, 0x8E, 0xDE, 0x8E, 0xAE, 0x8E, 0xDD, 0x00, 0x00, 0x00,
                0x36, 0x39, 0x3A, 0x8C, 0x8E, 0xC4, 0x8E, 0xDE, 0x8E, 0xC4, 0x8E, 0xDE, 0x8E, 0xDD, 0x8E, 0xBA,
                0x8E, 0xDE, 0x20, 0x8E, 0xC0, 0x8E, 0xDE, 0x8E, 0xDD, 0x8E, 0xBC, 0x8E, 0xDE, 0x8E, 0xAE, 0x8E,
                0xDD, 0x20, 0x8E, 0xCE, 0x8E, 0xDE, 0x8E, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x3A, 0x8D,
                0x8E, 0xB7, 0x8E, 0xAE, 0x8E, 0xC0, 0x8E, 0xDE, 0x8E, 0xB2, 0x8E, 0xB7, 0x8E, 0xDE, 0x8E, 0xAE,
                0x20, 0x8C, 0x8E, 0xC0, 0x8E, 0xDE, 0x8E, 0xDD, 0x8E, 0xBC, 0x8E, 0xDE, 0x8E, 0xAE, 0x8E, 0xDD,
                0x00, 0x00, 0x00, 0x00, 0x37, 0x31, 0x3A, 0x8D, 0x8E, 0xB7, 0x8E, 0xAE, 0x8E, 0xC0, 0x8E, 0xDE,
                0x8E, 0xB2, 0x8E, 0xB7, 0x8E, 0xDE, 0x8E, 0xAE, 0x20, 0x8C, 0x8E, 0xC0, 0x8E, 0xDE, 0x8E, 0xDD,
                0x8E, 0xBC, 0x8E, 0xDE, 0x8E, 0xAE, 0x8E, 0xDD, 0x20, 0x8E, 0xCE, 0x8E, 0xDE, 0x8E, 0xBD, 0x00,

                // from code
                0xA5, 0xD5, 0xA5, 0xA9, 0xA5, 0xEB, 0xA5, 0xC8, 0xA5, 0xDE, 0xA5, 0xCD, 0xA1, 0xBC, 0xA5, 0xB8,
                0xA5, 0xE3, 0x3A, 0xC9, 0xD4, 0xCC, 0xC0, 0xA4, 0xCA, 0xA5, 0xE1, 0xA5, 0xC3, 0xA5, 0xBB, 0xA1,
                0xBC, 0xA5, 0xB8, 0xA4, 0xF2, 0xBC, 0xF5, 0xBF, 0xAE, 0xA4, 0xB7, 0xA4, 0xDE, 0xA4, 0xB7, 0xA4,
                0xBF, 0x0A, 0x00,
            };

            var results = EucJp.ExtractEucJpStrings(source, EucJp.AsciiColorCode, EucJp.UnknownExtraChars)
                          .ToArray();

            Assert.AreEqual("67:ヨウセイノキノ ダンジョン ボス", results[0].String);
            Assert.AreEqual("68:ドドンゴ ダンジョン", results[1].String);
            Assert.AreEqual("69:ドドンゴ ダンジョン ボス", results[2].String);
            Assert.AreEqual("70:キョダイギョ ダンジョン", results[3].String);
            Assert.AreEqual("71:キョダイギョ ダンジョン ボス", results[4].String);
            Assert.AreEqual("フォルトマネージャ:不明なメッセージを受信しました\n", results[5].String);

            Assert.IsTrue(results.All(x => x.ContainsEucJpCharacters));
        }
Esempio n. 3
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[]