protected override void PackageData(WritingContext SW) { // Write the segment load command SW.WriteFixedASCII(SegmentName, 16); SW.WriteUInt(VirtualAddress, AddressSize); SW.WriteUInt(VirtualSize, AddressSize); // Offset to first segment //@TODO: These file offsets and file lengths aren't correct (compared to the original MachO's) OffsetFieldU32or64 FileOffset = SW.WriteDeferredOffsetFrom(0, AddressSize); LengthFieldU32or64 FileLength = SW.WriteDeferredLength(0, AddressSize); SW.Write(MaxProt); SW.Write(InitProt); SW.Write(Sections.Count); SW.Write(Flags); // Enqueue a job to commit the file offset to the first section SW.CurrentPhase.PendingWrites.Enqueue(delegate(WritingContext Context) { FileLength.Rebase(Context.Position); FileOffset.Commit(Context); }); // Write the sections belonging to the segment foreach (MachSection Section in Sections) { Section.Write(SW); } // Enqueue a job to commit the length of data in all the sections SW.CurrentPhase.PendingWrites.Enqueue(delegate(WritingContext Context) { FileLength.Commit(Context); }); }
public void Write(WritingContext SW) { SW.WriteFixedASCII(SectionName, 16); SW.WriteFixedASCII(SegmentName, 16); SW.WriteUInt(Addr, AddressSize); SW.WriteUInt(Size, AddressSize); SW.WriteAbsoluteOffsetAndDelayedData(SectionData, 1 << (byte)LogAlignment, AddressSize); SW.Write(LogAlignment); SW.Write(RelocationOffset); SW.Write(NumRelocations); SW.Write((UInt32)Flags); SW.Write(Reserved1); SW.Write(Reserved2); if (AddressSize == Bits.Num._64) SW.Write(Reserved3); }
/// <summary> /// Patches just the file length of this segment in an existing file /// </summary> public void PatchFileLength(WritingContext SW, UInt32 NewLength) { Debug.Assert(StartingLoadOffset >= 0); if (Config.bCodeSignVerbose) { Console.WriteLine("ZZZZZZZZZZZZZZZZ"); Console.WriteLine(" Segment Length from 0x{0:X} to 0x{1:X} (delta {2})", FileSize, NewLength, (long)NewLength - (long)FileSize); Console.WriteLine("ZZZZZZZZZZZZZZZZ"); } FileSize = NewLength; long PatchOffset = StartingLoadOffset + (2 * sizeof(UInt32)); // Command, CommandLength PatchOffset += 16; // SegmentName PatchOffset += 3 * Bits.Bytes(AddressSize); // VirtualAddress, VirtualSize, FileOffset SW.PushPositionAndJump(PatchOffset); SW.WriteUInt(FileSize, AddressSize); SW.PopPosition(); }
public void Commit(WritingContext Context) { long CurrentPos = Context.Position; long Length = CurrentPos - AnchorPoint; if (AddressSize == Bits.Num._32) { Debug.Assert((Length >= UInt32.MinValue) && (Length <= UInt32.MaxValue)); } Context.PushPositionAndJump(WritePoint); Context.WriteUInt((UInt64)Length, AddressSize); Context.PopPosition(); }