Example #1
0
 private static void Poll(string file, ReaderParameters rparam,
                          IDependencyReport report, params IInspector[] inspectors)
 {
     using (var ass = ReadAssembly(null, rparam, file))
     {
         if (ass == null || IsStandardLib(ass.Name.Name) || IsGenerated(ass))
         {
             return;
         }
         var founds = new Dictionary <string, int>();
         foreach (var inspector in inspectors)
         {
             var count = inspector.Inspect(ass, report);
             if (count < 1)
             {
                 continue;
             }
             founds[inspector.GetType().Name] = count;
         }
         if (founds.Count < 1)
         {
             return;
         }
         Log.Info($"'{ass.FullName}' {string.Join(" ", founds)}");
         report.Files.Add(Path.GetFullPath(file));
     }
 }
Example #2
0
        private static void ProcessMarkedFiles(string workDir, IDependencyReport report,
                                               IEnumerable <string> injectables, string outDir)
        {
            IRewiring rewriter = new PurgeRewriter();

            using (var resolv = new DefaultAssemblyResolver())
            {
                resolv.AddSearchDirectory(workDir);
                resolv.AddSearchDirectory(outDir);
                var rparam = new ReaderParameters {
                    AssemblyResolver = resolv
                };
                var wparam   = new WriterParameters();
                var injected = injectables.Select(i => AssemblyDefinition.ReadAssembly(i, rparam)).ToArray();
                foreach (var file in report.Files)
                {
                    using (var stream = new MemoryStream(File.ReadAllBytes(file)))
                        using (var ass = AssemblyDefinition.ReadAssembly(stream, rparam))
                        {
                            Log.Info($"... '{ass.FullName}'");
                            if (ass.Modules.Any(m => m.Attributes.HasFlag(ModuleAttributes.StrongNameSigned)))
                            {
                                Log.InfoFormat($" skipping code in '{ToRelativePath(workDir, file)}'!");
                                continue;
                            }
                            rewriter.Rewrite(ass, injected);
                            var outFile = Path.Combine(outDir, Path.GetFileName(file));
                            ass.Write(outFile, wparam);
                            Log.InfoFormat($" inverted code in '{ToRelativePath(workDir, file)}'!");
                        }
                }
                Array.ForEach(injected, i => i.Dispose());
            }
        }
Example #3
0
        public int Inspect(AssemblyDefinition ass, IDependencyReport report)
        {
            var manageds = 0;
            var assTypes = ass.GetAllTypeRefs().ToArray();
            var assMembs = ass.GetAllMemberRefs().ToArray();

            foreach (var assRef in ass.Modules.SelectMany(m => m.AssemblyReferences)
                     .Where(r => Filters.Count < 1 || Filters.Contains(r.Name, Comp)))
            {
                var key = assRef.Name;
                if (IsStandardLib(key))
                {
                    continue;
                }
                ISet <string> list;
                if (!report.ManagedRefs.TryGetValue(key, out list))
                {
                    report.ManagedRefs[key] = list = new SortedSet <string>();
                }
                list.Add(ass.FullName);
                Process(report, assRef, assTypes, assMembs);
                manageds++;
            }
            return(manageds);
        }
Example #4
0
        private void CheckAndInclude(IDependencyReport report, TypeReference type, INamingStrategy strategy)
        {
            if (type?.IsInStandardLib() ?? true)
            {
                return;
            }
            var typeDef = type.Resolve();

            Managed.InspectType(report, type, typeDef, null, strategy);
        }
Example #5
0
        internal static void WriteToFile(IDependencyReport report, string fileName = "report.json")
        {
            var jopts = new JsonSerializerSettings
            {
                Formatting           = Formatting.Indented,
                Converters           = { new StringEnumConverter() },
                NullValueHandling    = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore
            };
            var json = JsonConvert.SerializeObject(report, jopts);

            File.WriteAllText(fileName, json, Encoding.UTF8);
        }
