コード例 #1
0
        public void InjectIntoDol(Dol dol)
        {
            if (_baseAddress.Type == WordType.RelativeAddr)
            {
                throw new InvalidOperationException("cannot pack a dynamically linked binary into a DOL");
            }

            // find an empty text section
            int victimSection = -1;

            for (int i = dol.Sections.Length - 1; i >= 0; i--)
            {
                if (dol.Sections[i].Data.Length == 0)
                {
                    victimSection = i;
                    break;
                }
            }

            if (victimSection == -1)
            {
                throw new InvalidOperationException("cannot find an empty text section in the DOL");
            }

            // throw the code blob into it
            dol.Sections[victimSection].LoadAddress = _baseAddress.Value;
            dol.Sections[victimSection].Data        = _codeBlob;

            // apply all patches
            foreach (var pair in _commands)
            {
                pair.Value.ApplyToDol(dol);
            }
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: Treeki/Kamek
        static void Main(string[] args)
        {
            Console.WriteLine("Kamek 2.0 by Ninji/Ash Wolf - https://github.com/Treeki/Kamek");
            Console.WriteLine();

            // Parse the command line arguments and do cool things!
            var         modules = new List <Elf>();
            uint?       baseAddress = null;
            string      outputKamekPath = null, outputRiivPath = null, outputGeckoPath = null, outputCodePath = null;
            string      inputDolPath = null, outputDolPath = null;
            var         externals        = new Dictionary <string, uint>();
            VersionInfo versions         = null;
            var         selectedVersions = new List <String>();

            foreach (var arg in args)
            {
                if (arg.StartsWith("-"))
                {
                    if (arg == "-h" || arg == "-help" || arg == "--help")
                    {
                        ShowHelp();
                        return;
                    }
                    if (arg == "-dynamic")
                    {
                        baseAddress = null;
                    }
                    else if (arg.StartsWith("-static=0x"))
                    {
                        baseAddress = uint.Parse(arg.Substring(10), System.Globalization.NumberStyles.HexNumber);
                    }
                    else if (arg.StartsWith("-output-kamek="))
                    {
                        outputKamekPath = arg.Substring(14);
                    }
                    else if (arg.StartsWith("-output-riiv="))
                    {
                        outputRiivPath = arg.Substring(13);
                    }
                    else if (arg.StartsWith("-output-gecko="))
                    {
                        outputGeckoPath = arg.Substring(14);
                    }
                    else if (arg.StartsWith("-output-code="))
                    {
                        outputCodePath = arg.Substring(13);
                    }
                    else if (arg.StartsWith("-input-dol="))
                    {
                        inputDolPath = arg.Substring(11);
                    }
                    else if (arg.StartsWith("-output-dol="))
                    {
                        outputDolPath = arg.Substring(12);
                    }
                    else if (arg.StartsWith("-externals="))
                    {
                        ReadExternals(externals, arg.Substring(11));
                    }
                    else if (arg.StartsWith("-versions="))
                    {
                        versions = new VersionInfo(arg.Substring(10));
                    }
                    else if (arg.StartsWith("-select-version="))
                    {
                        selectedVersions.Add(arg.Substring(16));
                    }
                    else
                    {
                        Console.WriteLine("warning: unrecognised argument: {0}", arg);
                    }
                }
                else
                {
                    Console.WriteLine("adding {0} as object..", arg);
                    using (var stream = new FileStream(arg, FileMode.Open))
                    {
                        modules.Add(new Elf(stream));
                    }
                }
            }


            // We need a default VersionList for the loop later
            if (versions == null)
            {
                versions = new VersionInfo();
            }


            // Can we build a thing?
            if (modules.Count == 0)
            {
                Console.WriteLine("no input files specified");
                return;
            }
            if (outputKamekPath == null && outputRiivPath == null && outputGeckoPath == null && outputCodePath == null && outputDolPath == null)
            {
                Console.WriteLine("no output path(s) specified");
                return;
            }
            if (outputDolPath != null && inputDolPath == null)
            {
                Console.WriteLine("input dol path not specified");
                return;
            }


            // Do safety checks
            if (versions.Mappers.Count > 1 && selectedVersions.Count != 1)
            {
                bool ambiguousOutputPath = false;
                ambiguousOutputPath |= (outputKamekPath != null && !outputKamekPath.Contains("$KV$"));
                ambiguousOutputPath |= (outputRiivPath != null && !outputRiivPath.Contains("$KV$"));
                ambiguousOutputPath |= (outputGeckoPath != null && !outputGeckoPath.Contains("$KV$"));
                ambiguousOutputPath |= (outputCodePath != null && !outputCodePath.Contains("$KV$"));
                ambiguousOutputPath |= (outputDolPath != null && !outputDolPath.Contains("$KV$"));
                if (ambiguousOutputPath)
                {
                    Console.WriteLine("ERROR: this configuration builds for multiple game versions, and some of the outputs will be overwritten");
                    Console.WriteLine("add the $KV$ placeholder to your output paths, or use -select-version=.. to only build one version");
                    return;
                }
            }


            foreach (var version in versions.Mappers)
            {
                if (selectedVersions.Count > 0 && !selectedVersions.Contains(version.Key))
                {
                    Console.WriteLine("(skipping version {0} as it's not selected)", version.Key);
                    continue;
                }
                Console.WriteLine("linking version {0}...", version.Key);

                var linker = new Linker(version.Value);
                foreach (var module in modules)
                {
                    linker.AddModule(module);
                }

                if (baseAddress.HasValue)
                {
                    linker.LinkStatic(baseAddress.Value, externals);
                }
                else
                {
                    linker.LinkDynamic(externals);
                }

                var kf = new KamekFile();
                kf.LoadFromLinker(linker);
                if (outputKamekPath != null)
                {
                    File.WriteAllBytes(outputKamekPath.Replace("$KV$", version.Key), kf.Pack());
                }
                if (outputRiivPath != null)
                {
                    File.WriteAllText(outputRiivPath.Replace("$KV$", version.Key), kf.PackRiivolution());
                }
                if (outputGeckoPath != null)
                {
                    File.WriteAllText(outputGeckoPath.Replace("$KV$", version.Key), kf.PackGeckoCodes());
                }
                if (outputCodePath != null)
                {
                    File.WriteAllBytes(outputCodePath.Replace("$KV$", version.Key), kf.CodeBlob);
                }

                if (outputDolPath != null)
                {
                    var dol = new Dol(new FileStream(inputDolPath.Replace("$KV$", version.Key), FileMode.Open));
                    kf.InjectIntoDol(dol);

                    var outpath = outputDolPath.Replace("$KV$", version.Key);
                    using (var outStream = new FileStream(outpath, FileMode.Create))
                    {
                        dol.Write(outStream);
                    }
                }
            }
        }
コード例 #3
0
        static void Main(string[] args)
        {
            Console.WriteLine("Kamek 2.0 by Treeki");
            Console.WriteLine();

            // Parse the command line arguments and do cool things!
            var         modules = new List <Elf>();
            uint?       baseAddress = null;
            string      outputKamekPath = null, outputRiivPath = null, outputGeckoPath = null, outputCodePath = null;
            string      inputDolPath = null, outputDolPath = null;
            var         externals = new Dictionary <string, uint>();
            VersionInfo versions  = null;

            foreach (var arg in args)
            {
                if (arg.StartsWith("-"))
                {
                    if (arg == "-dynamic")
                    {
                        baseAddress = null;
                    }
                    else if (arg.StartsWith("-static=0x"))
                    {
                        baseAddress = uint.Parse(arg.Substring(10), System.Globalization.NumberStyles.HexNumber);
                    }
                    else if (arg.StartsWith("-output-kamek="))
                    {
                        outputKamekPath = arg.Substring(14);
                    }
                    else if (arg.StartsWith("-output-riiv="))
                    {
                        outputRiivPath = arg.Substring(13);
                    }
                    else if (arg.StartsWith("-output-gecko="))
                    {
                        outputGeckoPath = arg.Substring(14);
                    }
                    else if (arg.StartsWith("-output-code="))
                    {
                        outputCodePath = arg.Substring(13);
                    }
                    else if (arg.StartsWith("-input-dol="))
                    {
                        inputDolPath = arg.Substring(11);
                    }
                    else if (arg.StartsWith("-output-dol="))
                    {
                        outputDolPath = arg.Substring(12);
                    }
                    else if (arg.StartsWith("-externals="))
                    {
                        ReadExternals(externals, arg.Substring(11));
                    }
                    else if (arg.StartsWith("-versions="))
                    {
                        versions = new VersionInfo(arg.Substring(10));
                    }
                    else
                    {
                        Console.WriteLine("warning: unrecognised argument: {0}", arg);
                    }
                }
                else
                {
                    Console.WriteLine("adding {0} as object..", arg);
                    using (var stream = new FileStream(arg, FileMode.Open))
                    {
                        modules.Add(new Elf(stream));
                    }
                }
            }


            // We need a default VersionList for the loop later
            if (versions == null)
            {
                versions = new VersionInfo();
            }


            // Can we build a thing?
            if (modules.Count == 0)
            {
                Console.WriteLine("no input files specified");
                return;
            }
            if (outputKamekPath == null && outputRiivPath == null && outputGeckoPath == null && outputCodePath == null && outputDolPath == null)
            {
                Console.WriteLine("no output path(s) specified");
                return;
            }
            if (outputDolPath != null && inputDolPath == null)
            {
                Console.WriteLine("input dol path not specified");
                return;
            }


            foreach (var version in versions.Mappers)
            {
                Console.WriteLine("linking version {0}...", version.Key);

                var linker = new Linker(version.Value);
                foreach (var module in modules)
                {
                    linker.AddModule(module);
                }

                if (baseAddress.HasValue)
                {
                    linker.LinkStatic(baseAddress.Value, externals);
                }
                else
                {
                    linker.LinkDynamic(externals);
                }

                var kf = new KamekFile();
                kf.LoadFromLinker(linker);
                if (outputKamekPath != null)
                {
                    File.WriteAllBytes(outputKamekPath.Replace("$KV$", version.Key), kf.Pack());
                }
                if (outputRiivPath != null)
                {
                    File.WriteAllText(outputRiivPath.Replace("$KV$", version.Key), kf.PackRiivolution());
                }
                if (outputGeckoPath != null)
                {
                    File.WriteAllText(outputGeckoPath.Replace("$KV$", version.Key), kf.PackGeckoCodes());
                }
                if (outputCodePath != null)
                {
                    File.WriteAllBytes(outputCodePath.Replace("$KV$", version.Key), kf.CodeBlob);
                }

                if (outputDolPath != null)
                {
                    var dol = new Dol(new FileStream(inputDolPath, FileMode.Open));
                    kf.InjectIntoDol(dol);

                    var outpath = outputDolPath.Replace("$KV$", version.Key);
                    using (var outStream = new FileStream(outpath, FileMode.Create))
                    {
                        dol.Write(outStream);
                    }
                }
            }
        }