bool IBinaryAppender <RelocationSection.ImageBaseRelocation, ReaderWithOffsetArgs> .Attach(ref RelocationSection.ImageBaseRelocation s, uint size, ReaderWithOffsetArgs arg) { UnmanagedDataReader r = arg.Source; RelocationSection section = arg.Tag as RelocationSection; RelocationDescription desc; ushort data = 0; RelocationType type; uint count; uint offset; // validate input data: if (s.SizeOfBlock == 0 || s.VirtualAddress == 0 || section == null) { return(false); } // append data to section: count = (s.SizeOfBlock - (uint)Marshal.SizeOf(typeof(RelocationSection.ImageBaseRelocation))) / (uint)Marshal.SizeOf(typeof(ushort)); if (count > 0) { desc = new RelocationDescription(s.VirtualAddress, s.SizeOfBlock); for (uint i = 0; i < count; i++) { if (r.Read(ref data)) { type = (RelocationType)((data & 0xF000) >> 12); offset = (uint)(data & 0x0FFF); if (type == RelocationType.BasedHighAdjust) { if (r.Read(ref data)) { offset += ((uint)data) << 12; count--; } } desc.Add(new RelocationItem(type, offset)); } else { break; } } // if data is defined inside the given description: if (desc.Count > 0) { section.Add(desc); } } return(true); }
/// <summary> /// Reads given structure and appends info to given section. /// </summary> protected static bool Append <T, S, Z>(UnmanagedDataReader source, S section, Z arg) where T : struct where S : class, IBinaryAppender <T, Z> { T headerElement = new T(); // load native type: if (section != null && source.Read(ref headerElement)) { return(section.Attach(ref headerElement, source.LastReadSize, arg)); } // return failure: return(false); }
/// <summary> /// Reads given structure from specified source. /// </summary> protected S Read <T, S>(UnmanagedDataReader source, bool canStore) where T : struct where S : BinarySection, IBinaryConverter <T>, new() { T headerNativeType = new T(); // load native data: if (source.Read(ref headerNativeType)) { S section = new S(); if (section.Convert(ref headerNativeType, source.LastReadStartOffset, source.LastReadSize)) { if (canStore) { Add(section); } return(section); } } // return failure in reading: return(null); }
/// <summary> /// Loads a binary data as a Windows COFF Portable Executable. /// </summary> private void LoadExeBinary(UnmanagedDataReader s, WindowsPortableExecutableLoadArgs e) { NtHeaderSection ntSection; NtOptionalHeaderSection ntOptionalSection; DataHeaderSection dataSection; // read Win NT compatible header: ntSection = Read <NtHeaderSection.ImageNtHeader, NtHeaderSection>(s); if (ntSection == null) { return; } // detect the type of optional header: ushort magicNumber = 0; if (!s.Read(ref magicNumber)) { return; } // undo the last read: s.UndoRead(); // now parse the corresponding sections: if (magicNumber == NtOptionalHeaderSection.OptionalHeader32Magic) { ntOptionalSection = Read <NtOptionalHeaderSection.ImageOptionalHeader32, NtOptionalHeaderSection>(s); } else if (magicNumber == NtOptionalHeaderSection.OptionalHeader64Magic) { ntOptionalSection = Read <NtOptionalHeaderSection.ImageOptionalHeader64, NtOptionalHeaderSection>(s); } else { ntOptionalSection = Read <NtOptionalHeaderSection.ImageOptionalHeaderROM, NtOptionalHeaderSection>(s); } // and read specified number of other section locations: if (ntOptionalSection != null) { for (uint i = 0; i < ntOptionalSection.DataDirectoryCount; i++) { if (!Append <DataSectionDescription.ImageDataDirectory, WindowsPortableExecutable, DirectoryEntry> (s, this, (DirectoryEntry)i)) { return; } } } // read data sections: for (uint i = 0; i < ntSection.DataSectionCount; i++) { dataSection = Read <DataHeaderSection.ImageSectionHeader, DataHeaderSection>(s); if (dataSection == null) { break; } dataSections.Add(dataSection); } if (knownSections != null) { if (e.LoadExports) { // add export information section: DataSectionDescription exportSection; if (knownSections.TryGetValue(DirectoryEntry.Export, out exportSection)) { AppendExportSection(s, exportSection); } } if (e.LoadImports) { // add import information section: DataSectionDescription importSection; DataSectionDescription importBoundSection; if (knownSections.TryGetValue(DirectoryEntry.Import, out importSection)) { knownSections.TryGetValue(DirectoryEntry.BoundImport, out importBoundSection); AppendImportSection(s, importSection, importBoundSection, ntSection); } } if (e.LoadResources) { // add resources information section: DataSectionDescription resourceSection; if (knownSections.TryGetValue(DirectoryEntry.Resource, out resourceSection)) { AppendResourceSection(s, resourceSection); } } if (e.LoadBaseRelocations) { // add relocation information section: DataSectionDescription relocationSection; if (knownSections.TryGetValue(DirectoryEntry.BaseRelocationTable, out relocationSection)) { AppendRelocationSection(s, relocationSection); } } } // remove temporary data: knownSections = null; dataSections = null; }