Example #6
0
        internal void InspectType(IDependencyReport report, TypeReference typeRef,
                                  TypeDefinition typeDef, MemberReference[] myMembers, INamingStrategy strategy)
        {
            if (typeDef == null)
            {
                return;
            }
            var   purged     = report.Units;
            var   invRef     = typeDef.Module.Assembly;
            var   invRefName = strategy.GetName(invRef);
            IUnit purge;

            if (!purged.TryGetValue(invRefName, out purge))
            {
                purged[invRefName] = purge = new AssemblyUnit(invRefName, new Version(0, 0, 0, 0));
            }
            var   kind        = typeDef.GetTypeKind();
            var   typeDefName = strategy.GetName(typeDef);
            IType ptype;

            if (!purge.Types.TryGetValue(typeDefName, out ptype))
            {
                purge.Types[typeDefName] = ptype = new AssemblyType(typeDefName, kind);
            }
            var members = myMembers ?? typeDef.GetAllMembers();

            switch (kind)
            {
            case TypeKind.Enum:
                InspectEnum(ptype, typeDef);
                break;

            case TypeKind.Delegate:
                InspectDelegate(ptype, typeDef);
                break;

            case TypeKind.Struct:
            case TypeKind.Interface:
                InspectMembers(ptype, members);
                ExtractGenerics(ptype, typeDef);
                ExtractBases(ptype, typeDef);
                break;

            case TypeKind.Class:
                InspectClass(ptype, typeRef, typeDef, members);
                break;
            }
        }
Example #7
0
        public int Inspect(AssemblyDefinition ass, IDependencyReport report)
        {
            var natives = 0;
            var types   = ass.GetAllTypes().ToArray();

            foreach (var nativeRef in ass.Modules.SelectMany(m => m.ModuleReferences)
                     .Where(r => Filters.Count < 1 || Filters.Contains(r.Name, Comp)))
            {
                var           key = NormalizeNativeRef(nativeRef);
                ISet <string> list;
                if (!report.NativeRefs.TryGetValue(key, out list))
                {
                    report.NativeRefs[key] = list = new SortedSet <string>();
                }
                list.Add(ass.FullName);
                Process(key, types, nativeRef, report);
                natives++;
            }
            return(natives);
        }
Example #8
0
        private void Process(IDependencyReport report, AssemblyNameReference invRef,
                             IEnumerable <TypeReference> assTypes, IEnumerable <MemberReference> assMembs)
        {
            var mbmFlter  = new MemberReference[0];
            var myTypes   = assTypes.Where(t => ContainsType(invRef, t)).ToArray();
            var myMembers = assMembs.Where(m => ContainsMember(invRef, m)).GroupBy(m => m.DeclaringType).ToArray();

            foreach (var myType in myTypes)
            {
                var myTypeDef = myType.Resolve();
                InspectType(report, myType, myTypeDef, mbmFlter, NamingStrategy);
            }
            foreach (var myPair in myMembers)
            {
                var myType    = myPair.Key;
                var myMembs   = myPair.ToArray();
                var myTypeDef = myType.Resolve();
                InspectType(report, myType, myTypeDef, myMembs, NamingStrategy);
            }
        }
Example #9
0
        private void Process(string name, IEnumerable <TypeDefinition> types,
                             IMetadataTokenProvider invRef, IDependencyReport report)
        {
            var             units           = report.Units;
            var             nativeTypeName  = Capitalize(Path.GetFileNameWithoutExtension(name));
            var             collot          = new TypeCollector();
            INamingStrategy nameArgStrategy = null;

            foreach (var meth in types.SelectMany(t => t.Methods))
            {
                PInvokeInfo pinv;
                if (!meth.HasPInvokeInfo || invRef != (pinv = meth.PInvokeInfo).Module)
                {
                    continue;
                }
                var   nativeMethName = pinv.EntryPoint;
                var   retType        = Deobfuscate(meth.ReturnType.ToString());
                var   parms          = Deobfuscate(GetParamStr(meth));
                var   key            = $"{nativeMethName} {retType} {parms}";
                IUnit unit;
                if (!units.TryGetValue(name, out unit))
                {
                    units[name] = unit = new AssemblyUnit(nativeTypeName, new Version("0.0.0.0"));
                }
                IType ptype;
                if (!unit.Types.TryGetValue(nativeTypeName, out ptype))
                {
                    unit.Types[nativeTypeName] = ptype = new AssemblyType(nativeTypeName, TypeKind.Class);
                }
                nameArgStrategy = new NativeArgNameStrategy(ptype);
                collot.Collect(meth);
                var newRetType  = nameArgStrategy.GetName(meth.ReturnType);
                var methRetType = Deobfuscate(meth.ReturnType.FullName);
                if (newRetType != null)
                {
                    methRetType = newRetType;
                }
                IMethod pmethod;
                if (!ptype.Methods.TryGetValue(key, out pmethod))
                {
                    ptype.Methods[key] = pmethod = new AssemblyMethod(nativeMethName, methRetType);
                }
                pmethod.Parameters.Clear();
                foreach (var parm in meth.Parameters)
                {
                    var newParmType = nameArgStrategy.GetName(parm.ParameterType);
                    var mparmType   = Deobfuscate(parm.ParameterType.FullName);
                    if (newParmType != null)
                    {
                        mparmType = newParmType;
                    }
                    var mparm = new MethodParameter(parm.Name, mparmType);
                    pmethod.Parameters.Add(mparm);
                }
                const StringSplitOptions sso = StringSplitOptions.None;
                var text = $"{meth}".Split(new[] { $"{meth.ReturnType}" }, 2, sso).Last().Trim();
                pmethod.Aliases.Add(Deobfuscate(text));
            }
            if (nameArgStrategy == null)
            {
                return;
            }
            foreach (var type in collot.Types)
            {
                CheckAndInclude(report, type, nameArgStrategy);
            }
            RewriteTypeNames(collot, nameArgStrategy, report);
        }
