/// <inheritdoc /> public DynamicCilOperandResolver(SerializedModuleDefinition contextModule, CilMethodBody methodBody, IList <object> tokens) : base(contextModule, methodBody) { _tokens = tokens ?? throw new ArgumentNullException(nameof(tokens)); _readerContext = contextModule.ReaderContext; _importer = new ReferenceImporter(contextModule); }
public void AddStringReference() { const string testConstant = "Lorem ipsum."; // set up temp assembly. var assembly = Utilities.CreateTempNetAssembly(); var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var methodTable = tableStream.GetTable <MethodDefinition>(); var importer = new ReferenceImporter(tableStream); // write code. var body = methodTable[0].MethodBody; body.Instructions.Clear(); body.Instructions.Add(MsilInstruction.Create(MsilOpCodes.Ldstr, testConstant)); body.Instructions.Add(MsilInstruction.Create(MsilOpCodes.Call, importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })))); body.Instructions.Add(MsilInstruction.Create(MsilOpCodes.Call, importer.ImportMethod(typeof(Console).GetMethod("ReadKey", Type.EmptyTypes)))); body.Instructions.Add(MsilInstruction.Create(MsilOpCodes.Pop)); body.Instructions.Add(MsilInstruction.Create(MsilOpCodes.Ret)); // build and validate. assembly = Utilities.RebuildNetAssembly(assembly); methodTable = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>().GetTable <MethodDefinition>(); var operand = methodTable[0].MethodBody.Instructions[0].Operand; Assert.IsInstanceOfType(operand, typeof(string)); Assert.AreEqual(testConstant, operand); }
public void EntrypointNotAdded() { // Create new assembly. var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, false); var image = assembly.NetDirectory.MetadataHeader.LockMetadata(); var importer = new ReferenceImporter(image); var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })); // Create but don't add main method. var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static, new MethodSignature(image.TypeSystem.Void)); main.CilMethodBody = new CilMethodBody(main); main.CilMethodBody.Instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldstr, "Hello world!"), CilInstruction.Create(CilOpCodes.Call, writeLine), CilInstruction.Create(CilOpCodes.Ret), }); image.ManagedEntrypoint = main; Assert.Throws <MemberNotImportedException>(() => image.Header.UnlockMetadata()); }
public void OperandTypeField() { var methodBody = CreateDummyMethodBody(); var image = methodBody.Method.Image; var importer = new ReferenceImporter(image); var instructions = methodBody.Instructions; var simpleField = importer.ImportField(typeof(Type).GetField("EmptyTypes", BindingFlags.Public | BindingFlags.Static)); instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldsfld, simpleField), CilInstruction.Create(CilOpCodes.Pop), CilInstruction.Create(CilOpCodes.Ret), }); var mapping = image.Header.UnlockMetadata(); image = image.Header.LockMetadata(); var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]); instructions = newMethod.CilMethodBody.Instructions; Assert.Equal(simpleField, instructions[0].Operand as IMemberReference, _comparer); }
public void PersistentNestedClasses() { var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true); var header = assembly.NetDirectory.MetadataHeader; var image = header.LockMetadata(); var importer = new ReferenceImporter(image); var type = new TypeDefinition("SomeNamespace", "SomeType", TypeAttributes.Public, importer.ImportType(typeof(object))); var nestedType = new TypeDefinition(null, "NestedType", TypeAttributes.NestedPublic, importer.ImportType(typeof(object))); type.NestedClasses.Add(new NestedClass(nestedType)); image.Assembly.Modules[0].TopLevelTypes.Add(type); var mapping = header.UnlockMetadata(); image = header.LockMetadata(); type = (TypeDefinition)image.ResolveMember(mapping[type]); Assert.Single(type.NestedClasses); Assert.Same(type, type.NestedClasses[0].EnclosingClass); Assert.Equal(nestedType, type.NestedClasses[0].Class, _comparer); Assert.DoesNotContain(type.NestedClasses[0].Class, image.Assembly.Modules[0].TopLevelTypes); Assert.Contains(type.NestedClasses[0].Class, image.Assembly.Modules[0].GetAllTypes()); }
public void StackInbalanceLoop() { var methodBody = CreateDummyMethodBody(); var importer = new ReferenceImporter(methodBody.Method.Image); var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) })); var instructions = methodBody.Instructions; var loopHead = CilInstruction.Create(CilOpCodes.Nop); instructions.AddRange(new[] { loopHead, CilInstruction.Create(CilOpCodes.Ldc_I4_1), CilInstruction.Create(CilOpCodes.Ldc_I4_2), CilInstruction.Create(CilOpCodes.Add), CilInstruction.Create(CilOpCodes.Call, writeLine), CilInstruction.Create(CilOpCodes.Ldc_I4_0), CilInstruction.Create(CilOpCodes.Ldc_I4_1), CilInstruction.Create(CilOpCodes.Brtrue, loopHead), CilInstruction.Create(CilOpCodes.Ret), }); Assert.Throws <StackInbalanceException>(() => methodBody.ComputeMaxStack()); }
public void PersistentVariables() { var methodBody = CreateDummyMethodBody(); var image = methodBody.Method.Image; var importer = new ReferenceImporter(image); var var1 = new VariableSignature(image.TypeSystem.Int32); var var2 = new VariableSignature(importer.ImportTypeSignature(typeof(Stream))); methodBody.Signature = new StandAloneSignature(new LocalVariableSignature(new[] { var1, var2 })); var mapping = image.Header.UnlockMetadata(); image = image.Header.LockMetadata(); methodBody = ((MethodDefinition)image.ResolveMember(mapping[methodBody.Method])).CilMethodBody; Assert.NotNull(methodBody.Signature); Assert.IsType <LocalVariableSignature>(methodBody.Signature.Signature); var localVarSig = (LocalVariableSignature)methodBody.Signature.Signature; Assert.Equal(2, localVarSig.Variables.Count); Assert.Equal(var1.VariableType, localVarSig.Variables[0].VariableType, _comparer); Assert.Equal(var2.VariableType, localVarSig.Variables[1].VariableType, _comparer); }
public void ComplexGenericTypeInstance() { var spec = CreateDummyType(); var image = spec.Image; var importer = new ReferenceImporter(image); // Tuple<Tuple<decimal, decimal>, Tuple<decimal, decimal>> var signature = new GenericInstanceTypeSignature(importer.ImportType(typeof(Tuple <,>)), new GenericInstanceTypeSignature( importer.ImportType(typeof(Tuple <,>)), importer.ImportTypeSignature(typeof(decimal)), importer.ImportTypeSignature(typeof(decimal))), new GenericInstanceTypeSignature( importer.ImportType(typeof(Tuple <,>)), importer.ImportTypeSignature(typeof(decimal)), importer.ImportTypeSignature(typeof(decimal)))); spec.Signature = signature; var header = image.Header; var mapping = header.UnlockMetadata(); var newImage = header.LockMetadata(); var newSpec = (TypeSpecification)newImage.ResolveMember(mapping[spec]); Assert.Equal(signature, newSpec.Signature, Comparer); }
public void ImportGenericInstanceType() { var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true); var image = assembly.NetDirectory.MetadataHeader.LockMetadata(); var importer = new ReferenceImporter(image); var signature = new GenericInstanceTypeSignature(CreateTypeReference(typeof(List <>))); var genericArg = CreateTypeDefOrRef(typeof(Form)); signature.GenericArguments.Add(genericArg); var newSignature = importer.ImportTypeSignature(signature); Assert.NotSame(signature, newSignature); Assert.Equal(signature, newSignature, _comparer); var newGenericSiganture = (GenericInstanceTypeSignature)newSignature; Assert.Equal(image, newGenericSiganture.GenericType.Image); var genericArgElementType = newGenericSiganture.GenericArguments[0].GetElementType(); Assert.IsAssignableFrom <ITypeDefOrRef>(genericArgElementType); Assert.Equal(image, ((ITypeDefOrRef)genericArgElementType).Image); }
public void NewStandaloneSignature() { var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld); // Import arbitrary method signature. var importer = new ReferenceImporter(module); var signature = new StandAloneSignature( importer.ImportMethodSignature(MethodSignature.CreateStatic(module.CorLibTypeFactory.Void))); // Ensure reference is added to the module by referencing it in main. var instructions = module.ManagedEntrypointMethod.CilMethodBody.Instructions; instructions.Insert(0, CilOpCodes.Ldnull); instructions.Insert(0, CilOpCodes.Calli, signature); // Rebuild. var builder = new ManagedPEImageBuilder(); var result = builder.CreateImage(module); // Assert valid token. var newToken = result.TokenMapping[signature]; Assert.NotEqual(0u, newToken.Rid); // Assert token resolves to the same method reference. var newModule = ModuleDefinition.FromImage(result.ConstructedImage); var newSignature = (StandAloneSignature)newModule.LookupMember(newToken); Assert.Equal(signature.Signature, newSignature.Signature, new SignatureComparer()); }
private TypeSpecification CreateDummyType() { var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", true); var image = assembly.NetDirectory.MetadataHeader.LockMetadata(); var importer = new ReferenceImporter(image); var typeSpec = (TypeSpecification)importer.ImportType(new TypeSpecification(image.TypeSystem.Void)); var method = new MethodDefinition("SomeMethod", MethodAttributes.Public | MethodAttributes.Static, new MethodSignature(image.TypeSystem.Void)); method.CilMethodBody = new CilMethodBody(method) { Instructions = { CilInstruction.Create(CilOpCodes.Ldtoken, typeSpec), CilInstruction.Create(CilOpCodes.Pop), CilInstruction.Create(CilOpCodes.Ret), } }; image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(method); return(typeSpec); }
public void NewMethodSpecification() { var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld); // Import arbitrary generic method. var importer = new ReferenceImporter(module); var reference = importer.ImportMethod(typeof(Array).GetMethod("Empty").MakeGenericMethod(typeof(object))); // Ensure method reference is added to the module by referencing it in main. var instructions = module.ManagedEntrypointMethod.CilMethodBody.Instructions; instructions.Insert(0, CilOpCodes.Call, reference); instructions.Insert(1, CilOpCodes.Pop); // Rebuild. var builder = new ManagedPEImageBuilder(); var result = builder.CreateImage(module); // Assert valid token. var newToken = result.TokenMapping[reference]; Assert.NotEqual(0u, newToken.Rid); // Assert token resolves to the same method reference. var newModule = ModuleDefinition.FromImage(result.ConstructedImage); var newReference = (MethodSpecification)newModule.LookupMember(newToken); Assert.Equal(reference.Name, newReference.Name); }
public void NewTypeReference() { var module = ModuleDefinition.FromBytes(Properties.Resources.HelloWorld); // Import arbitrary type as reference. var importer = new ReferenceImporter(module); var reference = importer.ImportType(typeof(MemoryStream)); // Ensure type ref is added to the module by adding a dummy field referencing it. module.GetOrCreateModuleType().Fields.Add(new FieldDefinition( "MyField", FieldAttributes.Public | FieldAttributes.Static, FieldSignature.CreateStatic(reference.ToTypeSignature()))); // Rebuild. var builder = new ManagedPEImageBuilder(); var result = builder.CreateImage(module); // Assert valid token. var newToken = result.TokenMapping[reference]; Assert.NotEqual(0u, newToken.Rid); // Assert token resolves to the same type reference. var newModule = ModuleDefinition.FromImage(result.ConstructedImage); var newReference = (TypeReference)newModule.LookupMember(newToken); Assert.Equal(reference.Namespace, newReference.Namespace); Assert.Equal(reference.Name, newReference.Name); }
public void ExtensionMethodTest() { var sourceAssembly = WindowsAssembly.FromFile(typeof(StaticClass).Assembly.Location); var sourceImage = sourceAssembly.NetDirectory.MetadataHeader.LockMetadata(); var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", false); var header = assembly.NetDirectory.MetadataHeader; var image = header.LockMetadata(); var importer = new ReferenceImporter(image); var cloner = new MemberCloner(image); var staticClass = sourceImage.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == "StaticClass"); var clonedType = cloner.CloneType(staticClass); var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static, new MethodSignature(image.TypeSystem.Void)); main.CilMethodBody = new CilMethodBody(main); var instructions = main.CilMethodBody.Instructions; instructions.Add(CilInstruction.Create(CilOpCodes.Ldc_I4_1)); instructions.Add(CilInstruction.Create(CilOpCodes.Call, clonedType.Methods.First(x => x.Name == "SomeExtension"))); instructions.Add(CilInstruction.Create(CilOpCodes.Call, importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) })))); instructions.Add(CilInstruction.Create(CilOpCodes.Ret)); image.Assembly.Modules[0].TopLevelTypes.Add(clonedType); image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main); image.ManagedEntrypoint = main; header.UnlockMetadata(); _context.VerifyOutput(assembly, "4"); }
public void CreateCustomSizeFieldRva() { const int dataSize = 128; var assembly = Utilities.CreateTempNetAssembly(); var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var typeTable = tableStream.GetTable <TypeDefinition>(); var classLayoutTable = tableStream.GetTable <ClassLayout>(); var importer = new ReferenceImporter(tableStream); var type = new TypeDefinition(string.Empty, "__StaticArrayInitTypeSize=" + dataSize, importer.ImportType(typeof(ValueType))); type.MetadataRow.Column5 = 2; // FieldList type.MetadataRow.Column6 = 2; // MethodList typeTable.Add(type); var layout = new ClassLayout(type, 128, 1); type.ClassLayout = layout; classLayoutTable.Add(layout); TestFieldRva(assembly, new TypeDefOrRefSignature(type), Enumerable.Repeat((byte)1, dataSize).ToArray(), false); }
public void CreateGenericInstanceFieldReflection() { // set up temp assembly. var assembly = Utilities.CreateTempNetAssembly(); var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var fieldTable = tableStream.GetTable <FieldDefinition>(); var importer = new ReferenceImporter(tableStream); // create field. var typeSignature = (GenericInstanceTypeSignature)importer.ImportTypeSignature(typeof(List <string>)); var field = new FieldDefinition(FieldName, FieldAttributes.Public | FieldAttributes.Static, new FieldSignature(typeSignature)); fieldTable.Add(field); // build and validate. assembly = Utilities.RebuildNetAssembly(assembly); fieldTable = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>().GetTable <FieldDefinition>(); field = fieldTable.First(x => x.Name == FieldName); Assert.IsInstanceOfType(field.Signature.FieldType, typeof(GenericInstanceTypeSignature)); var newTypeSignature = (GenericInstanceTypeSignature)field.Signature.FieldType; Utilities.ValidateType(typeSignature.GenericType, newTypeSignature.GenericType); Assert.AreEqual(typeSignature.GenericArguments.Count, newTypeSignature.GenericArguments.Count); for (int i = 0; i < typeSignature.GenericArguments.Count; i++) { Assert.AreEqual(typeSignature.GenericArguments[i].FullName, newTypeSignature.GenericArguments[i].FullName); } }
public void ComputeMaxStackConditionalBranch() { var methodBody = CreateDummyMethodBody(); var importer = new ReferenceImporter(methodBody.Method.Image); var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) })); var instructions = methodBody.Instructions; var elseInstr = CilInstruction.Create(CilOpCodes.Sub); var endInstr = CilInstruction.Create(CilOpCodes.Call, writeLine); instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldc_I4_1), CilInstruction.Create(CilOpCodes.Ldc_I4_2), CilInstruction.Create(CilOpCodes.Ldc_I4_0), CilInstruction.Create(CilOpCodes.Brtrue, elseInstr), CilInstruction.Create(CilOpCodes.Add), CilInstruction.Create(CilOpCodes.Br, endInstr), elseInstr, endInstr, CilInstruction.Create(CilOpCodes.Ret) }); Assert.Equal(3, methodBody.ComputeMaxStack()); }
public void CreateRequiredModifierField() { // set up temp assembly. var assembly = Utilities.CreateTempNetAssembly(); var typeSystem = assembly.NetDirectory.MetadataHeader.TypeSystem; var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var fieldTable = tableStream.GetTable <FieldDefinition>(); var importer = new ReferenceImporter(tableStream); // create field. var typeSignature = new RequiredModifierSignature(importer.ImportType(typeof(IsVolatile)), typeSystem.Int32); var field = new FieldDefinition(FieldName, FieldAttributes.Public | FieldAttributes.Static, new FieldSignature(typeSignature)); fieldTable.Add(field); // build and validate. assembly = Utilities.RebuildNetAssembly(assembly); fieldTable = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>().GetTable <FieldDefinition>(); field = fieldTable.First(x => x.Name == FieldName); Assert.IsInstanceOfType(field.Signature.FieldType, typeof(RequiredModifierSignature)); var newTypeSignature = (RequiredModifierSignature)field.Signature.FieldType; Utilities.ValidateType(typeSignature.ModifierType, newTypeSignature.ModifierType); Utilities.ValidateType(typeSignature.BaseType, newTypeSignature.BaseType); }
public void PersistentInstructions() { var methodBody = CreateDummyMethodBody(); var image = methodBody.Method.Image; var importer = new ReferenceImporter(image); var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })); var instructions = methodBody.Instructions; instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldstr, "Lorem Ipsum"), CilInstruction.Create(CilOpCodes.Call, writeLine), CilInstruction.Create(CilOpCodes.Ret), }); var mapping = image.Header.UnlockMetadata(); image = image.Header.LockMetadata(); var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]); Assert.Equal(instructions, newMethod.CilMethodBody.Instructions, new CilInstructionComparer()); }
public void CreateArrayField() { // set up temp assembly. var assembly = Utilities.CreateTempNetAssembly(); var typeSystem = assembly.NetDirectory.MetadataHeader.TypeSystem; var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var fieldTable = tableStream.GetTable <FieldDefinition>(); var importer = new ReferenceImporter(tableStream); // create field. var arraySignature = new ArrayTypeSignature(typeSystem.Int32); arraySignature.Dimensions.Add(new ArrayDimension(2, 1)); arraySignature.Dimensions.Add(new ArrayDimension(2)); arraySignature.Dimensions.Add(new ArrayDimension()); var field = new FieldDefinition(FieldName, FieldAttributes.Public | FieldAttributes.Static, new FieldSignature(importer.ImportTypeSignature(arraySignature))); fieldTable.Add(field); // build and validate. assembly = Utilities.RebuildNetAssembly(assembly); fieldTable = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>().GetTable <FieldDefinition>(); field = fieldTable.First(x => x.Name == FieldName); Assert.IsInstanceOfType(field.Signature.FieldType, typeof(ArrayTypeSignature)); Utilities.ValidateType(arraySignature, field.Signature.FieldType); }
public void OperandTypeType() { var methodBody = CreateDummyMethodBody(); var image = methodBody.Method.Image; var importer = new ReferenceImporter(image); var instructions = methodBody.Instructions; var simpleType = importer.ImportType(typeof(Form)); instructions.Add(CilInstruction.Create(CilOpCodes.Ldtoken, simpleType)); instructions.Add(CilInstruction.Create(CilOpCodes.Pop)); var genericType = importer.ImportType(typeof(List <Form>)); instructions.Add(CilInstruction.Create(CilOpCodes.Ldtoken, genericType)); instructions.Add(CilInstruction.Create(CilOpCodes.Pop)); instructions.Add(CilInstruction.Create(CilOpCodes.Ret)); var mapping = image.Header.UnlockMetadata(); image = image.Header.LockMetadata(); var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]); instructions = newMethod.CilMethodBody.Instructions; Assert.Equal(simpleType, instructions[0].Operand as ITypeDescriptor, _comparer); Assert.Equal(genericType, instructions[2].Operand as ITypeDescriptor, _comparer); }
public void ImportNewTypeReference() { var assembly = Utilities.CreateTempNetAssembly(); var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var importer = new ReferenceImporter(tableStream); var typeRefTable = tableStream.GetTable <TypeReference>(); var assemblyRefTable = tableStream.GetTable <AssemblyReference>(); const string typeNamespace = "System.Windows.Forms"; const string typeName = "Form"; var assemblyDescr = new ReflectionAssemblyNameWrapper(typeof(Form).Assembly.GetName()); var reference = new TypeReference(importer.ImportAssembly(assemblyDescr), typeNamespace, typeName); var newReference = importer.ImportType(reference); Assert.AreNotSame(reference, newReference, "Imported reference is the same object as original."); Assert.IsTrue(typeRefTable.Contains(newReference), "Imported reference not added to reference table."); Assert.IsTrue(_comparer.MatchTypes(reference, newReference), "Imported reference does not match original."); Assert.IsTrue(assemblyRefTable.FirstOrDefault(x => _comparer.MatchAssemblies(x, assemblyDescr)) != null, "Assembly reference not added to reference table."); }
public void OperandTypeSig() { var methodBody = CreateDummyMethodBody(); var image = methodBody.Method.Image; var importer = new ReferenceImporter(image); var instructions = methodBody.Instructions; var signature = importer.ImportStandAloneSignature( new StandAloneSignature(new MethodSignature(image.TypeSystem.Void) { HasThis = false })); instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Calli, signature), CilInstruction.Create(CilOpCodes.Ret) }); var mapping = image.Header.UnlockMetadata(); image = image.Header.LockMetadata(); var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]); instructions = newMethod.CilMethodBody.Instructions; var newSignature = (StandAloneSignature)instructions[0].Operand; Assert.Equal(signature.Signature as MethodSignature, newSignature.Signature as MethodSignature, _comparer); }
public void ImportExternalTypeDefinition() { var externalAssembly = Utilities.CreateTempNetAssembly(); var tableStream = externalAssembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var externalAssemblyDef = tableStream.GetTable <AssemblyDefinition>().First(); var externalType = new TypeDefinition("SomeNamespace", "SomeName"); tableStream.GetTable <TypeDefinition>().Add(externalType); var assembly = Utilities.CreateTempNetAssembly(); tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var importer = new ReferenceImporter(tableStream); var newReference = importer.ImportType(externalType); Assert.AreNotSame(externalType, newReference, "Imported reference is the same object as original."); Assert.IsTrue(_comparer.MatchTypes(externalType, newReference), "Imported reference does not match original."); Assert.IsTrue(tableStream.GetTable <AssemblyReference>().FirstOrDefault(x => _comparer.MatchAssemblies(x, externalAssemblyDef)) != null, "Assembly reference not added to table."); }
public void PersistentMethodImplementations() { var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true); var header = assembly.NetDirectory.MetadataHeader; var image = header.LockMetadata(); var importer = new ReferenceImporter(image); var type = new TypeDefinition("SomeNamespace", "SomeType", TypeAttributes.Public, importer.ImportType(typeof(object))); var @interface = importer.ImportType(typeof(IList)); type.Interfaces.Add(new InterfaceImplementation(@interface)); var addMethodRef = (IMethodDefOrRef)importer.ImportMethod(typeof(IList).GetMethod("Add", new[] { typeof(object) })); var addMethodDef = new MethodDefinition("Add", MethodAttributes.Public, (MethodSignature)addMethodRef.Signature); type.Methods.Add(addMethodDef); type.MethodImplementations.Add(new MethodImplementation(addMethodDef, addMethodRef)); image.Assembly.Modules[0].TopLevelTypes.Add(type); var mapping = header.UnlockMetadata(); image = header.LockMetadata(); type = (TypeDefinition)image.ResolveMember(mapping[type]); Assert.Single(type.MethodImplementations); Assert.Same(type, type.MethodImplementations[0].Class); Assert.Equal(addMethodDef, type.MethodImplementations[0].MethodBody, _comparer); Assert.Equal(addMethodRef, type.MethodImplementations[0].MethodDeclaration, _comparer); }
public void ImportGenericInstanceType() { var assembly = Utilities.CreateTempNetAssembly(); var tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var importer = new ReferenceImporter(tableStream); var signature = new GenericInstanceTypeSignature(CreateTypeReference(typeof(List <>))); var genericArg = CreateTypeDefOrRef(typeof(Form)); signature.GenericArguments.Add(genericArg); var newSignature = importer.ImportTypeSignature(signature); Assert.AreNotSame(signature, newSignature, "Imported signature is the same object as original."); Assert.IsTrue(_comparer.MatchTypes(signature, newSignature), "Imported signature does not match original."); Assert.IsTrue(tableStream.GetTable <TypeReference>().FirstOrDefault(x => _comparer.MatchTypes(x, signature.GenericType)) != null, "Generic type reference not added to table."); Assert.IsTrue(tableStream.GetTable <TypeReference>().FirstOrDefault(x => _comparer.MatchTypes(x, genericArg.Type)) != null, "Generic type argument not added to table."); }
public void PersistentEntrypoint() { // Create new assembly. var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, false); var image = assembly.NetDirectory.MetadataHeader.LockMetadata(); var importer = new ReferenceImporter(image); var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) })); // Create and add main method. var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static, new MethodSignature(image.TypeSystem.Void)); main.CilMethodBody = new CilMethodBody(main); main.CilMethodBody.Instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldstr, "Hello world!"), CilInstruction.Create(CilOpCodes.Call, writeLine), CilInstruction.Create(CilOpCodes.Ret), }); image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main); image.ManagedEntrypoint = main; // Commit. var mapping = image.Header.UnlockMetadata(); // Test. Assert.Equal(mapping[main].ToUInt32(), assembly.NetDirectory.EntryPointToken); var newImage = assembly.NetDirectory.MetadataHeader.LockMetadata(); Assert.Equal(main, newImage.ManagedEntrypoint, _comparer); }
public void ImportExternalFieldDefinition() { var externalAssembly = Utilities.CreateTempNetAssembly(); var metadataHeader = externalAssembly.NetDirectory.MetadataHeader; var tableStream = metadataHeader.GetStream <TableStream>(); var type = new TypeDefinition("SomeNamespace", "SomeType"); tableStream.GetTable <TypeDefinition>().Add(type); var field = new FieldDefinition("SomeField", FieldAttributes.Public | FieldAttributes.Static, new FieldSignature(metadataHeader.TypeSystem.String)); type.Fields.Add(field); tableStream.GetTable <FieldDefinition>().Add(field); var assembly = Utilities.CreateTempNetAssembly(); tableStream = assembly.NetDirectory.MetadataHeader.GetStream <TableStream>(); var importer = new ReferenceImporter(tableStream); var newReference = importer.ImportField(field) as MemberReference; Assert.AreNotSame(field, newReference, "Imported field definition is the same object as the original."); Assert.IsTrue(_comparer.MatchMembers(field, newReference), "Imported field definition does not match the original."); }
public void PersistentManagedFatMethodVariables() { const string expectedOutput = "Hello, world!"; var assembly = CreateTempAssembly(); var image = assembly.NetDirectory.MetadataHeader.Image; var importer = new ReferenceImporter(image); var mainMethod = image.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == TypeName).Methods.First(x => x.Name == MainMethodName); mainMethod.CilMethodBody.Signature = new StandAloneSignature( new LocalVariableSignature(new[] { image.TypeSystem.String })); var instructions = mainMethod.CilMethodBody.Instructions; instructions.AddRange(new[] { CilInstruction.Create(CilOpCodes.Ldstr, expectedOutput), CilInstruction.Create(CilOpCodes.Stloc_0), CilInstruction.Create(CilOpCodes.Ldloc_0), CilInstruction.Create(CilOpCodes.Call, importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }))), CilInstruction.Create(CilOpCodes.Ret) }); assembly.NetDirectory.MetadataHeader.UnlockMetadata(); _context.VerifyOutput(assembly, expectedOutput); }
public void PersistentNamedArgument() { var assembly = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, true); var header = assembly.NetDirectory.MetadataHeader; var image = header.LockMetadata(); var importer = new ReferenceImporter(image); var namedArg = new CustomAttributeNamedArgument(CustomAttributeArgumentMemberType.Property, image.TypeSystem.Boolean, "Exclude", new CustomAttributeArgument(image.TypeSystem.Boolean, new ElementSignature(true))); var customAttribute = new CustomAttribute( (ICustomAttributeType)importer.ImportMethod( typeof(ObfuscationAttribute).GetConstructor(Type.EmptyTypes)), new CustomAttributeSignature { NamedArguments = { namedArg } }); image.Assembly.CustomAttributes.Add(customAttribute); header.UnlockMetadata(); image = header.LockMetadata(); Assert.Single(image.Assembly.CustomAttributes); var newArg = image.Assembly.CustomAttributes[0].Signature.NamedArguments[0]; Assert.Equal(namedArg.MemberName, newArg.MemberName); Assert.Equal(namedArg.ArgumentMemberType, newArg.ArgumentMemberType); Assert.Equal(namedArg.Argument.ArgumentType, newArg.Argument.ArgumentType, _comparer); Assert.Equal(namedArg.Argument.Elements[0].Value, newArg.Argument.Elements[0].Value); }