Ejemplo n.º 1
0
        public void LoadFromLinker(Linker linker)
        {
            if (_codeBlob != null)
                throw new InvalidOperationException("this KamekFile already has stuff in it");

            // Extract _just_ the code/data sections
            _codeBlob = new byte[linker.OutputEnd - linker.OutputStart];
            Array.Copy(linker.Memory, linker.OutputStart - linker.BaseAddress, _codeBlob, 0, _codeBlob.Length);

            _baseAddress = linker.BaseAddress;
            _bssSize = linker.BssSize;

            _hooks = new List<Hooks.Hook>();
            _commands = new Dictionary<Word, Commands.Command>();

            AddRelocsAsCommands(linker.Fixups);
            foreach (var cmd in linker.Hooks)
                ApplyHook(cmd);
            ApplyStaticCommands();
        }
Ejemplo n.º 2
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 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);
                    }
                }
            }
        }
Ejemplo n.º 4
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;
            var externals = new Dictionary<string, uint>();

            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("-externals="))
                        ReadExternals(externals, arg.Substring(11));
                    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));
                    }
                }
            }

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

            var linker = new Linker();
            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, kf.Pack());
            if (outputRiivPath != null)
                File.WriteAllText(outputRiivPath, kf.PackRiivolution());
            if (outputGeckoPath != null)
                File.WriteAllText(outputGeckoPath, kf.PackGeckoCodes());
        }
Ejemplo n.º 5
0
 public static byte[] PackFrom(Linker linker)
 {
     var kf = new KamekFile();
     kf.LoadFromLinker(linker);
     return kf.Pack();
 }
Ejemplo n.º 6
0
 private void ApplyHook(Linker.HookData hookData)
 {
     var hook = Hooks.Hook.Create(hookData);
     foreach (var cmd in hook.Commands)
     {
         if (_commands.ContainsKey(cmd.Address))
             throw new InvalidOperationException(string.Format("duplicate commands for address {0}", cmd.Address));
         _commands[cmd.Address] = cmd;
     }
     _hooks.Add(hook);
 }