Exemple #1
0
        object Run(ulong codeAddr, uint key, VMFuncSig sig, object[] arguments)
        {
            if (currentCtx != null)
            {
                ctxStack.Push(currentCtx);
            }
            currentCtx = new VMContext(this);

            try {
                Debug.Assert(sig.ParamTypes.Length == arguments.Length);
                currentCtx.Stack.SetTopPosition((uint)arguments.Length + 1);
                for (uint i = 0; i < arguments.Length; i++)
                {
                    currentCtx.Stack[i + 1] = VMSlot.FromObject(arguments[i], sig.ParamTypes[i]);
                }
                currentCtx.Stack[(uint)arguments.Length + 1] = new VMSlot {
                    U8 = 1
                };

                currentCtx.Registers[Constants.REG_K1] = new VMSlot {
                    U4 = key
                };
                currentCtx.Registers[Constants.REG_BP] = new VMSlot {
                    U4 = 0
                };
                currentCtx.Registers[Constants.REG_SP] = new VMSlot {
                    U4 = (uint)arguments.Length + 1
                };
                currentCtx.Registers[Constants.REG_IP] = new VMSlot {
                    U8 = codeAddr
                };
                VMDispatcher.Run(currentCtx);
                Debug.Assert(currentCtx.EHStack.Count == 0);

                object retVal = null;
                if (sig.RetType != typeof(void))
                {
                    var retSlot = currentCtx.Registers[Constants.REG_R0];
                    if (Type.GetTypeCode(sig.RetType) == TypeCode.String && retSlot.O == null)
                    {
                        retVal = Data.LookupString(retSlot.U4);
                    }
                    else
                    {
                        retVal = retSlot.ToObject(sig.RetType);
                    }
                }

                return(retVal);
            }
            finally {
                currentCtx.Stack.FreeAllLocalloc();

                if (ctxStack.Count > 0)
                {
                    currentCtx = ctxStack.Pop();
                }
            }
        }
 static bool ShouldBeTyped(VMFuncSig sig)
 {
     foreach (var param in sig.ParamTypes)
     {
         if (param.IsByRef)
         {
             return(true);
         }
     }
     return(sig.RetType.IsByRef);
 }
