public void ReplaceByNopAt(string typeName, string methodName, int instructionIndex)
        {
            var method     = CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName);
            var methodBody = method.Body;

            ReplaceByNop(methodBody, methodBody.Instructions[instructionIndex]);
        }
        public void ClearAllButLast(string typeName, string methodName)
        {
            var method     = CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName);
            var methodBody = method.Body;

            ClearAllButLast(methodBody);
        }
Example #3
0
        private void InjectOnionDoWorldGen()
        {
            try
            {
                var doWorldGenInitialiseBody = CecilHelper.GetMethodDefinition(_csharpModule, "OfflineWorldGen", "DoWordGenInitialise").Body;

                var callResetInstruction = doWorldGenInitialiseBody
                                           .Instructions
                                           .Where(instruction => instruction.OpCode == OpCodes.Call)
                                           .Reverse()
                                           .Skip(3)
                                           .First();

                var instructionInserter = new InstructionInserter(doWorldGenInitialiseBody);

                instructionInserter.InsertBefore(callResetInstruction, Instruction.Create(OpCodes.Pop));
                instructionInserter.InsertBefore(callResetInstruction, Instruction.Create(OpCodes.Pop));

                _onionToCSharpInjector.InjectBefore(
                    "Hooks", "OnDoOfflineWorldGen",
                    doWorldGenInitialiseBody,
                    callResetInstruction);

                _csharpInstructionRemover.ReplaceByNop(doWorldGenInitialiseBody, callResetInstruction);
            }
            catch (Exception e)
            {
                Logger.Log("World generation injection failed");
                Logger.Log(e);

                Failed = true;
            }
        }
Example #4
0
        public void InjectBefore(
            string sourceTypeName,
            string sourceMethodName,
            string targetTypeName,
            string targetMethodName,
            int instructionIndex,
            bool includeCallingObject = false,
            int includeArgumentCount  = 0,
            bool passArgumentsByRef   = false,
            bool useFullName          = false)
        {
            MethodBody targetMethodBody = CecilHelper
                                          .GetMethodDefinition(
                this._targetModule,
                targetTypeName,
                targetMethodName,
                useFullName).Body;
            Instruction instruction = targetMethodBody.Instructions[instructionIndex];

            this.InjectBefore(
                sourceTypeName,
                sourceMethodName,
                targetMethodBody,
                instruction,
                includeCallingObject,
                includeArgumentCount,
                passArgumentsByRef,
                useFullName);
        }
Example #5
0
        private void InjectOnionDebugHandler()
        {
            var debugHandler = _csharpModule
                               .Types
                               .FirstOrDefault(type => type.Name == "DebugHandler");

            if (debugHandler != null)
            {
                var debugHandlerEnabledProperty = debugHandler
                                                  .Properties
                                                  .FirstOrDefault(property => property.Name == "enabled");

                if (debugHandlerEnabledProperty != null)
                {
                    debugHandlerEnabledProperty
                    .SetMethod
                    .IsPublic = true;
                }
            }
            else
            {
                Logger.Log("Can't find type DebugHandler");

                Failed = true;
            }

            var debugHandlerConstructorBody = CecilHelper.GetMethodDefinition(_csharpModule, debugHandler, ".ctor").Body;

            var lastInstruction = debugHandlerConstructorBody.Instructions.Last();

            _onionToCSharpInjector.InjectBefore("Hooks", "OnDebugHandlerCtor", debugHandlerConstructorBody, lastInstruction);
        }
        public void ClearAllButLast(string typeName, string methodName)
        {
            MethodDefinition method     = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName);
            MethodBody       methodBody = method.Body;

            this.ClearAllButLast(methodBody);
        }
Example #7
0
        public void PatchMod(ModuleDefinition module, string filePath, string className, string methodName)
        {
            AssemblyDefinition originalDll = CecilHelper.GetAssembly(filePath);

            if (Injector.IsPatched(originalDll))
            {
                ModLogger.WriteLine(ConsoleColor.Red, module.Name + " already patched.");
                return;
            }

            this.MakeBackup(filePath);
            this.SaveModule(module, filePath);

            string tempDllPath = GetTempPathForFile(filePath);

            if (this.TempForFileExists(filePath))
            {
                File.Delete(tempDllPath);
            }
            File.Move(filePath, tempDllPath);

            AssemblyDefinition unityGameDll = CecilHelper.GetAssembly(tempDllPath);

            Injector.Inject(ref unityGameDll, className, methodName);
            Injector.InjectPatchedSign(ref unityGameDll);
            unityGameDll.Write(filePath);

            File.Delete(tempDllPath);
        }
        public void InjectBefore(string sourceTypeName, string sourceMethodName, MethodBody targetMethodBody,
                                 Instruction targetInstruction, bool includeCallingObject = false, int includeArgumentCount = 0, bool passArgumentsByRef = false, bool useFullName = false)
        {
            var sourceMethod          = CecilHelper.GetMethodDefinition(_sourceModule, sourceTypeName, sourceMethodName, useFullName: useFullName);
            var sourceMethodReference = CecilHelper.GetMethodReference(_targetModule, sourceMethod);

            InjectBefore(sourceMethodReference, targetMethodBody, targetInstruction, includeCallingObject, includeArgumentCount, passArgumentsByRef);
        }
