private void FindTypeReference(ModuleDefMD module, string assemblyRefName, string typeFullName, Action <TypeRef> action) { foreach (var typeRef in module.GetTypeRefs()) { if (typeRef.DefinitionAssembly.Name == assemblyRefName && typeRef.FullName == typeFullName) { action(typeRef); } } }
//Here we replace the AssemblyRef entry for TrinitySeal with Unitas.Runtime //With this, we not only hijack all library calls //But we also bypass the hash check static void ProcessAssembly(string vars) { Console.WriteLine("Processing assembly..."); var opts = new ModuleWriterOptions(_mod) { Logger = DummyLogger.NoThrowInstance }; var writer = new ModuleWriter(_mod, opts); foreach (var asmref in _mod.GetAssemblyRefs()) { if (asmref.Name != "TrinitySeal") { continue; } Console.WriteLine("Replacing reference"); asmref.Name = "Unitas.Runtime"; } Console.WriteLine("Fixing namespaces..."); foreach (var typeref in _mod.GetTypeRefs()) { if (typeref.Namespace == "TrinitySeal" && typeref.DefinitionAssembly.Name == "Unitas.Runtime") { typeref.Namespace = "Unitas.Runtime"; } } //Preserve EVERYTHING opts.MetadataOptions.PreserveHeapOrder(_mod, true); opts.MetadataOptions.Flags |= MetadataFlags.PreserveRids | MetadataFlags.KeepOldMaxStack; var runtime = Path.Combine(Path.GetDirectoryName(_mod.Location), "Unitas.Runtime.dll"); File.Copy(typeof(Seal).Assembly.Location, runtime, true); if (vars != null) { AddServerVariables(vars, runtime); } writer.Write(GetNewName()); Console.WriteLine($"Bypassed assembly saved at: {GetNewName()}"); }
/// <summary> /// Resolve a TypeDef or TypeRef from its name. If neither a TypeDef or TypeRef are found /// in the module, search its references (AssemblyRefs) and if a match is found, add a TypeRef /// for it to the module and return that. /// </summary> /// <param name="fullName">Name of TypeDef or TypeRef as found in the resource</param> /// <param name="isReflectionName">Whether or not the name is a reflection name</param> /// <returns>TypeDef or TypeRef, or null if none found</returns> public ITypeDefOrRef ResolveTypeDefOrRef(TypeName typeName) { String fullName = typeName.Name; // Return TypeDef if found TypeDef typeDef = _module.Find(fullName, false); if (typeDef != null) { return(typeDef); } // Return existing TypeRef if found var typeRefs = _module.GetTypeRefs(); foreach (var typeRef in typeRefs) { if (typeRef.FullName.Equals(fullName)) { return(typeRef); } } // Get the AssemblyRef from the type name and make our own TypeRef AssemblyRef asmRef = this.FindAssemblyRef(typeName); if (!typeName.IsNested) { return(new TypeRefUser(_module, typeName.Namespace, typeName.NameWithoutNamespace, asmRef)); } else { // Lazy... var parentName = typeName.ParentName.Split('.').Last(); TypeRef resolutionRef = new TypeRefUser(_module, typeName.Namespace, parentName, asmRef); return(new TypeRefUser(_module, "", typeName.NestedName, resolutionRef)); } }
private void ExecuteOperation() { List <(Regex pattern, string replacement)> replacementPatterns = new List <(Regex pattern, string replacement)>(); string[] regexpOptions = _commandLineOptions.Regexps.ToArray(); for (int i = 0; i < regexpOptions.Length; i += 2) { string regexpOption = regexpOptions[i]; string regexpReplacementOption = regexpOptions[i + 1]; Regex regex = new Regex(regexpOption, RegexOptions.Singleline); replacementPatterns.Add((regex, regexpReplacementOption)); } string UpdateName(string name, Action onNameChanged) { string originalName = name; foreach ((Regex pattern, string replacement)replacementPattern in replacementPatterns) { name = replacementPattern.pattern.Replace(name, replacementPattern.replacement); } if (name != originalName) { onNameChanged(); } return(name); } Log.Info($"Reading assembly from {_commandLineOptions.InputAssemblyPath}"); ModuleDefMD module = ModuleDefMD.Load(_commandLineOptions.InputAssemblyPath); AssemblyDef assembly = module.Assembly; TypeDef[] types = module.GetTypes().ToArray(); TypeRef[] typeReferences = module.GetTypeRefs().ToArray(); AssemblyRef[] assemblyReferences = module.GetAssemblyRefs().ToArray(); Log.Info("Updating assembly name"); if (_commandLineOptions.ReplaceAssemblyName) { assembly.Name = UpdateName(assembly.Name, () => Log.Info("Assembly name modified")); for (int i = 0; i < assembly.Modules.Count; i++) { ModuleDef moduleDef = assembly.Modules[i]; int finalI = i; moduleDef.Name = UpdateName(moduleDef.Name, () => Log.Info($"Module {finalI} name modified")); } } Log.Info("Modifying types"); int modifiedTypes = 0; foreach (TypeDef type in types) { type.Namespace = UpdateName(type.Namespace, () => modifiedTypes++); } Log.Info($"Modified {modifiedTypes} type(s)"); Log.Info("Modifying type references"); int modifiedTypeReferences = 0; foreach (TypeRef typeReference in typeReferences) { typeReference.Namespace = UpdateName(typeReference.Namespace, () => modifiedTypeReferences++); } Log.Info($"Modified {modifiedTypeReferences} type reference(s)"); if (_commandLineOptions.ReplaceAssemblyReferences) { Log.Info("Modifying assembly references"); int modifiedReferences = 0; foreach (AssemblyRef assemblyReference in assemblyReferences) { assemblyReference.Name = UpdateName(assemblyReference.Name, () => modifiedReferences++); } Log.Info($"Modified {modifiedReferences} assembly reference(s)"); } Log.Info("Updating attributes"); HashSet <CustomAttribute> customAttributes = new HashSet <CustomAttribute>(); customAttributes.UnionWith(module.CustomAttributes); customAttributes.UnionWith(assembly.CustomAttributes); foreach (TypeDef type in types) { customAttributes.UnionWith(type.CustomAttributes); type.Events.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); type.Fields.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); type.Interfaces.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); type.Methods.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); type.GenericParameters.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); type.Properties.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); foreach (MethodDef method in type.Methods) { method.GenericParameters.ToList().ForEach(m => customAttributes.UnionWith(m.CustomAttributes)); method.Parameters.ToList() .ForEach(m => { if (m.HasParamDef) { customAttributes.UnionWith(m.ParamDef.CustomAttributes); } }); } } int modifiedAttributesParameters = 0; bool isAttributeModified = false; void UpdateAttributeConstructorArgument(object argument) { switch (argument) { case TypeDefOrRefSig type: if (type.IsTypeDef) { type.TypeDef.Namespace = UpdateName(type.Namespace, () => isAttributeModified = true); if (type.TypeDef.Scope is AssemblyRefUser assemblyRefUser) { assemblyRefUser.Name = UpdateName(assemblyRefUser.Name, () => isAttributeModified = true); } } else if (type.IsTypeRef) { type.TypeRef.Namespace = UpdateName(type.Namespace, () => isAttributeModified = true); if (type.TypeRef.Scope is AssemblyRefUser assemblyRefUser) { assemblyRefUser.Name = UpdateName(assemblyRefUser.Name, () => isAttributeModified = true); } } break; case GenericInstSig genericInstSig: foreach (TypeSig genericArgument in genericInstSig.GenericArguments) { UpdateAttributeConstructorArgument(genericArgument); } UpdateAttributeConstructorArgument(genericInstSig.GenericType); break; } } foreach (CustomAttribute customAttribute in customAttributes) { isAttributeModified = false; IEnumerable <CAArgument> constructorArguments = customAttribute.ConstructorArguments.Concat(customAttribute.NamedArguments.Select(na => na.Argument)); foreach (CAArgument attributeConstructorArgument in constructorArguments) { UpdateAttributeConstructorArgument(attributeConstructorArgument.Type); UpdateAttributeConstructorArgument(attributeConstructorArgument.Value); } if (isAttributeModified) { modifiedAttributesParameters++; } } Log.Info($"Modified {modifiedAttributesParameters} attribute(s)"); string outputPath; if (!String.IsNullOrWhiteSpace(_commandLineOptions.OutputAssemblyPath)) { outputPath = _commandLineOptions.OutputAssemblyPath; } else { outputPath = Path.Combine( Path.GetDirectoryName(_commandLineOptions.InputAssemblyPath) ?? "", Path.GetFileNameWithoutExtension(_commandLineOptions.InputAssemblyPath) + ".Modified" + Path.GetExtension(_commandLineOptions.InputAssemblyPath) ); } Log.Info($"Writing assembly to {outputPath}"); assembly.Write(outputPath); }