예제 #1
0
        public void TestDetection()
        {
            return;

// Unreachable code detected
#pragma warning disable CS0162
            var signatures = new SignatureDatabase(@"..\..\..\signatures.db");
#pragma warning restore CS0162

            var toCompare = signatures.Imports
                            .SelectMany(i => i.Variants)
                            .Select(v => new {
                Variant     = v,
                ZeroedInsns = v.Instructions
                              .WithPc(0)
                              .ZeroRelocatedValues()
                              .ToList(),
                RegularInsns = v.Instructions
                               .WithPc(0)
                               .ToList()
            });

            var faults = new List <Tuple <Variant, List <InstructionWithPc> > >();

            foreach (var c in toCompare)
            {
                var result = c.ZeroedInsns.SequenceEqual(c.RegularInsns);

                if (!result)
                {
                    faults.Add(Tuple.Create(c.Variant, c.ZeroedInsns));
                }
                //$"{c.Variant} didn't work well with our PIC zeroing!";
            }

            if (faults.Count > 0)
            {
                throw new Exception(string.Join(Environment.NewLine, new[] {
                    $"The following {faults.Count} variants were mangled by our algorithm:"
                }
                                                .Concat(faults.Select(f => $" - {f.Item1}")))
                                    );
            }
        }
예제 #2
0
파일: Program.cs 프로젝트: kskjer/MipsSharp
        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[]