Beispiel #1
0
 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);
         }
     }
 }
Beispiel #2
0
        //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()}");
        }
Beispiel #3
0
        /// <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);
        }