Example #9
0
        public void InjectDefaultAndBackup()
        {
            string           path            = Directory.GetCurrentDirectory();
            ModuleDefinition onionModule     = CecilHelper.GetModule("ONI-Common.dll", path);
            ModuleDefinition csharpModule    = CecilHelper.GetModule("Assembly-CSharp.dll", path);
            ModuleDefinition firstPassModule = CecilHelper.GetModule("Assembly-CSharp-firstpass.dll", path);

            InjectorOnion injection = new InjectorOnion(onionModule, csharpModule, firstPassModule);

            injection.Inject();

            this.BackupAndSaveCSharpModule(csharpModule);
            this.BackupAndSaveFirstPassModule(firstPassModule);
        }
Example #10
0
        // TODO: use other sprite, refactor
        private void AddOverlayButton()
        {
            _csharpPublisher.MakeFieldPublic("OverlayMenu", "overlay_toggle_infos");

            var overlayMenu = _csharpModule.Types.First(type => type.Name == "OverlayMenu");

            overlayMenu.NestedTypes.First(nestedType => nestedType.Name == "OverlayToggleInfo").IsPublic = true;

            var onPrefabInitBody = CecilHelper.GetMethodDefinition(_csharpModule, overlayMenu, "OnPrefabInit").Body;

            var loadOverlayToggleInfosInstuction = onPrefabInitBody.Instructions.First(instruction => instruction.OpCode == OpCodes.Ldfld);

            _coreToCSharpInjector.InjectBefore(
                "OverlayMenuManager", "OnOverlayMenuPrefabInit",
                onPrefabInitBody, loadOverlayToggleInfosInstuction.Next, true);
        }
Example #11
0
        public void PatchMod(string filePath)
        {
            string tempDllPath = GetTempPathForFile(filePath);

            if (this.TempForFileExists(filePath))
            {
                File.Delete(tempDllPath);
            }
            File.Move(filePath, tempDllPath);

            AssemblyDefinition unityGameDll = CecilHelper.GetAssembly(tempDllPath);

            Injector.Inject(unityGameDll, filePath);

            File.Delete(tempDllPath);
        }
Example #12
0
        private void InjectOnionCameraController()
        {
            const string TypeName = "CameraController";

            _csharpPublisher.MakeFieldPublic(TypeName, "maxOrthographicSize");
            _csharpPublisher.MakeFieldPublic(TypeName, "maxOrthographicSizeDebug");

            var cameraControllerOnSpawnBody = CecilHelper.GetMethodDefinition(_csharpModule, TypeName, "OnSpawn").Body;
            var restoreCall = cameraControllerOnSpawnBody.Instructions.Last(instruction => instruction.OpCode == OpCodes.Call);

            _onionToCSharpInjector.InjectBefore(
                "Hooks",
                "OnCameraControllerCtor",
                cameraControllerOnSpawnBody,
                restoreCall,
                true);
        }
