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); }
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; } }
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); }
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); }
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); }
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); }
// 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); }
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); }
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); }
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; } }
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); }
// 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); }
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); }
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; } }
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; } }
public void MakeMethodPublic(string typeName, string methodName) { MethodDefinition method = CecilHelper.GetMethodDefinition(this._targetModule, typeName, methodName); method.IsPublic = true; }
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;