예제 #1
0
        static int getMapId(Type idMapType, MethodBase method)
        {
            IDTagAttribute id         = Attribute.GetCustomAttribute(method, typeof(IDTagAttribute), false) as IDTagAttribute;
            int            overrideId = id == null ? 0 : id.ID;
            var            fieldName  = string.Format("{0}-{1}{2}", method.DeclaringType.FullName.Replace('.', '-')
                                                      .Replace('+', '-'), method.Name, overrideId);
            var field = idMapType.GetField(fieldName);

            if (field == null)
            {
                throw new Exception(string.Format("cat not find id field: {0}, for {1}", fieldName, method));
            }
            return((int)field.GetValue(null));
        }
예제 #2
0
        static FieldInfo getRedirectField(MethodBase method)
        {
            var redirectTypeName = "IFix.RedirectTo." + method.DeclaringType.AssemblyQualifiedName;
            var redirectType     = Type.GetType(redirectTypeName);

            if (redirectType == null)
            {
                throw new Exception("cat not find redirect type: " + redirectTypeName);
            }
            IDTagAttribute id = Attribute.GetCustomAttribute(method, typeof(IDTagAttribute), false) as IDTagAttribute;
            var            redirectFieldName = string.Format("_rf_{0}{1}", method.Name, id == null ? 0 : id.ID);
            var            redirectField     = redirectType.GetField(redirectFieldName, BindingFlags.DeclaredOnly | BindingFlags.Static
                                                                     | BindingFlags.Public);

            if (redirectField == null)
            {
                throw new Exception(string.Format("cat not find redirect field: {0}, for {1}", redirectFieldName,
                                                  redirectType));
            }
            return(redirectField);
        }
예제 #3
0
        static int getMapId(List <Type> idMapArray, MethodBase method)
        {
            IDTagAttribute id         = Attribute.GetCustomAttribute(method, typeof(IDTagAttribute), false) as IDTagAttribute;
            int            overrideId = id == null ? 0 : id.ID;
            var            fieldName  = string.Format("{0}-{1}{2}", method.DeclaringType.FullName.Replace('.', '-')
                                                      .Replace('+', '-'), method.Name, overrideId);
            FieldInfo field = null;

            for (int i = 0; i < idMapArray.Count; i++)
            {
                field = idMapArray[i].GetField(fieldName);
                if (field != null)
                {
                    break;
                }
            }
            if (field == null)
            {
                throw new Exception(string.Format("cat not find id field: {0}, for {1}", fieldName, method));
            }
            return((int)field.GetValue(null));
        }
