internal Section GetSectionAtVirtualAddress(RVA rva) { foreach (Section sect in this.Sections) { if (rva >= sect.VirtualAddress && rva < sect.VirtualAddress + sect.SizeOfRawData) { return(sect); } } return(null); }
public long ResolveVirtualAddress(RVA rva) { foreach (Section sect in this.Sections) { if (rva >= sect.VirtualAddress && rva < sect.VirtualAddress + sect.SizeOfRawData) { return(rva + sect.PointerToRawData - sect.VirtualAddress); } } throw new ArgumentOutOfRangeException("Cannot map the rva to any section"); }
public BinaryReader GetReaderAtVirtualAddress(RVA rva) { Section sect = GetSectionAtVirtualAddress(rva); if (sect == null) { return(null); } BinaryReader br = new BinaryReader(new MemoryStream(sect.Data)); br.BaseStream.Position = rva - sect.VirtualAddress; return(br); }
RVA [] ReadArrayOfRVA(RVA position, uint length) { if (position == RVA.Zero) { return(new RVA [0]); } SetPositionToAddress(position); RVA [] addresses = new RVA [length]; for (int i = 0; i < length; i++) { addresses [i] = m_binaryReader.ReadUInt32(); } return(addresses); }
ushort [] ReadArrayOfUInt16(RVA position, uint length) { if (position == RVA.Zero) { return(new ushort [0]); } SetPositionToAddress(position); ushort [] array = new ushort [length]; for (int i = 0; i < length; i++) { array [i] = m_binaryReader.ReadUInt16(); } return(array); }
public void Initialize() { Image img = m_img; ResourceWriter resWriter = null; uint sectAlign = img.PEOptionalHeader.NTSpecificFields.SectionAlignment; uint fileAlign = img.PEOptionalHeader.NTSpecificFields.FileAlignment; m_textSect = img.TextSection; foreach (Section s in img.Sections) { if (s.Name == Section.Relocs) { m_relocSect = s; } else if (s.Name == Section.Resources) { m_rsrcSect = s; m_rsrcWriter = new MemoryBinaryWriter(); resWriter = new ResourceWriter(img, m_rsrcSect, m_rsrcWriter); resWriter.Write(); } } // size computations, fields setting, etc. uint nbSects = (uint)img.Sections.Count; img.PEFileHeader.NumberOfSections = (ushort)nbSects; // build the reloc section data uint relocSize = 12; m_relocWriter.Write((uint)0); m_relocWriter.Write(relocSize); m_relocWriter.Write((ushort)0); m_relocWriter.Write((ushort)0); m_textSect.VirtualSize = (uint)m_textWriter.BaseStream.Length; m_relocSect.VirtualSize = (uint)m_relocWriter.BaseStream.Length; if (m_rsrcSect != null) { m_rsrcSect.VirtualSize = (uint)m_rsrcWriter.BaseStream.Length; } // start counting before sections headers // section start + section header sixe * number of sections uint headersEnd = 0x178 + 0x28 * nbSects; uint fileOffset = headersEnd; uint sectOffset = sectAlign; uint imageSize = 0; foreach (Section sect in img.Sections) { fileOffset = GetAligned(fileOffset, fileAlign); sectOffset = GetAligned(sectOffset, sectAlign); sect.PointerToRawData = new RVA(fileOffset); sect.VirtualAddress = new RVA(sectOffset); sect.SizeOfRawData = GetAligned(sect.VirtualSize, fileAlign); fileOffset += sect.SizeOfRawData; sectOffset += sect.SizeOfRawData; imageSize += GetAligned(sect.SizeOfRawData, sectAlign); } if (m_textSect.VirtualAddress.Value != 0x2000) { throw new ImageFormatException("Wrong RVA for .text section"); } if (resWriter != null) { resWriter.Patch(); } img.PEOptionalHeader.StandardFields.CodeSize = GetAligned( m_textSect.SizeOfRawData, fileAlign); img.PEOptionalHeader.StandardFields.InitializedDataSize = m_textSect.SizeOfRawData; if (m_rsrcSect != null) { img.PEOptionalHeader.StandardFields.InitializedDataSize += m_rsrcSect.SizeOfRawData; } img.PEOptionalHeader.StandardFields.BaseOfCode = m_textSect.VirtualAddress; img.PEOptionalHeader.StandardFields.BaseOfData = m_relocSect.VirtualAddress; imageSize += headersEnd; img.PEOptionalHeader.NTSpecificFields.ImageSize = GetAligned(imageSize, sectAlign); img.PEOptionalHeader.DataDirectories.BaseRelocationTable = new DataDirectory( m_relocSect.VirtualAddress, m_relocSect.VirtualSize); if (m_rsrcSect != null) { img.PEOptionalHeader.DataDirectories.ResourceTable = new DataDirectory( m_rsrcSect.VirtualAddress, (uint)m_rsrcWriter.BaseStream.Length); } if (m_kind == AssemblyKind.Dll) { img.PEFileHeader.Characteristics = ImageCharacteristics.CILOnlyDll; img.HintNameTable.RuntimeMain = HintNameTable.RuntimeMainDll; img.PEOptionalHeader.NTSpecificFields.DLLFlags = 0x400; } else { img.PEFileHeader.Characteristics = ImageCharacteristics.CILOnlyExe; img.HintNameTable.RuntimeMain = HintNameTable.RuntimeMainExe; } switch (m_kind) { case AssemblyKind.Dll: case AssemblyKind.Console: img.PEOptionalHeader.NTSpecificFields.SubSystem = SubSystem.WindowsCui; break; case AssemblyKind.Windows: img.PEOptionalHeader.NTSpecificFields.SubSystem = SubSystem.WindowsGui; break; } RVA importTable = new RVA(img.TextSection.VirtualAddress + m_mdWriter.ImportTablePosition); img.PEOptionalHeader.DataDirectories.ImportTable = new DataDirectory(importTable, 0x57); img.ImportTable.ImportLookupTable = new RVA((uint)importTable + 0x28); img.ImportLookupTable.HintNameRVA = img.ImportAddressTable.HintNameTableRVA = new RVA((uint)img.ImportTable.ImportLookupTable + 0x14); img.ImportTable.Name = new RVA((uint)img.ImportLookupTable.HintNameRVA + 0xe); }
void SetPositionToAddress(RVA address) { m_binaryReader.BaseStream.Position = m_image.ResolveVirtualAddress(address); }