Example #13
0
        private void AddDefaultKeybinding(ModuleDefinition CSharpModule, ModuleDefinition firstPassModule, KKeyCode keyCode, Modifier keyModifier, Action action, string screen = "Root")
        {
            var beforeFieldInit = CecilHelper.GetMethodDefinition(firstPassModule, CecilHelper.GetTypeDefinition(firstPassModule, "GameInputMapping"), ".cctor");

            var lastKeybindingDeclarationEnd = beforeFieldInit.Body.Instructions.Last(instruction => instruction.OpCode == OpCodes.Stobj);
            var stoBindingEntryInstruction   = beforeFieldInit.Body.Instructions.First(instruction => instruction.OpCode == OpCodes.Stobj);
            var newBindingEntryInstruction   = beforeFieldInit.Body.Instructions.First(instruction => instruction.OpCode == OpCodes.Newobj);

            var lastDupInstruction = beforeFieldInit.Body.Instructions.LastOrDefault(instr => instr.OpCode == OpCodes.Dup);

            if (lastDupInstruction != null)
            {
                var lastEntryIndex = Convert.ToInt32(lastDupInstruction.Next.Operand);

                var instructionsToAdd = new List <Instruction>
                {
                    Instruction.Create(OpCodes.Dup),
                    Instruction.Create(OpCodes.Ldc_I4, lastEntryIndex + 1), // index
                    Instruction.Create(OpCodes.Ldelema, (TypeReference)stoBindingEntryInstruction.Operand),
                    Instruction.Create(OpCodes.Ldstr, screen),
                    Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)16), // gamepad button
                    Instruction.Create(OpCodes.Ldc_I4, (int)keyCode),
                    Instruction.Create(OpCodes.Ldc_I4, (int)keyModifier),
                    Instruction.Create(OpCodes.Ldc_I4, (int)action),
                    Instruction.Create(OpCodes.Ldc_I4_1), // rebindable = true
                    Instruction.Create(OpCodes.Ldc_I4_1), // ignore root conflicts = true
                    newBindingEntryInstruction,           // create new object
                    stoBindingEntryInstruction            // store in array
                };

                var ILProcessor = beforeFieldInit.Body.GetILProcessor();

                // increase array size by one
                var arraySizeSetInstruction = beforeFieldInit.Body.Instructions.First();
                ILProcessor.Replace(arraySizeSetInstruction, Instruction.Create(OpCodes.Ldc_I4, (int)arraySizeSetInstruction.Operand + 1));
                //

                new InstructionInserter(ILProcessor).InsertAfter(lastKeybindingDeclarationEnd, instructionsToAdd);
            }
            else
            {
                Logger.Log("Can't find last duplication instruction at GameInputMapping.cctor");

                Failed = true;
            }
        }
Example #14
0
        private void FixGameUpdateExceptionHandling()
        {
            var handler            = new ExceptionHandler(ExceptionHandlerType.Finally);
            var methodBody         = CecilHelper.GetMethodDefinition(_csharpModule, "Game", "Update").Body;
            var methodInstructions = methodBody.Instructions;

            handler.TryStart = methodInstructions.First(instruction => instruction.OpCode == OpCodes.Ldsfld);

            var tryEndInstruction = methodInstructions.Last(instruction => instruction.OpCode == OpCodes.Ldloca_S);

            handler.TryEnd       = tryEndInstruction;
            handler.HandlerStart = tryEndInstruction;
            handler.HandlerEnd   = methodInstructions.Last();
            handler.CatchType    = _csharpModule.Import(typeof(Exception));

            methodBody.ExceptionHandlers.Clear();
            methodBody.ExceptionHandlers.Add(handler);
        }
Example #15
0
        // TODO: notify user when injection fails
        private void ExtendMaxActionCount()
        {
            const int MaxActionCount = 1000;

            TypeDefinition kInputController =
                this._firstPassModule.Types.FirstOrDefault(type => type.Name == "KInputController");

            if (kInputController != null)
            {
                TypeDefinition keyDef =
                    kInputController.NestedTypes.FirstOrDefault(nestedType => nestedType.Name == "KeyDef");

                if (keyDef != null)
                {
                    MethodBody keyDefConstructorBody = keyDef.Methods.First(method => method.Name == ".ctor").Body;

                    keyDefConstructorBody.Instructions.Last(instruction => instruction.OpCode == OpCodes.Ldc_I4)
                    .Operand = MaxActionCount;

                    MethodBody kInputControllerConstructorBody = CecilHelper
                                                                 .GetMethodDefinition(
                        this._firstPassModule,
                        kInputController,
                        ".ctor").Body;

                    kInputControllerConstructorBody
                    .Instructions.First(instruction => instruction.OpCode == OpCodes.Ldc_I4).Operand = MaxActionCount;
                }
                else
                {
                    Console.WriteLine("Can't find type KInputController.KeyDef");

                    this.Failed = true;
                }
            }
            else
            {
                Console.WriteLine("Can't find type KInputController");

                this.Failed = true;
            }
        }
        public bool InjectDefaultAndBackup(InjectorState injectorState)
        {
            var coreModule     = CecilHelper.GetModule(Paths.DefaultCoreAssemblyPath, Paths.ManagedDirectoryPath);
            var materialModule = CecilHelper.GetModule(Paths.DefaultMaterialAssemblyPath, Paths.ManagedDirectoryPath);
            var onionModule    = CecilHelper.GetModule(Paths.DefaultOnionAssemblyPath, Paths.ManagedDirectoryPath);

            var csharpModule    = CecilHelper.GetModule(Paths.DefaultAssemblyCSharpPath, Paths.ManagedDirectoryPath);
            var firstPassModule = CecilHelper.GetModule(Paths.DefaultAssemblyFirstPassPath, Paths.ManagedDirectoryPath);

            var injection = new Injection(coreModule, materialModule, onionModule, csharpModule, firstPassModule)
            {
                Logger = Logger
            };

            injection.Inject(injectorState);

            BackupAndSaveCSharpModule(csharpModule);
            BackupAndSaveFirstPassModule(firstPassModule);

            return(injection.Failed);
        }
