Example #1
0
        private void JumpToEdge(DirectCallMethod.Node node)
        {
            Instruction instruction = this.AddInstruction(OpCodes.Bne_Un, this.body.Instructions[1]);

            this.jumpToEdgePlaceholderTargets[instruction] = node;
        }
Example #2
0
        public DirectCallMethod(ModuleDefinition module, TypeDefinition type)
        {
            DirectCallMethod.Node         node;
            Func <MethodDefinition, bool> func = null;
            DirectCallMethod directCallMethod  = this;

            this.module        = module;
            this.type          = type;
            this.getLength     = module.Import(typeof(string).GetMethod("get_Length", new Type[0]));
            this.getChars      = module.Import(typeof(string).GetMethod("get_Chars", new Type[] { typeof(int) }));
            this.isNullOrEmpty = module.Import(typeof(string).GetMethod("IsNullOrEmpty", new Type[] { typeof(string) }));
            this.stringEquals  = module.Import(typeof(string).GetMethod("Equals", new Type[] { typeof(string) }));
            AssemblyDefinition assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.Combine(Interface.Oxide.ExtensionDirectory, "Oxide.CSharp.dll"));
            ModuleDefinition   mainModule         = assemblyDefinition.MainModule;
            TypeDefinition     typeDefinition     = module.Import(assemblyDefinition.MainModule.GetType("Oxide.Plugins.CSharpPlugin")).Resolve();
            MethodDefinition   methodDefinition   = module.Import(typeDefinition.Methods.First <MethodDefinition>((MethodDefinition method) => method.Name == "DirectCallHook")).Resolve();

            this.method = new MethodDefinition(methodDefinition.Name, methodDefinition.Attributes, mainModule.Import(methodDefinition.ReturnType))
            {
                DeclaringType = type
            };
            foreach (ParameterDefinition parameter in methodDefinition.Parameters)
            {
                ParameterDefinition parameterDefinition = new ParameterDefinition(parameter.Name, parameter.Attributes, mainModule.Import(parameter.ParameterType))
                {
                    IsOut         = parameter.IsOut,
                    Constant      = parameter.Constant,
                    MarshalInfo   = parameter.MarshalInfo,
                    IsReturnValue = parameter.IsReturnValue
                };
                foreach (CustomAttribute customAttribute in parameter.CustomAttributes)
                {
                    parameterDefinition.CustomAttributes.Add(new CustomAttribute(module.Import(customAttribute.Constructor)));
                }
                this.method.Parameters.Add(parameterDefinition);
            }
            foreach (CustomAttribute customAttribute1 in methodDefinition.CustomAttributes)
            {
                this.method.CustomAttributes.Add(new CustomAttribute(module.Import(customAttribute1.Constructor)));
            }
            this.method.ImplAttributes      = methodDefinition.ImplAttributes;
            this.method.SemanticsAttributes = methodDefinition.SemanticsAttributes;
            MethodDefinition attributes = this.method;

            attributes.Attributes = attributes.Attributes & (MethodAttributes.MemberAccessMask | MethodAttributes.Private | MethodAttributes.FamANDAssem | MethodAttributes.Assembly | MethodAttributes.Family | MethodAttributes.FamORAssem | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Abstract | MethodAttributes.SpecialName | MethodAttributes.PInvokeImpl | MethodAttributes.UnmanagedExport | MethodAttributes.RTSpecialName | MethodAttributes.HasSecurity | MethodAttributes.RequireSecObject);
            MethodDefinition attributes1 = this.method;

            attributes1.Attributes = attributes1.Attributes | MethodAttributes.CompilerControlled;
            this.body = new MethodBody(this.method);
            this.body.SimplifyMacros();
            this.method.Body = this.body;
            type.Methods.Add(this.method);
            this.body.Variables.Add(new VariableDefinition("name_size", module.TypeSystem.Int32));
            this.body.Variables.Add(new VariableDefinition("i", module.TypeSystem.Int32));
            this.AddInstruction(OpCodes.Ldarg_2);
            this.AddInstruction(OpCodes.Ldnull);
            this.AddInstruction(OpCodes.Stind_Ref);
            this.AddInstruction(OpCodes.Ldarg_1);
            this.AddInstruction(OpCodes.Call, this.isNullOrEmpty);
            Instruction instruction = this.AddInstruction(OpCodes.Brfalse, this.body.Instructions[0]);

            this.Return(false);
            instruction.Operand = this.AddInstruction(OpCodes.Ldarg_1);
            this.AddInstruction(OpCodes.Callvirt, this.getLength);
            this.AddInstruction(OpCodes.Stloc_0);
            this.AddInstruction(OpCodes.Ldc_I4_0);
            this.AddInstruction(OpCodes.Stloc_1);
            Collection <MethodDefinition> methods = type.Methods;
            Func <MethodDefinition, bool> func1   = func;

            if (func1 == null)
            {
                Func <MethodDefinition, bool> isStatic = (MethodDefinition m) => {
                    if (m.IsStatic || !m.IsPrivate && !directCallMethod.IsHookMethod(m) || m.HasGenericParameters || m.ReturnType.IsGenericParameter || m.DeclaringType != type || m.IsSetter)
                    {
                        return(false);
                    }
                    return(!m.IsGetter);
                };
                Func <MethodDefinition, bool> func2 = isStatic;
                func  = isStatic;
                func1 = func2;
            }
            foreach (MethodDefinition methodDefinition1 in methods.Where <MethodDefinition>(func1))
            {
                if (methodDefinition1.Name.Contains("<"))
                {
                    continue;
                }
                string name = methodDefinition1.Name;
                if (methodDefinition1.Parameters.Count > 0)
                {
                    name = string.Concat(name, "(", string.Join(", ", (
                                                                    from x in methodDefinition1.Parameters
                                                                    select x.ParameterType.ToString().Replace("/", "+").Replace("<", "[").Replace(">", "]")).ToArray <string>()), ")");
                }
                if (this.hookMethods.ContainsKey(name))
                {
                    continue;
                }
                this.hookMethods[name] = methodDefinition1;
            }
            DirectCallMethod.Node node1 = new DirectCallMethod.Node();
            foreach (string key in this.hookMethods.Keys)
            {
                DirectCallMethod.Node node2 = node1;
                for (int i = 1; i <= key.Length; i++)
                {
                    char chr = key[i - 1];
                    if (!node2.Edges.TryGetValue(chr, out node))
                    {
                        node = new DirectCallMethod.Node()
                        {
                            Parent = node2,
                            Char   = chr
                        };
                        node2.Edges[chr] = node;
                    }
                    if (i == key.Length)
                    {
                        node.Name = key;
                    }
                    node2 = node;
                }
            }
            int num = 1;

            foreach (char key1 in node1.Edges.Keys)
            {
                int num1 = num;
                num = num1 + 1;
                this.BuildNode(node1.Edges[key1], num1);
            }
            this.endInstruction = this.Return(false);
            foreach (Instruction firstInstruction in this.jumpToEdgePlaceholderTargets.Keys)
            {
                firstInstruction.Operand = this.jumpToEdgePlaceholderTargets[firstInstruction].FirstInstruction;
            }
            foreach (Instruction jumpToEndPlaceholder in this.jumpToEndPlaceholders)
            {
                jumpToEndPlaceholder.Operand = this.endInstruction;
            }
            this.body.OptimizeMacros();
        }
