/// <inheritdoc /> public MethodBody ReadMethodBody(MethodDefinition owner, MethodDefinitionRow row) { try { if (row.Body.CanRead) { if (owner.IsIL) { var rawBody = CilRawMethodBody.FromReader(row.Body.CreateReader()); return(CilMethodBody.FromRawMethodBody(owner, rawBody)); } else { // TODO: handle native method bodies. } } else if (row.Body.IsBounded && row.Body.GetSegment() is CilRawMethodBody rawMethodBody) { return(CilMethodBody.FromRawMethodBody(owner, rawMethodBody)); } } catch when(!ThrowOnInvalidMethodBody) { return(null); } return(null); }
private static void ReplaceBodyWithNativeCode(IPEImage image, CodeSegment body, bool is32bit) { // Adjust image flags appropriately. image.DotNetDirectory.Flags &= ~DotNetDirectoryFlags.ILOnly; if (is32bit) { image.MachineType = MachineType.I386; image.PEKind = OptionalHeaderMagic.Pe32; image.DotNetDirectory.Flags |= DotNetDirectoryFlags.Bit32Required; } else { image.MachineType = MachineType.Amd64; image.PEKind = OptionalHeaderMagic.Pe32Plus; } // Access metadata. var metadata = image.DotNetDirectory.Metadata; var stringsStream = metadata.GetStream <StringsStream>(); var tablesStream = metadata.GetStream <TablesStream>(); var typeTable = tablesStream.GetTable <TypeDefinitionRow>(); var methodTable = tablesStream.GetTable <MethodDefinitionRow>(); // Find the method to replace its body of. int index = -1; for (int i = 0; i < methodTable.Count && index == -1; i++) { if (stringsStream.GetStringByIndex(methodTable[i].Name) == "GetTheAnswer") { index = i; } } // Replace body. var methodRow = methodTable[index]; methodTable[index] = new MethodDefinitionRow( new SegmentReference(body), methodRow.ImplAttributes | MethodImplAttributes.Native | MethodImplAttributes.Unmanaged | MethodImplAttributes.PreserveSig, methodRow.Attributes | MethodAttributes.PInvokeImpl, methodRow.Name, methodRow.Signature, methodRow.ParameterList); // Move to <Module> var typeRow = typeTable[1]; typeTable[1] = new TypeDefinitionRow( typeRow.Attributes, typeRow.Name, typeRow.Namespace, typeRow.Extends, typeRow.FieldList, (uint)(index + 2)); }
/// <summary> /// Creates a method definition from a method metadata row. /// </summary> /// <param name="parentModule">The module that contains the method.</param> /// <param name="token">The token to initialize the method for.</param> /// <param name="row">The metadata table row to base the method definition on.</param> public SerializedMethodDefinition(SerializedModuleDefinition parentModule, MetadataToken token, MethodDefinitionRow row) : base(token) { _parentModule = parentModule ?? throw new ArgumentNullException(nameof(parentModule)); _row = row; Attributes = row.Attributes; ImplAttributes = row.ImplAttributes; }
public void RowEnumerationTest() { var rawRow = new uint[] { 0x00002050, 0x0000, 0x0091, 0x017E, 0x0023, 0x0001 }; var row = new MethodDefinitionRow( new VirtualAddress(rawRow[0]), (MethodImplAttributes)rawRow[1], (MethodAttributes)rawRow[2], rawRow[3], rawRow[4], rawRow[5]); RowTestUtils.VerifyRowColumnEnumeration(rawRow, row); }
/// <summary> /// Allocates metadata rows for the provided method definitions in the buffer. /// </summary> /// <param name="methods">The methods to define.</param> public void DefineMethods(IEnumerable <MethodDefinition> methods) { var table = Metadata.TablesStream.GetTable <MethodDefinitionRow>(TableIndex.Method); foreach (var method in methods) { // At this point, we might not have added all type defs/refs/specs yet, so we must delay the // serialization of the method body, as well as determining the parameter list. var row = new MethodDefinitionRow( null, method.ImplAttributes, method.Attributes, Metadata.StringsStream.GetStringIndex(method.Name), Metadata.BlobStream.GetBlobIndex(this, method.Signature, DiagnosticBag), 0); var token = table.Add(row); _tokenMapping.Register(method, token); } }