Example #17
0
        private void AttachCustomActionToToggle()
        {
            var onToggleSelectMethod     = CecilHelper.GetMethodDefinition(_csharpModule, "OverlayMenu", "OnToggleSelect");
            var onToggleSelectMethodBody = onToggleSelectMethod.Body;

            var firstInstruction = onToggleSelectMethodBody.Instructions.First();

            var instructionsToAdd = new List <Instruction>
            {
                Instruction.Create(OpCodes.Brfalse, firstInstruction),
                Instruction.Create(OpCodes.Ret)
            };

            new InstructionInserter(onToggleSelectMethod).InsertBefore(firstInstruction, instructionsToAdd);

            _materialToCSharpInjector.InjectAsFirst(
                "InjectionEntry",
                "EnterToggle",
                onToggleSelectMethodBody,
                true, 1);
        }
Example #18
0
        public void InjectDefaultAndBackup()
        {
            string path = Directory.GetCurrentDirectory();

            try
            {
                //ModuleDefinition onionModule = CecilHelper.GetModule("\\ONI-Common.dll", path);
                ModuleDefinition csharpModule    = CecilHelper.GetModule("\\Assembly-CSharp.dll", path);
                ModuleDefinition firstPassModule = CecilHelper.GetModule("\\Assembly-CSharp-firstpass.dll", path);

                try
                {
                    //InjectorOnion injection = new InjectorOnion(onionModule, csharpModule, firstPassModule);
                    //injection.Inject();

                    //InjectPatchedSign(csharpModule, firstPassModule);
                }
                catch (Exception ex)
                {
                    ModLogger.WriteLine(ConsoleColor.Red, "Onion injector errored: " + ex);
                    throw;
                }

                try
                {
                    this.BackupAndSaveCSharpModule(csharpModule, path);
                    this.BackupAndSaveFirstPassModule(firstPassModule, path);
                }
                catch (Exception ex)
                {
                    ModLogger.WriteLine(ConsoleColor.Red, "Backup errored: " + ex);
                    throw;
                }
            }
            catch (Exception ex)
            {
                ModLogger.WriteLine(ConsoleColor.Red, "ModuleDefinition errored: " + ex);
                throw;
            }
        }
Example #19
0
        public void InjectDefaultAndBackup()
        {
            string path = Directory.GetCurrentDirectory();

            try
            {
                ModuleDefinition onionModule     = CecilHelper.GetModule("\\ONI-Common.dll", path);
                ModuleDefinition csharpModule    = CecilHelper.GetModule("\\Assembly-CSharp.dll", path);
                ModuleDefinition firstPassModule = CecilHelper.GetModule("\\Assembly-CSharp-firstpass.dll", path);

                try
                {
                    InjectorOnion injection = new InjectorOnion(onionModule, csharpModule, firstPassModule);
                    injection.Inject();
                }
                catch
                {
                    Console.Error.WriteLine("Onion injector errored: \n");
                    throw;
                }
                try
                {
                    this.BackupAndSaveCSharpModule(csharpModule, path);
                    this.BackupAndSaveFirstPassModule(firstPassModule, path);
                }
                catch
                {
                    Console.Error.WriteLine("Backup errored: \n");
                    throw;
                }
            }
            catch
            {
                Console.Error.WriteLine("ModuleDefinition errored: \n");
                throw;
            }
        }
Example #20
0
        public void MakeMethodPublic(string typeName, string methodName)
        {
            MethodDefinition method = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName);

            method.IsPublic = true;
        }
Example #21
0
        public void MakeFieldPublic(string typeName, string fieldName)
        {
            FieldDefinition field = CecilHelper.GetFieldDefinition(this._targetModule, typeName, fieldName);

            field.IsPublic = true;
        }
 public bool IsCurrentAssemblyFirstpassPatched()
 => CecilHelper.GetModule(Paths.DefaultAssemblyFirstPassPath, Paths.ManagedDirectoryPath).Types.Any(TypePatched);
 private MethodBody GetMethodBody(string typeName, string methodName)
 => CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName).Body;