Example #3
0
        private void BuildNode(DirectCallMethod.Node node, int edge_number)
        {
            if (edge_number == 1)
            {
                node.FirstInstruction = this.AddInstruction(OpCodes.Ldloc_1);
                this.AddInstruction(OpCodes.Ldloc_0);
                this.jumpToEndPlaceholders.Add(this.AddInstruction(OpCodes.Bge, this.body.Instructions[0]));
            }
            if (edge_number != 1)
            {
                node.FirstInstruction = this.AddInstruction(OpCodes.Ldarg_1);
            }
            else
            {
                this.AddInstruction(OpCodes.Ldarg_1);
            }
            this.AddInstruction(OpCodes.Ldloc_1);
            this.AddInstruction(OpCodes.Callvirt, this.getChars);
            this.AddInstruction(this.Ldc_I4_n(node.Char));
            if (node.Parent.Edges.Count <= edge_number)
            {
                this.JumpToEnd();
            }
            else
            {
                this.JumpToEdge(node.Parent.Edges.Values.ElementAt <DirectCallMethod.Node>(edge_number));
            }
            if (node.Edges.Count == 1 && node.Name == null)
            {
                DirectCallMethod.Node node1 = node;
                while (node1.Edges.Count == 1 && node1.Name == null)
                {
                    node1 = node1.Edges.Values.First <DirectCallMethod.Node>();
                }
                if (node1.Edges.Count == 0 && node1.Name != null)
                {
                    this.AddInstruction(OpCodes.Ldarg_1);
                    this.AddInstruction(Instruction.Create(OpCodes.Ldstr, node1.Name));
                    this.AddInstruction(OpCodes.Callvirt, this.stringEquals);
                    this.jumpToEndPlaceholders.Add(this.AddInstruction(OpCodes.Brfalse, this.body.Instructions[0]));
                    this.CallMethod(this.hookMethods[node1.Name]);
                    this.Return(true);
                    return;
                }
            }
            this.AddInstruction(OpCodes.Ldloc_1);
            this.AddInstruction(OpCodes.Ldc_I4_1);
            this.AddInstruction(OpCodes.Add);
            this.AddInstruction(OpCodes.Stloc_1);
            if (node.Name != null)
            {
                this.AddInstruction(OpCodes.Ldloc_1);
                this.AddInstruction(OpCodes.Ldloc_0);
                if (node.Edges.Count <= 0)
                {
                    this.JumpToEnd();
                }
                else
                {
                    this.JumpToEdge(node.Edges.Values.First <DirectCallMethod.Node>());
                }
                this.CallMethod(this.hookMethods[node.Name]);
                this.Return(true);
            }
            int num = 1;

            foreach (char key in node.Edges.Keys)
            {
                int num1 = num;
                num = num1 + 1;
                this.BuildNode(node.Edges[key], num1);
            }
        }