public void InitializePatch(ModuleDefMD module) { var importer = new Importer(module); // Import and store the patching methods _crafterLogicIsCraftRecipeFulfilledPatch = importer.Import(typeof(CrafterLogicHelper).GetMethod("IsCraftRecipeFulfilled")); _crafterLogicConsumeResourcesPatch = importer.Import(typeof(CrafterLogicHelper).GetMethod("ConsumeResources")); _constructableConstructPatch = importer.Import(typeof(ConstructableHelper).GetMethod("Construct")); _tooltipFactoryWriteIngredientsPatch = importer.Import(typeof(CrafterLogicHelper).GetMethod("WriteIngredients")); // CrafterLogic var originalCrafterLogic = module.Find("CrafterLogic", false); // Get the original methods we're going to replace _crafterLogicIsCraftRecipeFulfilledOriginal = originalCrafterLogic.FindMethod("IsCraftRecipeFulfilled"); _crafterLogicConsumeResourcesOriginal = originalCrafterLogic.FindMethod("ConsumeResources"); // Patch CrafterLogic Patch_CrafterLogic_IsCraftRecipeFulfilled(module); // Patch Construtable Patch_Constructable_Construct(module); // Patch the tooltip var originalTooltipFactory = module.Find("TooltipFactory", false); _tooltipFactoryWriteIngredientsOriginal = originalTooltipFactory.FindMethod("WriteIngredients"); Patch_Tooltip_WriteIngredients(module, originalTooltipFactory); }
internal static async Task <int> Execute(ModuleDefMD targetModule) { var bodyPartTypeDef = targetModule.Find("BodyPart", true); var controllerTypeDef = targetModule.Find("Controller", true); var onCollisionEnterMethod = bodyPartTypeDef.FindMethod("OnCollisionEnter"); var canFlyFieldDef = controllerTypeDef.FindField("canFly"); var bodyPartControllerFieldDef = bodyPartTypeDef.FindField("controller"); var instructionSignature = new List <Instruction> { new Instruction(OpCodes.Ldfld, bodyPartControllerFieldDef), new Instruction(OpCodes.Ldfld, canFlyFieldDef), new Instruction(OpCodes.Brtrue, new Instruction(OpCodes.Ldarg_1, null)), new Instruction(OpCodes.Ldarg_0, null) }; var matchedInstructions = InjectionHelpers.FetchInstructionsBySignature(onCollisionEnterMethod.Body.Instructions, instructionSignature, false); if (matchedInstructions != null) { // NOP the matched instructions matchedInstructions.ForEach(matchedInstruction => matchedInstruction.OpCode = OpCodes.Nop); } else { return(await Task.FromResult(2)); } return(await Task.FromResult(0)); }
private void ReloadDll(string fileName) { injModule = ModuleDefMD.Load(fileName); TypeDef injClass = injModule.Find(TypeName, false); if (injClass == null) { throw new NullReferenceException("injClass"); } injMethod = injClass.FindMethod(MethodName); if (injMethod == null) { throw new NullReferenceException("injMethod"); } TypeDef hookClass = injModule.Find("ClustertruckSplit.Hook", false); if (hookClass == null) { throw new NullReferenceException("hookClass"); } injHookMethod = hookClass.FindMethod("Initialize"); if (injHookMethod == null) { throw new NullReferenceException("injHookMethod"); } }
private bool InjectTrainerLogicModuleTypes() { var trainerOptionsTypeDef = _logicModule.Find("TrainerOptions", false); var trainerManagerTypeDef = _logicModule.Find("TrainerManager", false); var singletonTypeDef = _logicModule.Find("Singleton`1", true); var singletonSucceeded = InjectionHelpers.AddTypeToModule(singletonTypeDef, _targetModule); var trainerOptionsSucceeded = InjectionHelpers.AddTypeToModule(trainerOptionsTypeDef, _targetModule); var trainerManagerSucceeded = InjectionHelpers.AddTypeToModule(trainerManagerTypeDef, _targetModule); return(singletonSucceeded && trainerOptionsSucceeded && trainerManagerSucceeded); }
static Patcher() { patcherModule = ModuleDefMD.Load(typeof(Patcher).Module); modMethod = patcherModule.Find(typeof(Patcher).FullName, true).FindMethod(nameof(AtlasLoaderBootstrap)); ignoredAttribute = patcherModule.Find(typeof(InjectorIgnoredAttribute).FullName, true); patchedAttribute = patcherModule.Find(typeof(PatchedAttribute).FullName, true); patchedAttribute.Namespace = null; injectedAttribute = patcherModule.Find(typeof(InjectedAttribute).FullName, true); injectedAttribute.Namespace = null; patchedAttributeCtor = patchedAttribute.FindMethod(ctor); injectedAttributeCtor = injectedAttribute.FindMethod(ctor); }
private static void CreateHook(ModuleDefMD module, string source, Type target, string methodName) { TypeDef sourceType = module.Find(source, isReflectionName: true); MethodDef sourceMethod = sourceType.Methods.Single(m => m.Name == methodName); TypeDef targetType = module.GetNuterraType(target); MethodDef targetMethod = targetType.Methods.Single(m => m.Name == methodName); MethodDefUser clonedSource = CloneMethod(sourceMethod); sourceMethod.Body.Variables.Clear(); var defaultValueLocal = new Local(clonedSource.ReturnType, "defaultValue"); sourceMethod.Body.Variables.Add(defaultValueLocal); var body = sourceMethod.Body.Instructions; body.Clear(); int i = 0; for (int j = 0; j < sourceMethod.Parameters.Count; j++) { body.Insert(i++, OpCodes.Ldarg_S.ToInstruction(sourceMethod.Parameters[j])); } body.Insert(i++, OpCodes.Call.ToInstruction(clonedSource)); body.Insert(i++, OpCodes.Stloc.ToInstruction(defaultValueLocal)); body.Insert(i++, OpCodes.Ldarg_S.ToInstruction(sourceMethod.Parameters[0])); body.Insert(i++, OpCodes.Ldloc.ToInstruction(defaultValueLocal)); for (int j = 1; j < sourceMethod.Parameters.Count; j++) { body.Insert(i++, OpCodes.Ldarg_S.ToInstruction(sourceMethod.Parameters[j])); } body.Insert(i++, OpCodes.Call.ToInstruction(targetMethod)); body.Insert(i++, OpCodes.Ret.ToInstruction()); }
private void ApplySettings() { // apply settings here TypeDef sType = injModule.Find("ClustertruckSplit.Settings", false); if (sType == null) { throw new NullReferenceException("Settings Type not Found"); } MethodDef settingsMeth = sType.FindStaticConstructor(); for (int i = 0; i < settingsMeth.Body.Instructions.Count; i++) { Instruction inst = settingsMeth.Body.Instructions[i]; if (inst.OpCode == OpCodes.Ldc_I4_S && ((SByte)inst.Operand) == 10) { // sleep time settingsMeth.Body.Instructions[i].Operand = (SByte)pSettings.SleepTime; } else if (inst.OpCode == OpCodes.Ldstr) { switch ((string)inst.Operand) { case "LEVEL": settingsMeth.Body.Instructions[i].Operand = pSettings.LevelModeEnabled.ToString(); break; case "PAUSE": settingsMeth.Body.Instructions[i].Operand = pSettings.PauseEnabled.ToString(); break; case "RESET": settingsMeth.Body.Instructions[i].Operand = pSettings.ResetEnabled.ToString(); break; case "LiveSplit": settingsMeth.Body.Instructions[i].Operand = pSettings.PipeName; break; } } } tmpPatchDll = Environment.CurrentDirectory + @"\Data\DEL_" + Guid.NewGuid().ToString() + ".dll"; if (!Directory.Exists(tmpPatchDll)) { Directory.CreateDirectory(Path.GetDirectoryName(tmpPatchDll)); } dnlib.DotNet.Writer.ModuleWriterOptions mr = new dnlib.DotNet.Writer.ModuleWriterOptions(injModule); mr.MetaDataOptions.Flags = dnlib.DotNet.Writer.MetaDataFlags.PreserveAll; injModule.Write(tmpPatchDll, mr); ReloadDll(tmpPatchDll); // dnlib pls why you no unload? }
private static void Hook_StringLookup_GetString(ModuleDefMD module) { TypeDef cecilSource = module.Find("StringLookup", isReflectionName: true); MethodDef sourceMethod = cecilSource.Methods.Single(m => m.Name == "GetString"); TypeDef cecilTarget = module.GetNuterraType(typeof(Hooks.ResourceLookup)); MethodDef targetMethod = cecilTarget.Methods.Single(m => m.Name == nameof(Hooks.ResourceLookup.GetString)); var body = sourceMethod.Body.Instructions; var originalMethodStart = body.First(); int index = 0; body.Insert(index++, OpCodes.Ldarg_0.ToInstruction()); body.Insert(index++, OpCodes.Ldarg_2.ToInstruction()); body.Insert(index++, OpCodes.Call.ToInstruction(targetMethod)); body.Insert(index++, OpCodes.Stloc_0.ToInstruction()); body.Insert(index++, OpCodes.Ldloc_0.ToInstruction()); body.Insert(index++, OpCodes.Brfalse_S.ToInstruction(originalMethodStart)); body.Insert(index++, OpCodes.Ldloc_0.ToInstruction()); body.Insert(index++, OpCodes.Ret.ToInstruction()); /* * 0 0000 ldarg.0 * 1 0001 ldarg.2 * 2 0002 call string Maritaria.BlockLoader::StringLookup_GetString(int32, valuetype LocalisationEnums/StringBanks) * 3 0007 stloc.0 * 4 0008 ldloc.0 * 5 0009 brfalse.s { original method start instruction } * 6 000B ldloc.0 * 7 000C ret * ... remaining method code ... */ }
public void InitializePatch(ModuleDefMD module) { var importer = new Importer(module); // Import and store the patching methods var performSaveMethod = importer.Import(typeof(SaveHelper).GetMethod("PerformSave")); var startSaveInvokerMethod = importer.Import(typeof(SaveHelper).GetMethod("StartSaveInvoker")); var playerType = module.Find("Player", false); var autoSaveMethod = new MethodDefUser( "Autosave", MethodSig.CreateInstance(module.CorLibTypes.Void), MethodImplAttributes.IL | MethodImplAttributes.Managed, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.ReuseSlot ); playerType.Methods.Add(autoSaveMethod); var body = autoSaveMethod.Body = new CilBody(); body.Instructions.Add(OpCodes.Call.ToInstruction(performSaveMethod)); body.Instructions.Add(OpCodes.Ret.ToInstruction()); var awakeMethod = playerType.FindMethod("Awake"); var instructions = awakeMethod.Body.Instructions; instructions.Insert(instructions.Count - 1, OpCodes.Ldarg_0.ToInstruction()); instructions.Insert(instructions.Count - 1, OpCodes.Call.ToInstruction(startSaveInvokerMethod)); }
public static void EncryptStrings(ModuleDefMD targetModule, bool encodeStrings, string encryptionKey) { // Finds the injected 'ByteGuardStringProtections' class that contains all the decryption methods. TypeDef stringProtections = targetModule.Find("ByteGuard.Protections.Online.Runtime.ByteGuardStringProtections", true); // Finds the 'DecodeAndDecrypt' method located in the 'ByteGuardProtection' class/type. MethodDef decryptStringMethod = (encodeStrings ? stringProtections.FindMethod("DecodeAndDecrypt") : stringProtections.FindMethod("Decrypt")); // TODO: Enable this. // Encrypts all strings within the 'ByteGuardProtection' type using an offline key. foreach ( TypeDef t in targetModule.GetTypes() .Where(type => type.Namespace.Contains("ByteGuard.Protections.Online.Runtime"))) { EncryptOfflineType(t, stringProtections.FindMethod("DecodeAndDecryptK")); } // Iterates through all the types and methods that are editable. foreach (TypeDef t in targetModule.GetTypes().Where(type => !type.Namespace.Contains("ByteGuard.Protections.Online.Runtime"))) //TODO: Ignore any classes required for string decrypt { foreach (MethodDef m in t.Methods.Where(mtd => mtd.HasBody)) { // Iterates through each instruction and encrypts/encodes any 'ldstr' instruction. for (int i = 0; i < m.Body.Instructions.Count; i++) { // Stores the current instruction into a new variable. Instruction ins = m.Body.Instructions[i]; // Checks that the current instruction is a string and is not null. if (ins.Operand is string) { // Randomly generates the encryption key's starting index and length, this will be parsed from the 25-character downloadable decryption key. int keyStartPosition = R.Next(0, (encryptionKey.Length - 1)); int keyLength = R.Next(1, ((encryptionKey.Length - 1) - keyStartPosition)); // Parses the encryption key using the start index and length generated above. string key = encryptionKey.Substring(keyStartPosition, keyLength); // Changes the instruction operand to the encrypted version of the string. ins.Operand = Methods.EncryptString(ins.Operand.ToString(), key, encodeStrings); // Inserts three new instructions, one of the start index of the key, the next is the key length and the third is the call to the decryption method. m.Body.Instructions.Insert(i + 1, Instruction.CreateLdcI4(keyStartPosition)); m.Body.Instructions.Insert(i + 2, Instruction.CreateLdcI4(keyLength)); m.Body.Instructions.Insert(i + 3, Instruction.Create(OpCodes.Call, decryptStringMethod)); // Simplify the branches of any modified methods as some projects can crash without this. m.Body.Instructions.SimplifyBranches(); // Increase the counter by 3 to skip over the newly added instructions. i += 3; } } } } }
private void PatchNuclearUpgrade_SubRoot(ModuleDefMD module) { var subRootType = module.Find("SubRoot", false); var fieldToAdd = new FieldDefUser("nuclearUpgrade", new FieldSig(module.CorLibTypes.Int32)) { Attributes = FieldAttributes.Public | FieldAttributes.NotSerialized }; subRootType.Fields.Add(fieldToAdd); var setCyclopsUpgradesMethod = subRootType.FindMethod("SetCyclopsUpgrades"); var importer = new Importer(module); var setCyclopsUpgradesPatchMethod = importer.Import(typeof(NuclearUpgradeHelper).GetMethod("SetCyclopsUpgrades")); var body = setCyclopsUpgradesMethod.Body = new CilBody(); body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction()); body.Instructions.Add(OpCodes.Call.ToInstruction(setCyclopsUpgradesPatchMethod)); body.Instructions.Add(OpCodes.Ret.ToInstruction()); PatchNuclearUpgrade_SubRoot_Update(module, subRootType, importer); }
private static void Hook_BugReportFlagger(ModuleDefMD module) { TypeDef bugReportFlagger = module.GetNuterraType(typeof(Hooks.BugReports)); MethodDef markReportForm = bugReportFlagger.Methods.Single(m => m.Name == nameof(Hooks.BugReports.MarkReportForm)); MethodDef markUserMessage = bugReportFlagger.Methods.Single(m => m.Name == nameof(Hooks.BugReports.MarkUserMessage)); TypeDef bugReporter = module.Find("UIScreenBugReport", isReflectionName: true); TypeDef postIterator = bugReporter.NestedTypes.Single(t => t.FullName.Contains("UIScreenBugReport/<PostIt>")); MethodDef moveNext = postIterator.Methods.Single(m => m.Name == "MoveNext"); FieldDef bodyField = bugReporter.Fields.Single(f => f.Name == "m_Body"); var body = moveNext.Body.Instructions; Instruction formInit = body.First(i => i.OpCode == OpCodes.Newobj); int index = body.IndexOf(formInit); Instruction storeForm = body[index + 1]; FieldDef formField = (FieldDef)storeForm.Operand; index += 2; body.Insert(index++, new Instruction(OpCodes.Ldarg_0)); body.Insert(index++, new Instruction(OpCodes.Ldfld, formField)); body.Insert(index++, new Instruction(OpCodes.Call, markReportForm)); Instruction loadBodyField = body.First(i => i.OpCode == OpCodes.Ldfld && i.Operand == bodyField); index = body.IndexOf(loadBodyField); Instruction readBodyText = body[index + 1]; body.Insert(index + 2, new Instruction(OpCodes.Call, markUserMessage)); }
public static bool ClearMethodBody(ModuleDefMD moduleDef, string typeDefName, string methodDefName) { var typeDef = moduleDef.Find(typeDefName, true); if (typeDef == null) { return(false); } var methodDef = typeDef.FindMethod(methodDefName); if (methodDef == null) { return(false); } if (methodDef.Body == null) { methodDef.Body = new CilBody(); } methodDef.Body.Instructions.Clear(); methodDef.Body.Instructions.Add(new Instruction(OpCodes.Ret)); return(true); }
private MethodDef GetMethod(ModuleDefMD module, string className, string FullMethodName) { var classDef = module.Find(className, true); var methodDef = classDef.Methods.Where(x => x.FullName == FullMethodName).FirstOrDefault(); return(methodDef); }
private static void HijackFont(ModuleDefMD module) { TypeDef UICoords = module.Find("UICoords", false); FieldDef m_Text = UICoords.Fields.First(f => f.Name == "m_Text"); PropertyDef font = m_Text.DeclaringType.FindProperty("font"); TypeSig fontType = font.DeclaringType.ToTypeSig(); FieldDef Exo = new FieldDefUser("Exo", new FieldSig(fontType), FieldAttributes.Public | FieldAttributes.Static); UICoords.Fields.Add(Exo); var body = UICoords.Methods.First(m => m.Name == "OnPool").Body.Instructions; body.Insert(body.Count - 1, OpCodes.Ldarg_0.ToInstruction()); body.Insert(body.Count - 1, OpCodes.Ldfld.ToInstruction(m_Text)); body.Insert(body.Count - 1, OpCodes.Callvirt.ToInstruction(font.GetMethod)); body.Insert(body.Count - 1, OpCodes.Stsfld.ToInstruction(Exo)); /* * 11 002B ldarg.0 * 12 002C ldfld class [UnityEngine.UI]UnityEngine.UI.Text UICoords::m_Text * 13 0031 callvirt instance class [UnityEngine]UnityEngine.Font [UnityEngine.UI]UnityEngine.UI.Text::get_font() * 14 0036 stsfld class [UnityEngine]UnityEngine.Font UICoords::Exo */ }
public async Task <bool> CheckTrainerAlreadyPatched() { var stickFightConstantsTypeDef = _targetModule.Find("StickFightConstants", false); // Check if patch indicator exists in the target module. if (stickFightConstantsTypeDef != null) { var trainerPatchIndicator = stickFightConstantsTypeDef.FindField("LoxaTrainerPatch"); if (trainerPatchIndicator != null) { return(await Task.FromResult(true)); } } return(await Task.FromResult(false)); }
internal static async Task <int> Execute(ModuleDefMD targetModule) { // Fetch target type defs var controllerTypeDef = targetModule.Find("Controller", true); // Fetch target method defs var controllerSetCollisionMethodDef = controllerTypeDef.FindMethod("SetCollision"); // Fetch target field defs var controllerIsAiFieldDef = controllerTypeDef.FindField("isAI"); var controllerPlayerIdFieldDef = controllerTypeDef.FindField("playerID"); /* * * 32 004C ldarg.0 * 33 004D ldfld bool Controller::isAI * 34 0052 brfalse.s 40 (0063) ldloc.2 * */ // Signature of the condition to which the check will be added var controllerSetCollisionAiCheckInstructionSignature = new List <Instruction> { new Instruction(OpCodes.Ldarg_0), new Instruction(OpCodes.Ldfld, controllerIsAiFieldDef), new Instruction(OpCodes.Brfalse, null) }; var matchedControllerSetCollisionAiCheckMethodInstructions = InjectionHelpers.FetchInstructionsBySignature(controllerSetCollisionMethodDef.Body.Instructions, controllerSetCollisionAiCheckInstructionSignature, false); if (matchedControllerSetCollisionAiCheckMethodInstructions != null) { var branchInstruction = matchedControllerSetCollisionAiCheckMethodInstructions.Last(); var injectionIndex = controllerSetCollisionMethodDef.Body.Instructions.IndexOf(branchInstruction) + 1; // Set unique gameObject layer in Controller.SetCollision for AIs with Player IDs. var controllerSetCollisionAiCheckInstructionsToInject = new List <Instruction> { new Instruction(OpCodes.Ldarg_0), new Instruction(OpCodes.Ldfld, controllerPlayerIdFieldDef), new Instruction(OpCodes.Ldc_I4_0), new Instruction(OpCodes.Bge_S, branchInstruction.Operand), }; // Add new instructions after the matched signature for (var i = 0; i < controllerSetCollisionAiCheckInstructionsToInject.Count; i++) { controllerSetCollisionMethodDef.Body.Instructions.Insert(injectionIndex + i, controllerSetCollisionAiCheckInstructionsToInject[i]); } controllerSetCollisionMethodDef.Body.UpdateInstructionOffsets(); } else { return(await Task.FromResult(1)); } return(await Task.FromResult(0)); }
private static void Redirect(ModuleDefMD module, string sourceType, Type targetType, RedirectSettings settings) { TypeDef cecilSource = module.Find(sourceType, isReflectionName: true); MethodDef sourceMethod = cecilSource.Methods.Single(m => m.Name == settings.SourceMethod); TypeDef cecilTarget = module.GetNuterraType(targetType); MethodDef targetMethod = cecilTarget.Methods.Single(m => m.Name == settings.TargetMethod); var body = sourceMethod.Body.Instructions; if (settings.ReplaceBody) { sourceMethod.Body.Variables.Clear(); sourceMethod.Body.ExceptionHandlers.Clear(); body.Clear(); body.Add(OpCodes.Ret.ToInstruction()); } int insertedInstructionCounter = settings.InsertionStart; //TODO: Use insertbefore instead if (settings.AppendToEnd) { if (body.Count > 0) { insertedInstructionCounter = body.Count - 1; //Last IL before ret instruction } } int insertionStart = insertedInstructionCounter; if (settings.PassArguments) { if (sourceMethod.Parameters.Count != targetMethod.Parameters.Count) { throw new Exception($"Parameter count mismatch for {sourceMethod} -> {targetMethod}"); } for (int i = 0; i < sourceMethod.Parameters.Count; i++) { body.Insert(insertedInstructionCounter++, GetLoadArgOpCode(i, sourceMethod, targetMethod)); } } body.Insert(insertedInstructionCounter++, OpCodes.Call.ToInstruction(targetMethod)); if (settings.AppendToEnd) { Instruction ret = body.Last(); foreach (Instruction instr in body) { if (instr.Operand is Instruction) { Instruction jumpTarget = instr.Operand as Instruction; if (jumpTarget == ret) { instr.Operand = body[insertionStart]; } } } } }
/// <summary> /// Injects/merges all the required types into the target module. /// </summary> /// <param name="targetModule">The module to inject the types into.</param> private static void Merge(ModuleDef targetModule) { ModuleDefMD currentModule = ModuleDefMD.Load(typeof(AntiTamperJIT).Assembly.ManifestModule); Merger.Merge(targetModule, currentModule, "ByteGuard.Protections.Online.Runtime.JIT"); TypeDef emptyType = currentModule.Find("EmptyType", true); targetModule.Types.Add(Cloner.Clone(emptyType, targetModule)); }
private void PatchNuclearUpgrade_CraftData(ModuleDefMD module) { var craftDataType = module.Find("CraftData", false); var equipmentTypesField = craftDataType.FindField("equipmentTypes"); equipmentTypesField.Attributes = FieldAttributes.Public | FieldAttributes.Static; var equipmentType = module.Find("Equipment", false); var isCompatibleMethod = equipmentType.FindMethod("IsCompatible"); var importer = new Importer(module); var isCompatiblePatchMethod = importer.Import(typeof(NuclearUpgradeHelper).GetMethod("IsCompatible")); var body = isCompatibleMethod.Body = new CilBody(); body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction()); body.Instructions.Add(OpCodes.Ldarg_1.ToInstruction()); body.Instructions.Add(OpCodes.Call.ToInstruction(isCompatiblePatchMethod)); body.Instructions.Add(OpCodes.Ret.ToInstruction()); }
public void InitializePatch(ModuleDefMD module) { // Patching this separately as the default mod method fires too early var importer = new Importer(module); var addKnownTechMethod = importer.Import(typeof(DefaultMod).GetMethod("AddNewKnownTech")); var knownTechType = module.Find("KnownTech", false); var initializeMethod = knownTechType.FindMethod("Initialize"); initializeMethod.Body.Instructions.Insert(initializeMethod.Body.Instructions.Count - 1, OpCodes.Call.ToInstruction(addKnownTechMethod)); }
internal static async Task <int> Execute(ModuleDefMD targetModule) { var stickFightConstantsTypeDef = targetModule.Find("StickFightConstants", false); if (stickFightConstantsTypeDef == null) { return(await Task.FromResult(1)); } stickFightConstantsTypeDef.Fields.Add(new FieldDefUser("LoxaTrainerPatch", new FieldSig(targetModule.CorLibTypes.Boolean), FieldAttributes.Private)); return(await Task.FromResult(0)); }
private void PatchNuclearUpgrade_EquipmentType(ModuleDefMD module) { var equipmentType = module.Find("EquipmentType", false); FieldDef fieldToAdd = new FieldDefUser("NuclearReactorOrCyclopsModule", new FieldSig(new ValueTypeSig(equipmentType))) { Constant = module.UpdateRowId(new ConstantUser(NuclearUpgradeHelper.NuclearReactorOrCyclopsModule, equipmentType.GetEnumUnderlyingType().ElementType)), Attributes = FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.HasDefault | FieldAttributes.Public }; equipmentType.Fields.Add(fieldToAdd); }
/// <summary> /// Injects the protection runtime methods and calls the 'InitializeByteGuard' method upon module launch. /// </summary> /// <param name="fileLocation">The file location of the file to protect.</param> private static ModuleDefMD InitializeProtection(string fileLocation) { ModuleDefMD targetModule = ModuleDefMD.Load(fileLocation); ModuleDefMD protectionModule = ModuleDefMD.Load("ByteGuard.Protections.dll"); targetModule = (ModuleDefMD)Merger.Merge(targetModule, protectionModule, "ByteGuard.Protections.Online.Runtime", false); TypeDef byteguardCore = targetModule.Find("ByteGuard.Protections.Online.Runtime.ByteGuardCore", true); MethodDef cctor = targetModule.GlobalType.FindOrCreateStaticConstructor(); MethodDef initializeByteguard = byteguardCore.FindMethod("InitializeByteGuard"); cctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, initializeByteguard)); return(targetModule); }
private void InjectType() { ModuleDefMD targetModule = ModuleDefMD.Load(@"A:\BlankForm.exe"); ModuleDefMD currentModule = ModuleDefMD.Load(typeof(BlankType).Assembly.ManifestModule); TypeDef typeToInject = currentModule.Find("ByteGuard.Tests.TestClass", true); TypeDef clonedType = Engine.Cloner.Clone(typeToInject, targetModule); MethodDef ctor = targetModule.GlobalType.FindOrCreateStaticConstructor(); MethodDef test = clonedType.FindMethod("TestMethod"); ctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, test)); targetModule.Types.Add(clonedType); targetModule.Write(@"A:\MergeTest.exe"); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); var youSubtitle = new Subtitle { Text = "You", Loaded = "You", Translation = "You", Offset = 0 }; youSubtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(youSubtitle); ModuleDefMD module = ModuleDefMD.Load(Path); TypeDef skillType = module.Find("Sunshine.Metric.Skill", false); MethodDef constructor = skillType.FindMethod(".cctor"); int i = 1; foreach (Instruction instr in constructor.Body.Instructions) { if (instr.OpCode != OpCodes.Ldstr) { continue; } string str = (string)instr.Operand; var subtitle = new Subtitle { Text = str, Loaded = str, Translation = str, Offset = i }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); i++; } var agentSubtitle = new Subtitle { Text = "Tutorial Agent", Loaded = "Tutorial Agent", Translation = "Tutorial Agent", Offset = i }; agentSubtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(agentSubtitle); result.Sort(); LoadChanges(result); return(result); }
public static bool RemoveTypeFromModule(string typeName, ModuleDefMD moduleDefMdTarget) { if (typeName == null || moduleDefMdTarget == null) { return(false); } var typeDefMatch = moduleDefMdTarget.Find(typeName, false); if (typeDefMatch != null) { moduleDefMdTarget.Types.Remove(typeDefMatch); return(true); } return(false); }
private static void Hook_SpriteFetcher_GetSprite(ModuleDefMD module) { TypeDef cecilSource = module.Find("SpriteFetcher", isReflectionName: true); MethodDef sourceMethod = cecilSource.Methods.Single(m => m.FullName == "UnityEngine.Sprite SpriteFetcher::GetSprite(ObjectTypes,System.Int32)"); TypeDef cecilTarget = module.GetNuterraType(typeof(Hooks.ResourceLookup)); MethodDef targetMethod = cecilTarget.Methods.Single(m => m.Name == nameof(Hooks.ResourceLookup.GetSprite)); AssemblyRef unityEngine = module.GetAssemblyRef(new UTF8String("UnityEngine")); TypeRefUser unityEngine_Object = new TypeRefUser(module, new UTF8String("UnityEngine"), new UTF8String("Object"), unityEngine); TypeSig objectSig = unityEngine_Object.ToTypeSig(); MethodSig op_Equality = MethodSig.CreateStatic(module.CorLibTypes.Boolean, objectSig, objectSig); MemberRefUser op_EqualityMethod = new MemberRefUser(module, new UTF8String("op_Inequality"), op_Equality, unityEngine_Object); var body = sourceMethod.Body.Instructions; var originalMethodStart = body.First(); int index = 0; sourceMethod.Body.MaxStack = 6; body.Insert(index++, new Instruction(OpCodes.Ldarg_1)); body.Insert(index++, new Instruction(OpCodes.Ldarg_2)); body.Insert(index++, new Instruction(OpCodes.Call, targetMethod)); body.Insert(index++, new Instruction(OpCodes.Stloc_0)); body.Insert(index++, new Instruction(OpCodes.Ldloc_0)); body.Insert(index++, new Instruction(OpCodes.Ldnull)); body.Insert(index++, new Instruction(OpCodes.Call, op_EqualityMethod)); body.Insert(index++, new Instruction(OpCodes.Brfalse_S, originalMethodStart)); body.Insert(index++, new Instruction(OpCodes.Ldloc_0)); body.Insert(index++, new Instruction(OpCodes.Ret)); /* * 0 0000 ldarg.1 * 1 0001 ldarg.2 * 2 0002 call class [UnityEngine]UnityEngine.Sprite Maritaria.BlockLoader::SpriteFetcher_GetSprite(valuetype ObjectTypes, int32) * 3 0007 stloc.0 * 4 0008 ldloc.0 * 5 0009 ldnull * 6 000A call bool [UnityEngine]UnityEngine.Object::op_Inequality(class [UnityEngine]UnityEngine.Object, class [UnityEngine]UnityEngine.Object) * 7 000F brfalse.s { original method start instruction } * 8 0011 ldloc.0 * 9 0012 ret * ... remaining method code ... */ }
public IEnumerable <Record> Collect() { var asm = typeof(ConfMgr).Assembly; foreach (var baseClass in CollectConfBaseClasses()) { var baseTypeName = baseClass.Name.ToString(); var itemTypeName = baseTypeName.Substring(0, baseTypeName.Length - 4) + "Item"; var name = baseTypeName.Substring(4, baseTypeName.Length - 8); var managedBaseType = asm.GetType(baseTypeName); Logger.Assert(managedBaseType != null, $"Type {baseTypeName} must exist in unhollowed assembly"); var managedItemType = asm.GetType(itemTypeName); Logger.Assert(managedItemType != null, $"Type {itemTypeName} must exist in unhollowed assembly"); var itemType = module.Find(itemTypeName, false); Logger.Assert(itemType != null, $"Type {itemTypeName} must exist in dumped assembly"); var ctorInfo = GetProperConstructorInfo(managedItemType); var ctorToken = GetProperConstructorToken(itemType, ctorInfo); var classPtr = IL2CPP.GetIl2CppClass("Assembly-CSharp.dll", "", itemTypeName); IL2CPP.il2cpp_runtime_class_init(classPtr); var ctorVa = IL2CPP.GetIl2CppMethodByToken(classPtr, ctorToken); var fields = GetItemFields(ctorInfo, itemType, managedItemType).ToArray(); // GetIl2CppMethodByToken sometimes points to dynamic generated function, so use RVA in dummy dll directly. var finalInitRva = GetFinalInitRva(baseClass); yield return(new Record { Name = name, BaseType = managedBaseType, ItemType = managedItemType, NativeItemClassPtr = classPtr, ItemCtor = (ctorInfo, ctorVa), FieldsInfo = fields, FinalInitVa = RvaToVa(finalInitRva), });
public static bool SetMethodAccessModifier(ModuleDefMD module, string typeDefName, string methodName, MethodAttributes methodAttribute) { var typeDef = module.Find(typeDefName, true); if (typeDef == null) { return(false); } var methodDef = typeDef.FindMethod(methodName); if (methodDef == null) { return(false); } methodDef.Access = methodAttribute; return(true); }