Example #1
0
        private void PatchTyped(ModuleDef module, MethodDef method, int id)
        {
            var body = new CilBody();

            method.Body = body;
            id          = 45 * id;
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 10));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 5));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldtoken, method.DeclaringType));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 20));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 15));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, method.Parameters.Count));
            body.Instructions.Add(Instruction.Create(OpCodes.Newarr, new PtrSig(method.Module.CorLibTypes.Void).ToTypeDefOrRef()));

            foreach (Parameter param in method.Parameters)
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Dup));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, param.Index));
                if (!param.Type.IsByRef)
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Ldarga, param));
                    body.Instructions.Add(Instruction.Create(OpCodes.Mkrefany, param.Type.ToTypeDefOrRef()));
                }
                else
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, param));
                    body.Instructions.Add(Instruction.Create(OpCodes.Mkrefany, param.Type.Next.ToTypeDefOrRef()));
                }
                var local = new Local(method.Module.CorLibTypes.TypedReference);
                body.Variables.Add(local);
                body.Instructions.Add(Instruction.Create(OpCodes.Stloc, local));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldloca, local));
                body.Instructions.Add(Instruction.Create(OpCodes.Conv_I));
                body.Instructions.Add(Instruction.Create(OpCodes.Stelem_I));
            }

            if (method.ReturnType.GetElementType() != ElementType.Void)
            {
                var retVar = new Local(method.ReturnType);
                var retRef = new Local(method.Module.CorLibTypes.TypedReference);
                body.Variables.Add(retVar);
                body.Variables.Add(retRef);
                body.Instructions.Add(Instruction.Create(OpCodes.Ldloca, retVar));
                body.Instructions.Add(Instruction.Create(OpCodes.Mkrefany, method.ReturnType.ToTypeDefOrRef()));
                body.Instructions.Add(Instruction.Create(OpCodes.Stloc, retRef));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldloca, retRef));
                body.Instructions.Add(Instruction.Create(OpCodes.Call, method.Module.Import(this.vmEntryTyped)));

                body.Instructions.Add(Instruction.Create(OpCodes.Ldloc, retVar));
            }
            else
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Ldnull));
                body.Instructions.Add(Instruction.Create(OpCodes.Call, method.Module.Import(this.vmEntryTyped)));
            }
            body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            body.OptimizeMacros();
        }
Example #2
0
        private void PatchNormal(ModuleDef module, MethodDef method, int id)
        {
            var body = new CilBody();

            method.Body = body;
            id          = 63493 * id;
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 10));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 5));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldtoken, method.DeclaringType));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 20));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id * 15));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, method.Parameters.Count));
            body.Instructions.Add(Instruction.Create(OpCodes.Newarr, method.Module.CorLibTypes.Object.ToTypeDefOrRef()));

            foreach (Parameter param in method.Parameters)
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Dup));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, param.Index));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, param));
                if (!param.Type.IsValueType)
                {
                    if (param.Type.IsPointer)
                    {
                        body.Instructions.Add(Instruction.Create(OpCodes.Conv_U));
                        body.Instructions.Add(Instruction.Create(OpCodes.Box, method.Module.CorLibTypes.UIntPtr.ToTypeDefOrRef()));
                    }
                }
                else
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Box, param.Type.ToTypeDefOrRef()));
                }
                body.Instructions.Add(Instruction.Create(OpCodes.Stelem_Ref));
            }
            body.Instructions.Add(Instruction.Create(OpCodes.Call, method.Module.Import(this.vmEntryNormal)));
            if (method.ReturnType.ElementType != ElementType.Void)
            {
                if (!method.ReturnType.IsValueType)
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Castclass, method.ReturnType.ToTypeDefOrRef()));
                }
                else
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Unbox_Any, method.ReturnType.ToTypeDefOrRef()));
                }
            }
            else
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Pop));
            }
            body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            body.OptimizeMacros();
        }
        public static Action <MethodDef> ApplyInject(this MethodBase inject, PatchConfiguration patch) => stub =>
        {
            CilBody            stubBody       = stub.Body;
            MethodBody         injectBody     = inject.GetMethodBody();
            List <Instruction> originalIL     = new List <Instruction>(stubBody.Instructions);
            List <Local>       originalLocals = new List <Local>(stubBody.Variables);
            stubBody.Variables.Clear();
            foreach (LocalVariableInfo local in injectBody.LocalVariables.OrderBy(lvi => lvi.LocalIndex))
            {
                stubBody.Variables.Add(stub.Module.ToDNLib(local));
            }
            List <Instruction> mixinIL = new CilParser(inject.Module, stubBody.Variables, injectBody.GetILAsByteArray()).Parse();
            mixinIL.SimplifyMacros(stubBody.Variables, stub.Parameters);
            IList <Instruction> newIL = stubBody.Instructions;
            newIL.Clear();
            foreach (Instruction inst in mixinIL)
            {
                switch (inst.Operand)
                {
                case FieldInfo field:
                    inst.Operand = patch.ResolveOrImport(stub.Module, field);
                    break;

                case MethodBase method:
                    if (method.IsDefined(typeof(BaseDependencyAttribute)))
                    {
                        throw new InvalidOperationException("attempt to inject a body with a base dependency call");
                    }
                    inst.Operand = patch.ResolveOrImport(stub.Module, method);
                    break;

                case Type type:
                    inst.Operand = patch.ResolveOrImport(stub.Module, type);
                    break;

                case byte[] blob:
                    throw new NotImplementedException("how do you import this?");

                case MemberInfo member:
                    throw new NotImplementedException("how do you import this?");
                }
                newIL.Add(inst);
            }
            stubBody.ExceptionHandlers.Clear();
            foreach (ExceptionHandlingClause ehc in injectBody.ExceptionHandlingClauses)
            {
                stubBody.ExceptionHandlers.Add(ehc.ToDNLib(stub.Module, newIL));
            }
            stubBody.OptimizeMacros();
        };
