コード例 #1
0
ファイル: Modify.cs プロジェクト: derekbking/uMod.Patcher
        private TypeDefinition GetType(string assemblyName, string typeName, Patching.Patcher patcher)
        {
            string targetDir = patcher != null ? patcher.PatchProject.TargetDirectory : PatcherForm.MainForm.CurrentProject.TargetDirectory;
            DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();

            resolver.AddSearchDirectory(targetDir);
            string             filename = Path.Combine(targetDir, assemblyName.Replace(".dll", "") + ".dll");
            AssemblyDefinition assem    = AssemblyDefinition.ReadAssembly(filename, new ReaderParameters {
                AssemblyResolver = resolver
            });

            if (assem == null)
            {
                ShowMsg($"The Assembly '{assemblyName}' for '{Name}' could not be found!", "Missing Assembly", patcher);
                return(null);
            }
            TypeDefinition type = assem.MainModule.GetType(typeName);

            if (type == null)
            {
                ShowMsg($"The Type '{typeName}' for '{Name}' could not be found!", "Missing Type", patcher);
                return(null);
            }
            return(type);
        }
コード例 #2
0
ファイル: Field.cs プロジェクト: MrBlue/uMod.Patcher
 protected void ShowMsg(string msg, string header, Patching.Patcher patcher = null)
 {
     if (patcher != null)
     {
         patcher.Log(msg);
     }
     else
     {
         MessageBox.Show(msg, header, MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
コード例 #3
0
ファイル: InitOxide.cs プロジェクト: derekbking/uMod.Patcher
        public override bool ApplyPatch(MethodDefinition original, ILWeaver weaver, AssemblyDefinition oxideassembly, Patching.Patcher patcher = null)
        {
            MethodDefinition initoxidemethod = oxideassembly.MainModule.Types
                                               .Single(t => t.FullName == "Oxide.Core.Interface")
                                               .Methods.Single(m => m.IsStatic && m.Name == "Initialize");

            // Start injecting where requested
            weaver.Pointer = InjectionIndex;

            // Get the existing instruction we're going to inject behind
            Instruction existing;

            try
            {
                existing = weaver.Instructions[weaver.Pointer];
            }
            catch (ArgumentOutOfRangeException)
            {
                ShowMsg($"The injection index specified for {Name} is invalid!", "Invalid Index", patcher);
                return(false);
            }

            // Load the hook name
            Instruction firstinjected = weaver.Add(Instruction.Create(OpCodes.Call, weaver.Module.Import(initoxidemethod)));

            // Find all instructions which pointed to the existing and redirect them
            for (int i = 0; i < weaver.Instructions.Count; i++)
            {
                Instruction ins = weaver.Instructions[i];
                if (ins.Operand != null && ins.Operand.Equals(existing))
                {
                    // Check if the instruction lies within our injection range
                    // If it does, it's an instruction we just injected so we don't want to edit it
                    if (i < InjectionIndex || i > weaver.Pointer)
                    {
                        ins.Operand = firstinjected;
                    }
                }
            }
            return(true);
        }
コード例 #4
0
ファイル: Modify.cs プロジェクト: derekbking/uMod.Patcher
        public override bool ApplyPatch(MethodDefinition original, ILWeaver weaver, AssemblyDefinition oxidemodule, Patching.Patcher patcher = null)
        {
            List <Instruction> insts = new List <Instruction>();

            foreach (InstructionData instructionData in Instructions)
            {
                Instruction instruction;
                try
                {
                    instruction = CreateInstruction(original, weaver, instructionData, insts, patcher);
                }
                catch (ArgumentOutOfRangeException)
                {
                    instruction = null;
                    ShowMsg($"Could not create instruction for {Name}!", "Instruction failed", patcher);
                }
                if (instruction == null)
                {
                    return(false);
                }

                insts.Add(instruction);
            }
            // Start injecting where requested
            weaver.Pointer = InjectionIndex;

            if (!weaver.RemoveAfter(RemoveCount))
            {
                ShowMsg($"The remove count specified for {Name} is invalid!", "Invalid Remove Count", patcher);
                return(false);
            }
            if (Instructions.Count == 0)
            {
                return(true);
            }

            // Get the existing instruction we're going to inject behind
            Instruction existing;

            try
            {
                existing = weaver.Instructions[weaver.Pointer];
            }
            catch (ArgumentOutOfRangeException)
            {
                ShowMsg($"The injection index specified for {Name} is invalid!", "Invalid Index", patcher);
                return(false);
            }
            foreach (Instruction inst in insts)
            {
                weaver.Add(inst);
            }
            // Find all instructions which pointed to the existing and redirect them
            for (int i = 0; i < weaver.Instructions.Count; i++)
            {
                Instruction ins = weaver.Instructions[i];
                if (ins.Operand != null && ins.Operand.Equals(existing))
                {
                    // Check if the instruction lies within our injection range
                    // If it does, it's an instruction we just injected so we don't want to edit it
                    if (i < InjectionIndex || i > weaver.Pointer)
                    {
                        ins.Operand = insts[0];
                    }
                }
            }
            return(true);
        }
コード例 #5
0
ファイル: Modify.cs プロジェクト: derekbking/uMod.Patcher
        private Instruction CreateInstruction(MethodDefinition method, ILWeaver weaver, InstructionData instructionData, List <Instruction> insts, Patching.Patcher patcher)
        {
            OpCode      opcode      = opCodes[instructionData.OpCode];
            OpType      optype      = instructionData.OpType;
            Instruction Instruction = null;
            int         start;
            int         end;

            switch (optype)
            {
            case OpType.None:
                Instruction = Instruction.Create(opcode);
                break;

            case OpType.Byte:
                Instruction = Instruction.Create(opcode, Convert.ToByte(instructionData.Operand));
                break;

            case OpType.SByte:
                Instruction = Instruction.Create(opcode, Convert.ToSByte(instructionData.Operand));
                break;

            case OpType.Int32:
                Instruction = Instruction.Create(opcode, Convert.ToInt32(instructionData.Operand));
                break;

            case OpType.Int64:
                Instruction = Instruction.Create(opcode, Convert.ToInt64(instructionData.Operand));
                break;

            case OpType.Single:
                Instruction = Instruction.Create(opcode, Convert.ToSingle(instructionData.Operand));
                break;

            case OpType.Double:
                Instruction = Instruction.Create(opcode, Convert.ToDouble(instructionData.Operand));
                break;

            case OpType.String:
                Instruction = Instruction.Create(opcode, Convert.ToString(instructionData.Operand));
                break;

            case OpType.VerbatimString:
                Instruction = Instruction.Create(opcode, Regex.Unescape(Convert.ToString(instructionData.Operand)));
                break;

            case OpType.Instruction:
                int index = Convert.ToInt32(instructionData.Operand);
                Instruction = Instruction.Create(opcode, index < 1024 ? weaver.Instructions[index] : insts[index - 1024]);
                break;

            case OpType.Variable:
                Instruction = Instruction.Create(opcode, method.Body.Variables[Convert.ToInt32(instructionData.Operand)]);
                break;

            case OpType.Parameter:
                Instruction = Instruction.Create(opcode, method.Parameters[Convert.ToInt32(instructionData.Operand)]);
                break;

            case OpType.Field:
                string[]       fieldData = Convert.ToString(instructionData.Operand).Split('|');
                TypeDefinition fieldType = GetType(fieldData[0], fieldData[1], patcher);
                if (fieldType == null)
                {
                    return(null);
                }

                FieldDefinition fieldField = fieldType.Fields.FirstOrDefault(f => f.Name.Equals(fieldData[2]));
                if (fieldField == null)
                {
                    ShowMsg($"The Field '{fieldData[2]}' for '{Name}' could not be found!", "Missing Field", patcher);
                    return(null);
                }
                Instruction = Instruction.Create(opcode, method.Module.Import(fieldField));
                break;

            case OpType.Method:
                string[]       methodData = Convert.ToString(instructionData.Operand).Split('|');
                TypeDefinition methodType = GetType(methodData[0], methodData[1], patcher);
                if (methodType == null)
                {
                    return(null);
                }

                if (methodData.Length > 3)
                {
                    methodData[2] = string.Join("|", methodData.Skip(2).ToArray());
                }
                MethodReference methodMethod;
                start = methodData[2].IndexOf('(');
                end   = methodData[2].IndexOf(')');
                if (start >= 0 && end >= 0 && start < end)
                {
                    string           name      = TagsRegex.Replace(methodData[2], string.Empty).Trim();
                    string           methodSig = methodData[2].Substring(start + 1, end - start - 1);
                    string[]         sigData   = methodSig.Split(',');
                    TypeDefinition[] sigTypes  = new TypeDefinition[sigData.Length];
                    for (int i = 0; i < sigData.Length; i++)
                    {
                        string s       = sigData[i];
                        string sigName = s.Trim();
                        string assem   = "mscorlib";
                        if (sigName.Contains('|'))
                        {
                            string[] split = sigName.Split('|');
                            assem   = split[0].Trim();
                            sigName = split[1].Trim();
                        }
                        TypeDefinition sigType = GetType(assem, sigName, patcher);
                        if (sigType == null)
                        {
                            ShowMsg($"SigType '{sigName}' not found", "Missing Method", patcher);
                            return(null);
                        }
                        sigTypes[i] = sigType;
                    }
                    methodMethod = null;
                    foreach (MethodDefinition methodDefinition in methodType.Methods)
                    {
                        if (!methodDefinition.Name.Equals(name) || methodDefinition.Parameters.Count != sigTypes.Length)
                        {
                            continue;
                        }

                        bool match = true;
                        for (int i = 0; i < methodDefinition.Parameters.Count; i++)
                        {
                            ParameterDefinition parameter = methodDefinition.Parameters[i];
                            if (!parameter.ParameterType.FullName.Equals(sigTypes[i].FullName))
                            {
                                match = false;
                                break;
                            }
                        }
                        if (!match)
                        {
                            continue;
                        }

                        methodMethod = methodDefinition;
                        break;
                    }
                }
                else
                {
                    string methodName = methodData[2];
                    int    position   = methodName.IndexOf('[');
                    if (position > 0)
                    {
                        methodName = methodName.Substring(0, position);
                    }

                    methodMethod = methodType.Methods.FirstOrDefault(f =>
                    {
                        if (!f.Name.Equals(methodName))
                        {
                            return(false);
                        }

                        if (position <= 0)
                        {
                            return(true);
                        }

                        return(f.HasGenericParameters);
                    });
                }
                if (methodMethod == null)
                {
                    ShowMsg($"The Method '{methodData[2]}' for '{Name}' could not be found!", "Missing Method", patcher);
                    return(null);
                }
                start = methodData[2].IndexOf('[');
                end   = methodData[2].IndexOf(']');
                if (start >= 0 && end >= 0 && start < end)
                {
                    GenericInstanceMethod generic = new GenericInstanceMethod(methodMethod);
                    string           methodG      = methodData[2].Substring(start + 1, end - start - 1);
                    string[]         genData      = methodG.Split(',');
                    TypeDefinition[] genTypes     = new TypeDefinition[genData.Length];
                    for (int i = 0; i < genData.Length; i++)
                    {
                        string s       = genData[i];
                        string genName = s.Trim();
                        string assem   = "mscorlib";
                        if (genName.Contains('|'))
                        {
                            string[] split = genName.Split('|');
                            assem   = split[0].Trim();
                            genName = split[1].Trim();
                        }
                        TypeDefinition genType = GetType(assem, genName, patcher);
                        if (genType == null)
                        {
                            ShowMsg($"GenericType '{genName}' not found", "Missing Method", patcher);
                            return(null);
                        }
                        genTypes[i] = genType;
                    }
                    foreach (TypeDefinition type in genTypes)
                    {
                        generic.GenericArguments.Add(type);
                    }

                    methodMethod = generic;
                }
                Instruction = Instruction.Create(opcode, method.Module.Import(methodMethod));
                break;

            case OpType.Generic:
                break;

            case OpType.Type:
                string[]      typeData = Convert.ToString(instructionData.Operand).Split('|');
                TypeReference typeType = GetType(typeData[0], TagsRegex.Replace(typeData[1], string.Empty).Trim(), patcher);
                if (typeType == null)
                {
                    return(null);
                }

                start = typeData[1].IndexOf('[');
                end   = typeData[1].IndexOf(']');
                if (start >= 0 && end >= 0 && start < end)
                {
                    GenericInstanceType generic = new GenericInstanceType(typeType);
                    string           typeG      = typeData[1].Substring(start + 1, end - start - 1);
                    string[]         genData    = typeG.Split(',');
                    TypeDefinition[] genTypes   = new TypeDefinition[genData.Length];
                    for (int i = 0; i < genData.Length; i++)
                    {
                        string s       = genData[i];
                        string genName = s.Trim();
                        string assem   = "mscorlib";
                        if (genName.Contains('|'))
                        {
                            string[] split = genName.Split('|');
                            assem   = split[0].Trim();
                            genName = split[1].Trim();
                        }
                        TypeDefinition genType = GetType(assem, genName, patcher);
                        if (genType == null)
                        {
                            ShowMsg($"GenericType '{genName}' not found", "Missing Type", patcher);
                            return(null);
                        }
                        genTypes[i] = genType;
                    }
                    foreach (TypeDefinition type in genTypes)
                    {
                        generic.GenericArguments.Add(type);
                    }

                    typeType = generic;
                }
                Instruction = Instruction.Create(opcode, method.Module.Import(typeType));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            return(Instruction);
        }
コード例 #6
0
ファイル: Simple.cs プロジェクト: MrBlue/uMod.Patcher
        /// <summary>
        /// PrePatches this hook into the target weaver
        /// </summary>
        /// <param name="weaver"></param>
        /// <param name="oxidemodule"></param>
        /// <param name="original"></param>
        /// <param name="patcher"></param>
        public override bool PreparePatch(AssemblyDefinition assembly, MethodDefinition original, ILWeaver weaver, AssemblyDefinition oxidemodule, Patching.Patcher patcher = null)
        {
            if (DependsOnField != null)
            {
                if (!DependsOnField.Apply(assembly))
                {
                    return(false);
                }
            }

            return(base.PreparePatch(assembly, original, weaver, oxidemodule, patcher));
        }
コード例 #7
0
ファイル: Simple.cs プロジェクト: MrBlue/uMod.Patcher
        public override bool ApplyPatch(AssemblyDefinition assembly, MethodDefinition original, ILWeaver weaver, AssemblyDefinition oxideassembly, Patching.Patcher patcher = null)
        {
            // Get the call hook method (only grab object parameters: ignore the object[] hook)
            List <MethodDefinition> callhookmethods = oxideassembly.MainModule.Types
                                                      .Single(t => t.FullName == "Oxide.Core.Interface")
                                                      .Methods.Where(m => m.IsStatic && m.Name == "CallHook" && m.HasParameters && m.Parameters.Any(p => p.ParameterType.IsArray) == false)
                                                      .OrderBy(x => x.Parameters.Count)
                                                      .ToList();

            // Start injecting where requested
            weaver.Pointer = InjectionIndex;

            // Get the existing instruction we're going to inject behind
            Instruction existing;

            try
            {
                existing = weaver.Instructions[weaver.Pointer];
            }
            catch (ArgumentOutOfRangeException)
            {
                ShowMsg($"The injection index specified for {Name} is invalid!", "Invalid Index", patcher);
                return(false);
            }

            // Load the hook name
            Instruction hookname = weaver.Add(Instruction.Create(OpCodes.Ldstr, HookName));

            // Push the arguments array to the stack and make the call
            //VariableDefinition argsvar; //This is the object array

            // Create an object array and load all arguments into it
            Instruction firstinjected = PushArgsArray(original, weaver, out int argCount, patcher) ?? hookname;

            /*if (argsvar != null)
             * weaver.Ldloc(argsvar);
             * else
             * weaver.Add(Instruction.Create(OpCodes.Ldnull));*/
            weaver.Add(Instruction.Create(OpCodes.Call, original.Module.Import(callhookmethods[argCount])));

            // Deal with the return value
            DealWithReturnValue(original, null, weaver);
            //DealWithReturnValue(original, argsvar, weaver);

            // Find all instructions which pointed to the existing and redirect them
            for (int i = 0; i < weaver.Instructions.Count; i++)
            {
                Instruction ins = weaver.Instructions[i];
                if (ins.Operand != null && ins.Operand.Equals(existing))
                {
                    // Check if the instruction lies within our injection range
                    // If it does, it's an instruction we just injected so we don't want to edit it
                    if (i < InjectionIndex || i > weaver.Pointer)
                    {
                        ins.Operand = firstinjected;
                    }
                }
            }
            return(true);
        }
コード例 #8
0
ファイル: Simple.cs プロジェクト: MrBlue/uMod.Patcher
        private bool GetFieldOrProperty(ILWeaver weaver, MethodDefinition originalMethod, ref TypeDefinition currentArg, string target, Patching.Patcher patcher)
        {
            if (currentArg == null || string.IsNullOrEmpty(target))
            {
                return(false);
            }

            while (currentArg != null)
            {
                if (currentArg.IsClass)
                {
                    if (currentArg.HasFields)
                    {
                        foreach (FieldDefinition field in currentArg.Fields)
                        {
                            if (!string.Equals(field.Name, target, StringComparison.CurrentCultureIgnoreCase))
                            {
                                continue;
                            }

                            weaver.Add(field.Module == originalMethod.Module
                                ? Instruction.Create(OpCodes.Ldfld, field)
                                : Instruction.Create(OpCodes.Ldfld, originalMethod.Module.Import(field)));
                            currentArg = field.FieldType.Resolve();

                            return(true);
                        }
                    }
                }

                if (currentArg.HasProperties)
                {
                    foreach (PropertyDefinition property in currentArg.Properties)
                    {
                        if (!string.Equals(property.Name, target, StringComparison.CurrentCultureIgnoreCase))
                        {
                            continue;
                        }

                        weaver.Add(property.GetMethod.Module == originalMethod.Module
                            ? Instruction.Create(OpCodes.Callvirt, property.GetMethod)
                            : Instruction.Create(OpCodes.Callvirt, originalMethod.Module.Import(property.GetMethod)));
                        currentArg = property.PropertyType.Resolve();

                        return(true);
                    }
                }

                if (currentArg.HasInterfaces)
                {
                    foreach (TypeReference intf in currentArg.Interfaces)
                    {
                        TypeDefinition previousArg = currentArg;
                        currentArg = intf.Resolve();
                        if (GetFieldOrProperty(weaver, originalMethod, ref currentArg, target, patcher))
                        {
                            return(true);
                        }

                        currentArg = previousArg;
                    }
                }

                if (currentArg.BaseType != null && originalMethod.Module.Assembly != currentArg.BaseType.Module.Assembly)
                {
                    TypeReference      baseType         = currentArg.BaseType;
                    AssemblyDefinition baseTypeAssembly = AssemblyDefinition.ReadAssembly($"{(patcher != null ? patcher.PatchProject.TargetDirectory : PatcherForm.MainForm.CurrentProject.TargetDirectory)}\\{baseType.Scope.Name}{(baseType.Scope.Name.EndsWith(".dll") ? "" : ".dll")}");
                    currentArg = baseTypeAssembly.MainModule.Types.Single(x => x.FullName == baseType.FullName);
                }
                else
                {
                    currentArg = currentArg.BaseType?.Resolve();
                }
            }

            return(false);
        }
コード例 #9
0
ファイル: Simple.cs プロジェクト: MrBlue/uMod.Patcher
        private bool GetFieldOrProperty(ILWeaver weaver, MethodDefinition originalMethod, TypeDefinition currentArg, string[] target, Patching.Patcher patcher)
        {
            if (currentArg == null || target == null || target.Length == 0)
            {
                return(false);
            }

            int            i;
            TypeDefinition arg = currentArg;

            for (i = 0; i < target.Length; i++)
            {
                if (GetFieldOrProperty(weaver, originalMethod, ref arg, target[i], patcher))
                {
                    continue;
                }

                ShowMsg($"Could not find the field or property `{target[i]}` in any of the base classes or interfaces of `{currentArg.Name}`.", "Invalid field or property", patcher);
                return(false);
            }

            if (arg.IsValueType || arg.IsByReference)
            {
                weaver.Add(arg.Module == originalMethod.Module
                    ? Instruction.Create(OpCodes.Box, arg.Resolve())
                    : Instruction.Create(OpCodes.Box, originalMethod.Module.Import(arg.Resolve())));
            }

            return(i >= 1);
        }
コード例 #10
0
ファイル: Simple.cs プロジェクト: MrBlue/uMod.Patcher
        private Instruction PushArgsArray(MethodDefinition method, ILWeaver weaver, /*out VariableDefinition argsvar*/ out int argCount, Patching.Patcher patcher)
        {
            argCount = 0;
            // Are we going to use arguments?
            if (ArgumentBehavior == ArgumentBehavior.None)
            {
                // Push null and we're done
                //argsvar = null;
                return(null);
            }

            // Create array variable
            Instruction firstInstruction = null;

            // Are we using the argument string?
            if (ArgumentBehavior == ArgumentBehavior.UseArgumentString)
            {
                string[] args = ParseArgumentString(out string retvalue);
                if (args == null)
                {
                    // Silently fail, but at least produce valid IL
                    //argsvar = null;
                    return(null);
                }

                // Create the array

                /*argsvar = weaver.AddVariable(new ArrayType(method.Module.TypeSystem.Object), "args");
                 * firstInstruction = weaver.Add(ILWeaver.Ldc_I4_n(args.Length));
                 * weaver.Add(Instruction.Create(OpCodes.Newarr, method.Module.TypeSystem.Object));
                 * weaver.Stloc(argsvar);*/

                // Populate it
                for (int i = 0; i < args.Length; i++)
                {
                    argCount++;
                    string   arg    = args[i].ToLowerInvariant();
                    string[] target = null;
                    if (!string.IsNullOrEmpty(arg) && args[i].Contains("."))
                    {
                        string[] split = args[i].Split('.');
                        arg    = split[0];
                        target = split.Skip(1).ToArray();
                    }

                    //weaver.Ldloc(argsvar);
                    //weaver.Add(ILWeaver.Ldc_I4_n(i));
                    if (string.IsNullOrEmpty(arg))
                    {
                        weaver.Add(Instruction.Create(OpCodes.Ldnull));
                    }
                    else if (arg == "this")
                    {
                        if (method.IsStatic)
                        {
                            weaver.Add(Instruction.Create(OpCodes.Ldnull));
                        }
                        else
                        {
                            weaver.Add(ILWeaver.Ldarg(null));
                        }

                        GetFieldOrProperty(weaver, method, method.DeclaringType.Resolve(), target, patcher);
                    }
                    else if (arg[0] == 'p' || arg[0] == 'a')
                    {
                        if (int.TryParse(arg.Substring(1), out int index))
                        {
                            ParameterDefinition pdef;

                            /*if (method.IsStatic)
                             *  pdef = method.Parameters[index];
                             * else
                             *  pdef = method.Parameters[index + 1];*/
                            if (index < method.Parameters.Count)
                            {
                                pdef = method.Parameters[index];

                                weaver.Add(ILWeaver.Ldarg(pdef));
                                if (pdef.ParameterType.IsByReference)
                                {
                                    weaver.Add(Instruction.Create(OpCodes.Ldobj, pdef.ParameterType));
                                    weaver.Add(Instruction.Create(OpCodes.Box, pdef.ParameterType));
                                }

                                if (!GetFieldOrProperty(weaver, method, pdef.ParameterType.Resolve(), target, patcher) && pdef.ParameterType.IsValueType)
                                {
                                    weaver.Add(Instruction.Create(OpCodes.Box, pdef.ParameterType));
                                }
                            }
                            else
                            {
                                ShowMsg($"Invalid argument `{arg}` supplied for {HookName}", "Invalid argument supplied", patcher);
                            }
                        }
                        else
                        {
                            weaver.Add(Instruction.Create(OpCodes.Ldnull));
                        }
                    }
                    else if (arg[0] == 'l' || arg[0] == 'v')
                    {
                        if (int.TryParse(arg.Substring(1), out int index))
                        {
                            if (index < method.Body.Variables.Count)
                            {
                                VariableDefinition vdef = weaver.Variables[index];

                                weaver.Ldloc(vdef);
                                if (vdef.VariableType.IsByReference)
                                {
                                    weaver.Add(Instruction.Create(OpCodes.Ldobj, vdef.VariableType));
                                    weaver.Add(Instruction.Create(OpCodes.Box, vdef.VariableType));
                                }

                                if (!GetFieldOrProperty(weaver, method, vdef.VariableType.Resolve(), target, patcher) && vdef.VariableType.IsValueType)
                                {
                                    weaver.Add(Instruction.Create(OpCodes.Box, vdef.VariableType));
                                }
                            }
                            else
                            {
                                ShowMsg($"Invalid variable `{arg}` supplied for {HookName}", "Invalid variable supplied", patcher);
                            }
                        }
                        else
                        {
                            weaver.Add(Instruction.Create(OpCodes.Ldnull));
                        }
                    }
                    else
                    {
                        weaver.Add(Instruction.Create(OpCodes.Ldnull));
                    }

                    //weaver.Add(Instruction.Create(OpCodes.Stelem_Ref));
                }
            }
            else
            {
                // Figure out what we're doing
                bool includeargs = ArgumentBehavior == ArgumentBehavior.All || ArgumentBehavior == ArgumentBehavior.JustParams;
                bool includethis = ArgumentBehavior == ArgumentBehavior.All || ArgumentBehavior == ArgumentBehavior.JustThis;
                if (method.IsStatic)
                {
                    includethis = false;
                }

                // Work out what arguments we're going to transmit
                List <ParameterDefinition> args = new List <ParameterDefinition>();
                if (includeargs)
                {
                    for (int i = 0; i < method.Parameters.Count; i++)
                    {
                        ParameterDefinition arg = method.Parameters[i];
                        if (!arg.IsOut)
                        {
                            args.Add(arg);
                        }
                    }
                }

                //argsvar = weaver.AddVariable(new ArrayType(method.Module.TypeSystem.Object), "args");

                // Load arg count, create array, store

                /*if (includethis)
                 *  firstInstruction = weaver.Add(ILWeaver.Ldc_I4_n(args.Count + 1));
                 * else
                 *  firstInstruction = weaver.Add(ILWeaver.Ldc_I4_n(args.Count));*/
                //weaver.Add(Instruction.Create(OpCodes.Newarr, method.Module.TypeSystem.Object));
                //weaver.Stloc(argsvar);

                // Include this
                if (includethis)
                {
                    //weaver.Ldloc(argsvar);
                    //weaver.Add(ILWeaver.Ldc_I4_n(0));
                    argCount++;
                    weaver.Add(ILWeaver.Ldarg(null));
                    //weaver.Add(Instruction.Create(OpCodes.Stelem_Ref));
                }

                // Loop each argument
                for (int i = 0; i < args.Count; i++)
                {
                    argCount++;
                    // Load array, load index load arg, store in array
                    ParameterDefinition arg = args[i];
                    //weaver.Ldloc(argsvar);

                    /*if (includethis)
                     *  weaver.Add(ILWeaver.Ldc_I4_n(i + 1));
                     * else
                     *  weaver.Add(ILWeaver.Ldc_I4_n(i));*/
                    weaver.Add(ILWeaver.Ldarg(args[i]));
                    if (arg.ParameterType.IsByReference)
                    {
                        weaver.Add(Instruction.Create(OpCodes.Ldobj, arg.ParameterType));
                        weaver.Add(Instruction.Create(OpCodes.Box, arg.ParameterType));
                    }
                    else if (arg.ParameterType.IsValueType)
                    {
                        weaver.Add(Instruction.Create(OpCodes.Box, arg.ParameterType));
                    }
                    //weaver.Add(Instruction.Create(OpCodes.Stelem_Ref));
                }
            }
            return(firstInstruction);
        }
コード例 #11
0
ファイル: Hook.cs プロジェクト: derekbking/uMod.Patcher
 /// <summary>
 /// Patches this hook into the target weaver
 /// </summary>
 /// <param name="original"></param>
 /// <param name="weaver"></param>
 /// <param name="oxidemodule"></param>
 /// <param name="patcher"></param>
 public abstract bool ApplyPatch(MethodDefinition original, ILWeaver weaver, AssemblyDefinition oxidemodule, Patching.Patcher patcher = null);
コード例 #12
0
ファイル: Hook.cs プロジェクト: derekbking/uMod.Patcher
 /// <summary>
 /// PrePatches this hook into the target weaver
 /// </summary>
 /// <param name="weaver"></param>
 /// <param name="oxidemodule"></param>
 /// <param name="original"></param>
 /// <param name="patcher"></param>
 public bool PreparePatch(MethodDefinition original, ILWeaver weaver, AssemblyDefinition oxidemodule, Patching.Patcher patcher = null)
 {
     if (BaseHook != null)
     {
         return(BaseHook.PreparePatch(original, weaver, oxidemodule, patcher) && BaseHook.ApplyPatch(original, weaver, oxidemodule, patcher));
     }
     return(true);
 }