private static ResourceSectionBuilder CreateNativeResourceSectionSerializer(CommonPEModuleBuilder module) { // Win32 resources are supplied to the compiler in one of two forms, .RES (the output of the resource compiler), // or .OBJ (the output of running cvtres.exe on a .RES file). A .RES file is parsed and processed into // a set of objects implementing IWin32Resources. These are then ordered and the final image form is constructed // and written to the resource section. Resources in .OBJ form are already very close to their final output // form. Rather than reading them and parsing them into a set of objects similar to those produced by // processing a .RES file, we process them like the native linker would, copy the relevant sections from // the .OBJ into our output and apply some fixups. ResourceSection nativeResourceSectionOpt = module.Win32ResourceSection; if (nativeResourceSectionOpt != null) { return(new ResourceSectionBuilderFromObj(nativeResourceSectionOpt)); } IEnumerable <IWin32Resource> nativeResourcesOpt = module.Win32Resources; if (nativeResourcesOpt?.Any() == true) { return(new ResourceSectionBuilderFromResources(nativeResourcesOpt)); } return(null); }
public static void SerializeWin32Resources(BlobBuilder builder, ResourceSection resourceSections, int resourcesRva) { var sectionWriter = new BlobWriter(builder.ReserveBytes(resourceSections.SectionBytes.Length)); sectionWriter.WriteBytes(resourceSections.SectionBytes); var readStream = new MemoryStream(resourceSections.SectionBytes); var reader = new BinaryReader(readStream); foreach (int addressToFixup in resourceSections.Relocations) { sectionWriter.Offset = addressToFixup; reader.BaseStream.Position = addressToFixup; sectionWriter.WriteUInt32(reader.ReadUInt32() + (uint)resourcesRva); } }
public ResourceSectionBuilderFromObj(ResourceSection resourceSection) { Debug.Assert(resourceSection != null); _resourceSection = resourceSection; }