Exemplo n.º 1
0
        private static void injectAssemblyLoad(MethodBody methodBody, string sourceAssemblyPath, Func <MethodDefinition, MethodReference> resolveMethod)
        {
            methodBody.SimplifyMacros();

            var returnInstructions = methodBody.Instructions
                                     .Where(x => x.OpCode == OpCodes.Ret)
                                     .ToList();

            using var sourceAssembly = AssemblyPathUtils.ReadAssemblyFromPath(sourceAssemblyPath, false);
            var sourceAssemblyMainModule = sourceAssembly.MainModule;

            var foundMethodInitializerMethods = ModuleDefinitionUtils.FindModuleInitializerMethods(sourceAssemblyMainModule)
                                                .Select(resolveMethod);

            foreach (var instruction in returnInstructions)
            {
                var instructions = new List <Instruction>(foundMethodInitializerMethods.Select(x => Instruction.Create(OpCodes.Call, x)))
                {
                    Instruction.Create(OpCodes.Ret)
                };

                methodBody.Instructions.Replace(instruction, instructions);
            }

            methodBody.OptimizeMacros();
        }
Exemplo n.º 2
0
        public static int Main(string[] args)
        {
            return(Parser.Default.ParseArguments <ReadFullAssemblyNameCommand, InjectAssemblyLoaderCommandOptions>(args)
                   .MapResult <ReadFullAssemblyNameCommand, InjectAssemblyLoaderCommandOptions, int>(
                       fullNameOptions => {
                try {
                    var assemblyFullName = AssemblyPathUtils.ReadAssemblyFullName(fullNameOptions.AssemblyPath);
                    Console.Out.WriteLine(assemblyFullName);
                } catch (ArgumentNullException) {
                    Console.Error.WriteLine("The assembly path cannot be null.");
                    return 1;
                } catch (FileNotFoundException) {
                    Console.Error.WriteLine("The assembly file was not found.");
                    return 1;
                } catch (Exception error) {
                    Console.Error.WriteLine(GetMessageWithPrependedType(error, "An error occured while trying to read the full assembly name."));
                    return 1;
                }

                return 0;
            },
                       injectOptions => {
                try {
                    AssemblyLoaderInjector.Default.InjectAssemblyLoader(injectOptions.InjectionTargetAssemblyPath,
                                                                        injectOptions.SourceAssemblyPathToBeLoaded);
                } catch (ArgumentNullException error) {
                    Console.Error.WriteLine($"The assembly path cannot be null. ({error.ParamName})");
                    return 1;
                } catch (FileNotFoundException error) {
                    Console.Error.WriteLine($"The assembly file '{error.FileName}' was not found.");
                    return 1;
                } catch (AggregateException error) {
                    foreach (var innerError in error.InnerExceptions)
                    {
                        Console.Error.WriteLine(GetMessageWithPrependedType(innerError));
                    }

                    return 1;
                } catch (Exception error) {
                    Console.Error.WriteLine(GetMessageWithPrependedType(error, "An error occured while trying to inject the " +
                                                                        $"full assembly name to injection target assembly."));

                    return 1;
                }

                return 0;
            },
                       errors => {
                foreach (var error in errors)
                {
                    Console.Error.WriteLine(error.ToString());
                }

                return 1;
            }));
        }
Exemplo n.º 3
0
        public void InjectAssemblyInitializer(string injectionTargetAssemblyPath, string sourceAssemblyPath, string?keyFile)
        {
            injectionTargetAssemblyPath = injectionTargetAssemblyPath
                                          ?? throw new ArgumentNullException(nameof(injectionTargetAssemblyPath));

            sourceAssemblyPath = sourceAssemblyPath
                                 ?? throw new ArgumentNullException(nameof(sourceAssemblyPath));

            var injectionTargetAssemblyCopyPath = Path.GetTempFileName();

            void deleteInjectionTargetAssemblyCopyFile() =>
            File.Delete(injectionTargetAssemblyCopyPath);

            try {
                // Copy original injection target assembly to temporary assembly path.
                File.Copy(injectionTargetAssemblyPath, injectionTargetAssemblyCopyPath, true);
                var assemblyPdbFilePath           = AssemblyPathUtils.GetPdbFilePathOrDefault(injectionTargetAssemblyCopyPath);
                var assemblyPdbFilePathIsExisting = !string.IsNullOrEmpty(assemblyPdbFilePath);

                var injectionTargetAssembly = AssemblyPathUtils.ReadAssemblyFromPath(injectionTargetAssemblyCopyPath,
                                                                                     readSymbols: assemblyPdbFilePathIsExisting);

                using var injectionTargetAssemblyMainModule = injectionTargetAssembly.MainModule;
                var injectionTargetAssemblyMainModuleClass          = findModuleClass(injectionTargetAssemblyMainModule);
                var injectionTargetAssemblyMainModuleClassCctor     = findOrCreateCctor(injectionTargetAssemblyMainModuleClass, injectionTargetAssemblyMainModule.TypeSystem);
                var injectionTargetAssemblyMainModuleClassCctorBody = injectionTargetAssemblyMainModuleClassCctor.Body;

                injectAssemblyLoad(injectionTargetAssemblyMainModuleClassCctorBody,
                                   sourceAssemblyPath,
                                   injectionTargetAssemblyMainModule.ImportReference);

                // AssemblyDefinition.Write(..) behaviour is to overwrite path if existing.
                writeTargetInjectionAssembly(injectionTargetAssembly, injectionTargetAssemblyPath, keyFile,
                                             writeSymbols: assemblyPdbFilePathIsExisting);

                injectionTargetAssembly.Dispose();
                deleteInjectionTargetAssemblyCopyFile();
            } catch (Exception error) {
                try {
                    deleteInjectionTargetAssemblyCopyFile();
                } catch (Exception deleteFileError) {
                    throw new AggregateException(error, deleteFileError);
                }

                throw error;
            }
        }