Exemple #3
0
        private void Run(ulong codeAddr, uint key, VMFuncSig sig, void *[] arguments, void *retTypedRef)
        {
            if (currentCtx != null)
            {
                ctxStack.Push(currentCtx);
            }
            currentCtx = new VMContext(this);

            try
            {
                Debug.Assert(sig.ParamTypes.Length == arguments.Length);
                currentCtx.Stack.SetTopPosition((uint)arguments.Length + 1);
                for (uint i = 0; i < arguments.Length; i++)
                {
                    var paramType = sig.ParamTypes[i];
                    if (paramType.IsByRef)
                    {
                        currentCtx.Stack[i + 1] = new VMSlot {
                            O = new TypedRef(arguments[i])
                        };
                    }
                    else
                    {
                        var typedRef = *(TypedReference *)arguments[i];
                        currentCtx.Stack[i + 1] = VMSlot.FromObject(TypedReference.ToObject(typedRef), __reftype(typedRef));
                    }
                }
                currentCtx.Stack[(uint)arguments.Length + 1] = new VMSlot {
                    U8 = 1
                };

                currentCtx.Registers[Constants.REG_K1] = new VMSlot {
                    U4 = key
                };
                currentCtx.Registers[Constants.REG_BP] = new VMSlot {
                    U4 = 0
                };
                currentCtx.Registers[Constants.REG_SP] = new VMSlot {
                    U4 = (uint)arguments.Length + 1
                };
                currentCtx.Registers[Constants.REG_IP] = new VMSlot {
                    U8 = codeAddr
                };
                VMDispatcher.Run(currentCtx);
                Debug.Assert(currentCtx.EHStack.Count == 0);

                if (sig.RetType != typeof(void))
                {
                    if (sig.RetType.IsByRef)
                    {
                        var retRef = currentCtx.Registers[Constants.REG_R0].O;
                        if (!(retRef is IReference))
                        {
                            throw new ExecutionEngineException();
                        }
                        ((IReference)retRef).ToTypedReference(currentCtx, retTypedRef, sig.RetType.GetElementType());
                    }
                    else
                    {
                        var    retSlot = currentCtx.Registers[Constants.REG_R0];
                        object retVal;
                        if (Type.GetTypeCode(sig.RetType) == TypeCode.String && retSlot.O == null)
                        {
                            retVal = Data.LookupString(retSlot.U4);
                        }
                        else
                        {
                            retVal = retSlot.ToObject(sig.RetType);
                        }
                        TypedReferenceHelpers.SetTypedRef(retVal, retTypedRef);
                    }
                }
            }
            finally
            {
                currentCtx.Stack.FreeAllLocalloc();

                if (ctxStack.Count > 0)
                {
                    currentCtx = ctxStack.Pop();
                }
            }
        }
        static DynamicMethod CreateTrampolineNormal(int moduleId, ulong codeAdr, uint key, VMFuncSig sig, uint sigId)
        {
            var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true);

            var gen = dm.GetILGenerator();

            //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)));
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldstr, "cracked.to/AndyLarkin | AndyLarkin#3553");
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)codeAdr);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)key);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)sigId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length);
            gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(object));
            for (int i = 0; i < sig.ParamTypes.Length; i++)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Dup);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i);
                if (sig.ParamTypes[i].IsValueType)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Box, sig.ParamTypes[i]);
                }
                gen.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref);
            }

            gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubNormal);

            if (sig.RetType == typeof(void))
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Pop);
            }
            else if (sig.RetType.IsValueType)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, sig.RetType);
            }
            else
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Castclass, sig.RetType);
            }

            gen.Emit(System.Reflection.Emit.OpCodes.Ret);

            return(dm);
        }
        public static IntPtr CreateTrampoline(Module module, ulong codeAdr, uint key, VMFuncSig sig, uint sigId)
        {
            object dm = trampolines[codeAdr];

            if (dm != null)
            {
                return(getDesc((DynamicMethod)dm).GetFunctionPointer());
            }

            lock (trampolines) {
                dm = (DynamicMethod)trampolines[codeAdr];
                if (dm != null)
                {
                    return(getDesc((DynamicMethod)dm).GetFunctionPointer());
                }

                if (ShouldBeTyped(sig))
                {
                    dm = CreateTrampolineTyped(VMInstance.GetModuleId(module), codeAdr, key, sig, sigId);
                }
                else
                {
                    dm = CreateTrampolineNormal(VMInstance.GetModuleId(module), codeAdr, key, sig, sigId);
                }
                trampolines[codeAdr] = dm;
                return(getDesc((DynamicMethod)dm).GetFunctionPointer());
            }
        }
        static DynamicMethod CreateTrampolineTyped(int moduleId, ulong codeAdr, uint key, VMFuncSig sig, uint sigId)
        {
            var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true);

            var gen = dm.GetILGenerator();

            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldstr, "cracked.to/AndyLarkin | AndyLarkin#3553");
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)codeAdr);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)key);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)sigId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length);
            gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(void *));
            for (int i = 0; i < sig.ParamTypes.Length; i++)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Dup);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                if (sig.ParamTypes[i].IsByRef)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i].GetElementType());
                }
                else
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Ldarga, i);
                    gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.ParamTypes[i]);
                }
                var local = gen.DeclareLocal(typeof(TypedReference));
                gen.Emit(System.Reflection.Emit.OpCodes.Stloc, local);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, local);
                gen.Emit(System.Reflection.Emit.OpCodes.Conv_I);
                gen.Emit(System.Reflection.Emit.OpCodes.Stelem_I);
            }

            if (sig.RetType != typeof(void))
            {
                var retVar = gen.DeclareLocal(sig.RetType);
                var retRef = gen.DeclareLocal(typeof(TypedReference));
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retVar);
                gen.Emit(System.Reflection.Emit.OpCodes.Mkrefany, sig.RetType);
                gen.Emit(System.Reflection.Emit.OpCodes.Stloc, retRef);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldloca, retRef);
                gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped);

                gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, retVar);
            }
            else
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Ldnull);
                gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubTyped);
            }
            gen.Emit(System.Reflection.Emit.OpCodes.Ret);

            return(dm);
        }
        private static DynamicMethod CreateTrampolineNormal(int moduleId, ulong codeAdr, uint key, VMFuncSig sig, uint sigId)
        {
            var dm = new DynamicMethod("", sig.RetType, sig.ParamTypes, Unverifier.Module, true);

            var gen = dm.GetILGenerator();

            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, moduleId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)codeAdr);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)key);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)sigId);
            gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, sig.ParamTypes.Length);
            gen.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(object));
            for (var i = 0; i < sig.ParamTypes.Length; i++)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Dup);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, i);
                gen.Emit(System.Reflection.Emit.OpCodes.Ldarg, i);
                if (sig.ParamTypes[i].IsValueType)
                {
                    gen.Emit(System.Reflection.Emit.OpCodes.Box, sig.ParamTypes[i]);
                }
                gen.Emit(System.Reflection.Emit.OpCodes.Stelem_Ref);
            }

            gen.Emit(System.Reflection.Emit.OpCodes.Call, entryStubNormal);

            if (sig.RetType == typeof(void))
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Pop);
            }
            else if (sig.RetType.IsValueType)
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, sig.RetType);
            }
            else
            {
                gen.Emit(System.Reflection.Emit.OpCodes.Castclass, sig.RetType);
            }

            gen.Emit(System.Reflection.Emit.OpCodes.Ret);

            return(dm);
        }