예제 #4
0
        // #lizard forgives
        unsafe static public VirtualMachine Load(Stream stream, bool checkNew = true)
        {
            List <IntPtr> nativePointers = new List <IntPtr>();

            IntPtr        nativePointer;
            Instruction **unmanagedCodes = null;

            Type[]       externTypes;
            MethodBase[] externMethods;
            List <ExceptionHandler[]> exceptionHandlers = new List <ExceptionHandler[]>();

            string[]              internStrings;
            FieldInfo[]           fieldInfos;
            Type[]                staticFieldTypes;
            int[]                 cctors;
            AnonymousStoreyInfo[] anonymousStoreyInfos;

            using (BinaryReader reader = new BinaryReader(stream))
            {
                var instructionMagic = reader.ReadUInt64();
                if (instructionMagic != Instruction.INSTRUCTION_FORMAT_MAGIC)
                {
                    throw new Exception("instruction magic not match, expect "
                                        + Instruction.INSTRUCTION_FORMAT_MAGIC
                                        + ", but got " + instructionMagic);
                }

                var interfaceBridgeTypeName = reader.ReadString();
                var interfaceBridgeType     = Type.GetType(interfaceBridgeTypeName);
                if (interfaceBridgeType == null)
                {
                    throw new Exception("assembly may be not injected yet, cat find "
                                        + interfaceBridgeTypeName);
                }

                //BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static
                //    | BindingFlags.NonPublic |BindingFlags.Public;
                int externTypeCount = reader.ReadInt32();
                externTypes = new Type[externTypeCount];
                for (int i = 0; i < externTypeCount; i++)
                {
                    var assemblyQualifiedName = reader.ReadString();
                    externTypes[i] = Type.GetType(assemblyQualifiedName);
                    if (externTypes[i] == null)
                    {
                        throw new Exception("can not load type [" + assemblyQualifiedName + "]");
                    }
                }

                int methodCount = reader.ReadInt32();

                nativePointer  = System.Runtime.InteropServices.Marshal.AllocHGlobal(sizeof(Instruction *) * methodCount);
                unmanagedCodes = (Instruction **)nativePointer.ToPointer();
                nativePointers.Add(nativePointer);

                for (int j = 0; j < methodCount; j++)
                {
                    //Console.WriteLine("==================method" + j + "==================");
                    int codeSize = reader.ReadInt32();
                    nativePointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(sizeof(Instruction) * codeSize);
                    var unmanagedCode = (Instruction *)nativePointer.ToPointer();
                    for (int i = 0; i < codeSize; i++)
                    {
                        unmanagedCode[i].Code    = (Code)reader.ReadInt32();
                        unmanagedCode[i].Operand = reader.ReadInt32();
                        //Console.WriteLine(i + " Code=" + unmanagedCode[i].Code + " Operand="
                        //    + unmanagedCode[i].Operand);
                    }
                    unmanagedCodes[j] = unmanagedCode;
                    nativePointers.Add(nativePointer);
                    ExceptionHandler[] ehsOfMethod = new ExceptionHandler[reader.ReadInt32()];
                    for (int i = 0; i < ehsOfMethod.Length; i++)
                    {
                        ExceptionHandler ehOfMethod = new ExceptionHandler();
                        ehOfMethod.HandlerType  = (ExceptionHandlerType)reader.ReadInt32();
                        ehOfMethod.CatchTypeId  = reader.ReadInt32();
                        ehOfMethod.TryStart     = reader.ReadInt32();
                        ehOfMethod.TryEnd       = reader.ReadInt32();
                        ehOfMethod.HandlerStart = reader.ReadInt32();
                        ehOfMethod.HandlerEnd   = reader.ReadInt32();
                        ehsOfMethod[i]          = ehOfMethod;
                        if (ehOfMethod.HandlerType == ExceptionHandlerType.Catch)
                        {
                            ehOfMethod.CatchType = ehOfMethod.CatchTypeId == -1 ?
                                                   typeof(object) : externTypes[ehOfMethod.CatchTypeId];
                        }
                    }
                    exceptionHandlers.Add(ehsOfMethod);
                }

                int externMethodCount = reader.ReadInt32();
                externMethods = new MethodBase[externMethodCount];
                for (int i = 0; i < externMethodCount; i++)
                {
                    externMethods[i] = readMethod(reader, externTypes);
                }

                int internStringsCount = reader.ReadInt32();
                internStrings = new string[internStringsCount];
                for (int i = 0; i < internStringsCount; i++)
                {
                    internStrings[i] = reader.ReadString();
                }

                fieldInfos = new FieldInfo[reader.ReadInt32()];
                for (int i = 0; i < fieldInfos.Length; i++)
                {
                    var type      = externTypes[reader.ReadInt32()];
                    var fieldName = reader.ReadString();
                    fieldInfos[i] = type.GetField(fieldName,
                                                  BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
                    if (fieldInfos[i] == null)
                    {
                        throw new Exception("can not load field [" + fieldName + "] of " + type);
                    }
                }

                staticFieldTypes = new Type[reader.ReadInt32()];
                cctors           = new int[staticFieldTypes.Length];
                for (int i = 0; i < staticFieldTypes.Length; i++)
                {
                    staticFieldTypes[i] = externTypes[reader.ReadInt32()];
                    cctors[i]           = reader.ReadInt32();
                }

                Dictionary <MethodInfo, int> itfMethodToId = new Dictionary <MethodInfo, int>();
                int maxId = 0;

                foreach (var itf in interfaceBridgeType.GetInterfaces())
                {
                    InterfaceMapping map = interfaceBridgeType.GetInterfaceMap(itf);
                    for (int i = 0; i < map.InterfaceMethods.Length; i++)
                    {
                        IDTagAttribute idTag = Attribute.GetCustomAttribute(map.TargetMethods[i],
                                                                            typeof(IDTagAttribute), false) as IDTagAttribute;
                        MethodInfo im = map.InterfaceMethods[i];
                        if (idTag == null)
                        {
                            throw new Exception(string.Format("can not find id for {0}", im));
                        }
                        int id = idTag.ID;
                        //VirtualMachine._Info(string.Format("{0} [{1}]", im, id));
                        maxId = id > maxId ? id : maxId;
                        itfMethodToId.Add(im, id);
                    }
                }

                anonymousStoreyInfos = new AnonymousStoreyInfo[reader.ReadInt32()];
                for (int i = 0; i < anonymousStoreyInfos.Length; i++)
                {
                    int   fieldNum   = reader.ReadInt32();
                    int[] fieldTypes = new int[fieldNum];
                    for (int fieldIdx = 0; fieldIdx < fieldNum; ++fieldIdx)
                    {
                        fieldTypes[fieldIdx] = reader.ReadInt32();
                    }
                    int ctorId       = reader.ReadInt32();
                    int ctorParamNum = reader.ReadInt32();
                    var slots        = readSlotInfo(reader, itfMethodToId, externTypes, maxId);

                    int   virtualMethodNum = reader.ReadInt32();
                    int[] vTable           = new int[virtualMethodNum];
                    for (int vm = 0; vm < virtualMethodNum; vm++)
                    {
                        vTable[vm] = reader.ReadInt32();
                    }
                    anonymousStoreyInfos[i] = new AnonymousStoreyInfo()
                    {
                        CtorId       = ctorId,
                        FieldNum     = fieldNum,
                        FieldTypes   = fieldTypes,
                        CtorParamNum = ctorParamNum,
                        Slots        = slots,
                        VTable       = vTable
                    };
                }


                var virtualMachine = new VirtualMachine(unmanagedCodes, () =>
                {
                    for (int i = 0; i < nativePointers.Count; i++)
                    {
                        System.Runtime.InteropServices.Marshal.FreeHGlobal(nativePointers[i]);
                    }
                })
                {
                    ExternTypes          = externTypes,
                    ExternMethods        = externMethods,
                    ExceptionHandlers    = exceptionHandlers.ToArray(),
                    InternStrings        = internStrings,
                    FieldInfos           = fieldInfos,
                    AnonymousStoreyInfos = anonymousStoreyInfos,
                    StaticFieldTypes     = staticFieldTypes,
                    Cctors = cctors
                };

                var             wrappersManagerImplName = reader.ReadString();
                WrappersManager wrapperManager          = Activator.CreateInstance(Type.GetType(wrappersManagerImplName, true),
                                                                                   virtualMachine) as WrappersManager;
                if (wrapperManager == null)
                {
                    throw new Exception("can not create WrappersManager!");
                }
                virtualMachine.WrappersManager = wrapperManager;

                var assemblyStr = reader.ReadString();
                var idMapList   = new List <Type>();
                for (int i = 0; i < 100; i++)
                {
                    var idMapType = Type.GetType("IFix.IDMAP" + i + assemblyStr, false);
                    if (idMapType == null)
                    {
                        break;
                    }
                    idMapList.Add(idMapType);
                }

                lock (removers)
                {
                    var    assembly = wrapperManager.GetType().Assembly;
                    Action remover;
                    if (removers.TryGetValue(assembly, out remover))
                    {
                        removers.Remove(assembly);
                        remover();
                    }

                    //int fixCount = reader.ReadInt32();
                    //FieldInfo[] toSet = new FieldInfo[fixCount];

                    //for (int i = 0; i < fixCount; i++)
                    //{
                    //    var fixMethod = readMethod(reader, externTypes);
                    //    var fixMethodIdx = reader.ReadInt32();
                    //    var redirectField = getRedirectField(fixMethod);
                    //    toSet[i] = redirectField;
                    //    var wrapper = wrapperManager.CreateWrapper(fixMethodIdx);
                    //    if (wrapper == null)
                    //    {
                    //        throw new Exception("create wrapper fail");
                    //    }
                    //    redirectField.SetValue(null, wrapper);
                    //}

                    //removers[assembly] = () =>
                    //{
                    //    for (int i = 0; i < fixCount; i++)
                    //    {
                    //        toSet[i].SetValue(null, null);
                    //    }
                    //};

                    int   fixCount      = reader.ReadInt32();
                    int[] methodIdArray = new int[fixCount];
                    int[] posArray      = new int[fixCount];
                    int   maxPos        = -1;
                    for (int i = 0; i < fixCount; i++)
                    {
                        var fixMethod   = readMethod(reader, externTypes);
                        var fixMethodId = reader.ReadInt32();
                        var pos         = getMapId(idMapList, fixMethod);
                        methodIdArray[i] = fixMethodId;
                        posArray[i]      = pos;
                        if (pos > maxPos)
                        {
                            maxPos = pos;
                        }
                    }
                    Array arr = wrapperManager.InitWrapperArray(maxPos + 1) as Array;
                    for (int i = 0; i < fixCount; i++)
                    {
                        var wrapper = wrapperManager.CreateWrapper(methodIdArray[i]);
                        if (wrapper == null)
                        {
                            throw new Exception("create wrapper fail");
                        }
                        arr.SetValue(wrapper, posArray[i]);
                    }
                    removers[assembly] = () =>
                    {
                        wrapperManager.InitWrapperArray(0);
                    };
                }

                if (checkNew)
                {
                    int newClassCount = reader.ReadInt32();
                    for (int i = 0; i < newClassCount; i++)
                    {
                        var newClassFullName = reader.ReadString();
                        var newClassName     = Type.GetType(newClassFullName);
                        if (newClassName != null)
                        {
                            throw new Exception(newClassName + " class is expected to be a new class , but it already exists ");
                        }
                    }
                }

                return(virtualMachine);
            }
        }