Beispiel #1
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;
            }
        }
Beispiel #2
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)
        {
            var method     = CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName);
            var methodBody = method.Body;

            ClearAllButLast(methodBody);
        }
        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]);
        }
Beispiel #5
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);
        }
        public void ClearAllButLast(string typeName, string methodName)
        {
            MethodDefinition method     = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName);
            MethodBody       methodBody = method.Body;

            this.ClearAllButLast(methodBody);
        }
        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);
        }
Beispiel #8
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);
        }
Beispiel #9
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);
        }
Beispiel #10
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;
            }
        }
Beispiel #11
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);
        }
Beispiel #12
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;
            }
        }
Beispiel #13
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);
        }
Beispiel #14
0
        public void MakeMethodPublic(string typeName, string methodName)
        {
            MethodDefinition method = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName);

            method.IsPublic = true;
        }
 private MethodBody GetMethodBody(string typeName, string methodName)
 => CecilHelper.GetMethodDefinition(_targetModule, typeName, methodName).Body;