Example #4
0
        void PatchNormal(ModuleDef module, MethodDef method, int id)
        {
            var body = new CilBody();

            method.Body = body;

            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, id));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, "cracked.to/AndyLarkin | AndyLarkin#3553"));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldtoken, method.DeclaringType));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldstr, gx(id)));
            body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, method.Parameters.Count));
            body.Instructions.Add(Instruction.Create(OpCodes.Newarr, method.Module.CorLibTypes.Object.ToTypeDefOrRef()));

            foreach (var param in method.Parameters)
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Dup));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4, param.Index));
                body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, param));
                if (param.Type.IsValueType)
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Box, param.Type.ToTypeDefOrRef()));
                }
                else if (param.Type.IsPointer)
                {
                    body.Instructions.Add(Instruction.Create(OpCodes.Conv_U));
                    body.Instructions.Add(Instruction.Create(OpCodes.Box, method.Module.CorLibTypes.UIntPtr.ToTypeDefOrRef()));
                }
                body.Instructions.Add(Instruction.Create(OpCodes.Stelem_Ref));
            }
            body.Instructions.Add(Instruction.Create(OpCodes.Call, method.Module.Import(vmEntryNormal)));
            if (method.ReturnType.ElementType == ElementType.Void)
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Pop));
            }
            else if (method.ReturnType.IsValueType)
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Unbox_Any, method.ReturnType.ToTypeDefOrRef()));
            }
            else
            {
                body.Instructions.Add(Instruction.Create(OpCodes.Castclass, method.ReturnType.ToTypeDefOrRef()));
            }
            body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            body.OptimizeMacros();
        }
        public static Action <MethodDef> ApplyMixin(this MethodBase mixin, PatchConfiguration patch) => original =>
        {
            CilBody            originalBody   = original.Body;
            MethodBody         mixinBody      = mixin.GetMethodBody();
            List <Instruction> originalIL     = new List <Instruction>(originalBody.Instructions);
            List <Local>       originalLocals = new List <Local>(originalBody.Variables);
            originalBody.Variables.Clear();
            foreach (LocalVariableInfo local in mixinBody.LocalVariables.OrderBy(lvi => lvi.LocalIndex))
            {
                originalBody.Variables.Add(original.Module.ToDNLib(local));
            }
            List <Instruction> mixinIL = new CilParser(mixin.Module, originalBody.Variables, mixinBody.GetILAsByteArray()).Parse();
            mixinIL.SimplifyMacros(originalBody.Variables, original.Parameters);
            IList <Instruction> newIL = originalBody.Instructions;
            newIL.Clear();
            int ilStart = 0;
            if (mixin.IsConstructor)
            {
                foreach (Instruction inst in mixin.IsDefined(typeof(RewriteBaseAttribute)) ? mixinIL : originalIL)
                {
                    ilStart++;
                    newIL.Add(inst);
                    if (inst.OpCode.FlowControl == FlowControl.Call)
                    {
                        break;
                    }
                }
                RemoveCall(originalIL);
                RemoveCall(mixinIL);
            }
            MethodDef baseCopy = new MethodDefUser(original.DeclaringType.FindUnusedMethodName(original.Name + "<Base>$"), original.MethodSig, original.ImplAttributes, original.Attributes & CopyMask | CopyAttr);
            bool      useBase  = false;
            foreach (Instruction inst in mixinIL)
            {
                switch (inst.Operand)
                {
                case FieldInfo field:
                    inst.Operand = patch.ResolveOrImport(original.Module, field);
                    break;

                case MethodBase method:
                    if (method.IsDefined(typeof(BaseDependencyAttribute)))
                    {
                        useBase      = true;
                        inst.Operand = baseCopy;
                        break;
                    }
                    inst.Operand = patch.ResolveOrImport(original.Module, method);
                    break;

                case Type type:
                    inst.Operand = patch.ResolveOrImport(original.Module, type);
                    break;

                case byte[] blob:
                    throw new NotImplementedException("how do you import this?");

                case MemberInfo member:
                    throw new NotImplementedException("how do you import this?");
                }
                newIL.Add(inst);
            }
            if (useBase)
            {
                baseCopy.Body = new CilBody(originalBody.InitLocals, originalIL, new List <ExceptionHandler>(originalBody.ExceptionHandlers), originalBody.Variables);
                original.DeclaringType.Methods.Add(baseCopy);
            }
            originalBody.ExceptionHandlers.Clear();
            foreach (ExceptionHandlingClause ehc in mixinBody.ExceptionHandlingClauses)
            {
                originalBody.ExceptionHandlers.Add(ehc.ToDNLib(original.Module, newIL));
            }
            originalBody.OptimizeMacros();

            void RemoveCall(List <Instruction> il)
            {
                for (int index = 0; index < il.Count; index++)
                {
                    if (il[index].OpCode.FlowControl != FlowControl.Call)
                    {
                        continue;
                    }
                    il.RemoveRange(0, index + 1);
                    break;
                }
            }
        };