private void AppendRelocationSection(UnmanagedDataReader s, DataSectionDescription relocationSection) { uint delta; uint offset = GetVirtualRelativeAddress(relocationSection.VirtualAddress, out delta); ReaderWithOffsetArgs arg; RelocationSection section; if (offset == 0) { return; } // read the info: s.Jump(offset); // add all sections: section = new RelocationSection(); arg = new ReaderWithOffsetArgs(s, offset, delta, section); while (Append <RelocationSection.ImageBaseRelocation, WindowsPortableExecutable, ReaderWithOffsetArgs> (s, this, arg)) { } // append relocation section when any data was read from file: if (section.Count > 0) { section.UpdateFileInfo(RelocationSection.DefaultName, offset, s.CurrentOffset - offset); section.UpdateVirtualInfo(offset, s.CurrentOffset - offset); Add(section); } }
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); }