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)); } }
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()); } }
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); }
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); }
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); }
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; } }
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); }
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); } }
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); }
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); } }
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)); } } }