예제 #1
0
 void AnalysisCodes(MethodDefinition mtd)
 {
     for (int i = 0; i < mtd.Body.Instructions.Count; i++)
     {
         Instruction inst = mtd.Body.Instructions[i];
         if (inst.Operand is MethodReference ||
             inst.Operand is FieldReference)
         {
             if ((inst.Operand as MemberReference).DeclaringType is TypeSpecification && ((inst.Operand as MemberReference).DeclaringType as TypeSpecification).GetElementType() is TypeDefinition)
             {
                 IMemberDefinition memDef;
                 if (inst.Operand is MethodReference && (memDef = (inst.Operand as MethodReference).GetElementMethod().Resolve()) != null)
                 {
                     ((memDef as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new SpecificationReference(inst.Operand as MemberReference));
                 }
                 else if (inst.Operand is FieldReference && (memDef = (inst.Operand as FieldReference).Resolve()) != null)
                 {
                     ((memDef as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new SpecificationReference(inst.Operand as MemberReference));
                 }
             }
             else if (inst.Operand is MethodReference)
             {
                 MethodReference refer = inst.Operand as MethodReference;
                 string          id    = refer.DeclaringType.FullName + "::" + refer.Name;
                 if (Database.Reflections.ContainsKey(id))
                 {
                     ReflectionMethod Rmtd = Database.Reflections[id];
                     Instruction      memInst;
                     MemberReference  mem = StackTrace(i, mtd.Body.Instructions, Rmtd, mtd.Module, out memInst);
                     if (mem != null)
                     {
                         ((mem as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new ReflectionReference(memInst));
                     }
                 }
             }
             if (ivtRefs.ContainsKey((inst.Operand as MemberReference).MetadataToken))
             {
                 IMemberDefinition memDef;
                 if (inst.Operand is TypeReference && (memDef = (inst.Operand as TypeReference).Resolve()) != null)
                 {
                     ((memDef as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new IvtMemberReference(inst.Operand as MemberReference));
                 }
                 else if (inst.Operand is MethodReference && (memDef = (inst.Operand as MethodReference).Resolve()) != null)
                 {
                     ((memDef as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new IvtMemberReference(inst.Operand as MemberReference));
                 }
                 else if (inst.Operand is FieldReference && (memDef = (inst.Operand as FieldReference).Resolve()) != null)
                 {
                     ((memDef as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new IvtMemberReference(inst.Operand as MemberReference));
                 }
             }
         }
     }
 }
예제 #2
0
        static Database()
        {
            Reflections = new Dictionary <string, ReflectionMethod>();
            string type = null;

            using (StringReader rdr = new StringReader(db))
            {
                while (true)
                {
                    string line = rdr.ReadLine();
                    if (line == "=")
                    {
                        break;
                    }
                    if (type != null)
                    {
                        if (line == "")
                        {
                            type = null; continue;
                        }
                        ReflectionMethod mtd = new ReflectionMethod();
                        mtd.typeName = type;
                        mtd.mtdName  = line.Substring(0, line.IndexOf('['));
                        string   param = line.Substring(line.IndexOf('[') + 1, line.IndexOf(']') - line.IndexOf('[') - 1);
                        string[] pars  = param.Split(',');
                        mtd.paramLoc  = new int[pars.Length];
                        mtd.paramType = new string[pars.Length];
                        for (int i = 0; i < pars.Length; i++)
                        {
                            mtd.paramLoc[i]  = int.Parse(pars[i].Split(':')[0]);
                            mtd.paramType[i] = pars[i].Split(':')[1];
                        }
                        Reflections.Add(mtd.typeName + "::" + mtd.mtdName, mtd);
                    }
                    else
                    {
                        type = line;
                    }
                }
            }
        }
예제 #3
0
        MemberReference StackTrace(int idx, Collection <Instruction> insts, ReflectionMethod mtd, ModuleDefinition scope, out Instruction memInst)
        {
            memInst = null;
            int count = ((insts[idx].Operand as MethodReference).HasThis ? 1 : 0) + (insts[idx].Operand as MethodReference).Parameters.Count;

            if (insts[idx].OpCode.Code == Code.Newobj)
            {
                count--;
            }
            int c = 0;

            for (idx--; idx >= 0; idx--)
            {
                if (count == c)
                {
                    break;
                }
                Instruction inst = insts[idx];
                switch (inst.OpCode.Code)
                {
                case Code.Ldc_I4:
                case Code.Ldc_I8:
                case Code.Ldc_R4:
                case Code.Ldc_R8:
                case Code.Ldstr:
                    c++; break;

                case Code.Call:
                case Code.Callvirt:
                {
                    MethodReference target = (inst.Operand as MethodReference);
                    c -= (target.HasThis ? 1 : 0) + target.Parameters.Count;
                    if (target.ReturnType.FullName != "System.Void")
                    {
                        c++;
                    }
                    break;
                }

                case Code.Newobj:
                {
                    MethodReference target = (inst.Operand as MethodReference);
                    c -= target.Parameters.Count - 1;
                    break;
                }

                case Code.Pop:
                    c--; break;

                case Code.Ldarg:
                    c++; break;

                case Code.Ldfld:
                    c++; break;

                case Code.Ldloc:
                    c++; break;

                case Code.Ldnull:
                    c++; break;

                case Code.Starg:
                case Code.Stfld:
                case Code.Stloc:
                    c--; break;

                case Code.Ldtoken:
                    c++; break;

                default:
                    FollowStack(inst.OpCode, ref c); break;
                }
            }

            return(StackTrace2(idx + 1, count, insts, mtd, scope, out memInst));
        }
예제 #4
0
        MemberReference StackTrace2(int idx, int c, Collection <Instruction> insts, ReflectionMethod mtd, ModuleDefinition scope, out Instruction memInst)
        {
            memInst = null;
            int            count = c;
            Stack <object> stack = new Stack <object>();

            for (int i = idx; ; i++)
            {
                if (stack.Count == count)
                {
                    break;
                }
                Instruction inst = insts[i];
                switch (inst.OpCode.Code)
                {
                case Code.Ldc_I4:
                case Code.Ldc_I8:
                case Code.Ldc_R4:
                case Code.Ldc_R8:
                case Code.Ldstr:
                    stack.Push(inst.Operand); break;

                case Code.Call:
                case Code.Callvirt:
                {
                    MethodReference target = (inst.Operand as MethodReference);
                    int             cc     = -(target.HasThis ? 1 : 0) - target.Parameters.Count;
                    for (int ii = cc; ii != 0; ii++)
                    {
                        stack.Pop();
                    }
                    if (target.ReturnType.FullName != "System.Void")
                    {
                        stack.Push(target.ReturnType);
                    }
                    break;
                }

                case Code.Newobj:
                {
                    MethodReference target = (inst.Operand as MethodReference);
                    for (int ii = -target.Parameters.Count; ii != 0; ii++)
                    {
                        stack.Pop();
                    }
                    stack.Push(target.DeclaringType);
                    break;
                }

                case Code.Pop:
                    stack.Pop(); break;

                case Code.Ldarg:
                    stack.Push((inst.Operand as ParameterReference).ParameterType); break;

                case Code.Ldfld:
                    stack.Push((inst.Operand as FieldReference).FieldType); break;

                case Code.Ldloc:
                    stack.Push((inst.Operand as VariableReference).VariableType); break;

                case Code.Ldnull:
                    stack.Push(null); break;

                case Code.Starg:
                case Code.Stfld:
                case Code.Stloc:
                    stack.Pop(); break;

                case Code.Ldtoken:
                    stack.Push(inst.Operand); break;

                default:
                    FollowStack(inst.OpCode, stack); break;
                }
            }

            object[] objs = stack.ToArray();
            Array.Reverse(objs);

            string         mem  = null;
            TypeDefinition type = null;
            int            typeIdx;
            Resource       res = null;

            for (int i = 0; i < mtd.paramLoc.Length; i++)
            {
                if (mtd.paramLoc[i] >= objs.Length)
                {
                    return(null);
                }
                object param = objs[mtd.paramLoc[i]];
                switch (mtd.paramType[i])
                {
                case "Target":
                    if ((mem = param as string) == null)
                    {
                        return(null);
                    }
                    memInst = StackTrace3(idx, c, insts, mtd.paramLoc[i]);
                    break;

                case "Type":
                case "This":
                    if (param as TypeDefinition != null)
                    {
                        type    = param as TypeDefinition;
                        typeIdx = mtd.paramLoc[i];
                    }
                    break;

                case "TargetType":
                    if (!(param is string))
                    {
                        return(null);
                    }
                    type    = scope.GetType(param as string);
                    typeIdx = mtd.paramLoc[i];
                    break;

                case "TargetResource":
                    if (!(param is string))
                    {
                        return(null);
                    }
                    res     = scope.Resources.FirstOrDefault((r) => (r.Name == param as string + ".resources"));
                    memInst = StackTrace3(idx, c, insts, mtd.paramLoc[i]);
                    break;
                }
            }
            if (mem == null && type == null && res == null)
            {
                return(null);
            }

            if (res != null)
            {
                ((res as IAnnotationProvider).Annotations["RenRef"] as List <IReference>).Add(new ResourceNameReference(memInst));
                return(null);
            }

            if (mem != null && type != null)
            {
                foreach (FieldDefinition fld in type.Fields)
                {
                    if (fld.Name == mem)
                    {
                        return(fld);
                    }
                }
                foreach (MethodDefinition mtd1 in type.Methods)
                {
                    if (mtd1.Name == mem)
                    {
                        return(mtd1);
                    }
                }
                foreach (PropertyDefinition prop in type.Properties)
                {
                    if (prop.Name == mem)
                    {
                        return(prop);
                    }
                }
                foreach (EventDefinition evt in type.Events)
                {
                    if (evt.Name == mem)
                    {
                        return(evt);
                    }
                }
            }
            else if (type != null)
            {
                memInst = StackTrace3(idx, c, insts, mtd.paramLoc[Array.IndexOf(mtd.paramType, "TargetType")]);
                return(type);
            }
            return(null);
        }