Example #10
0
        private void RewriteTypeNames(ITypeCollector collot, INamingStrategy nameStrategy, IDependencyReport report)
        {
            var          mappings = collot.Types.ToDictionary(k => k, nameStrategy.GetName);
            var          myTypes  = report.Units.Values.SelectMany(v => v.Types.Values).ToArray();
            ICodePatcher patcher  = new CodePatcher(mappings);

            foreach (var map in mappings)
            {
                var typeName = map.Value;
                var type     = myTypes.Single(t => $"{t.Namespace}.{t.Name}" == typeName);
                patcher.Patch(type);
            }
        }
Example #11
0
        private static IEnumerable <KeyValuePair <string, INamespace> > GenerateNamespaces(IDependencyReport report)
        {
            ICodeValidator validator = new MethodDeduper();

            foreach (var pair in report.Units)
            {
                var ass      = pair.Value;
                var fileName = $"{ass.Name}.cs";
                var groups   = pair.Value.Types.GroupBy(u => u.Value.Namespace);
                foreach (var group in groups)
                {
                    var nspName = Deobfuscate(group.Key);
                    var nsp     = Noast.Create <INamespace>(nspName);
                    nsp.AddUsing("System");
                    nsp.AddUsing("System.Text");
                    foreach (var twik in group)
                    {
                        var type    = twik.Value;
                        var kind    = type.Kind;
                        var rawName = DerivedClassDeobfuscate(type.Name).Replace("`1", "");
                        var name    = rawName;
                        if (!IsAttribute(type) && (HasNativeMethod(type) || kind == TypeKind.Struct || kind == TypeKind.Class))
                        {
                            kind = TypeKind.Interface;
                            if (HasNativeMethod(type))
                            {
                                name = $"I{name}";
                            }
                        }
                        var cstrs = type.Methods.Where(m => m.Value.Name.Equals(Defaults.InstConstrName)).ToArray();
                        if (cstrs.Any() && !IsAttribute(type))
                        {
                            var factType = Noast.Create <IInterface>($"I{rawName}Factory", nsp).With(Visibility.Public);
                            foreach (var cstr in cstrs)
                            {
                                var factMethod = Noast.Create <IMethod>($"Create{rawName}");
                                factMethod.ReturnType = name;
                                foreach (var parm in cstr.Value.Parameters)
                                {
                                    var fparm = Noast.Create <IParameter>(parm.Name);
                                    fparm.Type = parm.Type;
                                    factMethod.Parameters.Add(fparm);
                                }
                                factType.Methods.Add(factMethod);
                                type.Methods.Remove(cstr.Key);
                            }
                        }
                        switch (kind)
                        {
                        case TypeKind.Interface:
                            var intf = Noast.Create <IInterface>(name, nsp).With(Visibility.Public);
                            GenerateMembers(intf, type);
                            validator.Validate(intf);
                            break;

                        case TypeKind.Struct:
                            var stru = Noast.Create <IStruct>(name, nsp).With(Visibility.Public);
                            GenerateMembers(stru, type);
                            validator.Validate(stru);
                            break;

                        case TypeKind.Class:
                            var clas = Noast.Create <IClass>(name, nsp).With(Visibility.Public);
                            GenerateMembers(clas, type);
                            validator.Validate(clas);
                            break;

                        case TypeKind.Delegate:
                            var dlgt   = Noast.Create <IDelegate>(name, nsp).With(Visibility.Public);
                            var invoke = type.Methods.Single();
                            foreach (var parm in invoke.Value.Parameters)
                            {
                                dlgt.AddParameter(parm.Name, Simplify(parm.Type));
                            }
                            break;

                        case TypeKind.Enum:
                            var enm = Noast.Create <IEnum>(name, nsp).With(Visibility.Public);
                            foreach (var val in type.Values)
                            {
                                enm.AddValue(val.Value.Name);
                            }
                            break;
                        }
                    }
                    yield return(new KeyValuePair <string, INamespace>(fileName, nsp));
                }
            }
        }