protected override void PackageData(WritingContext SW) { long StartPos = SW.Position - (2 * sizeof(UInt32)); SW.Write(Version); SW.Write(Flags); // The hash offset is weird, it points to the first code page hash, not the start of the hashes array... OffsetFieldU32or64 HashOffset = SW.WriteDeferredOffsetFrom(StartPos - (BytesPerHash * SpecialSlotCount), Bits.Num._32); OffsetFieldU32or64 IdentifierStringOffset = SW.WriteDeferredOffsetFrom(StartPos, Bits.Num._32); SW.Write(SpecialSlotCount); SW.Write(CodeSlotCount); SW.Write(MainImageSignatureLimit); SW.Write(BytesPerHash); SW.Write(HashType); SW.Write(Spare1); SW.Write(LogPageSize); SW.Write(Spare2); SW.Write(ScatterCount); // Write the identifier SW.CommitDeferredField(IdentifierStringOffset); byte[] IdentifierOutput = Utilities.CreateASCIIZ(Identifier); SW.Write(IdentifierOutput); // Write the hashes SW.CommitDeferredField(HashOffset); SW.Write(Hashes); }
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) { // Magic (written in the outer) // Length (written in the outer) // SlotCount // Slot SlotTable[SlotCount] // Each slot is Key, Offset // <Slot-referenced data> //WritingContext.OffsetFieldU32or64[] Offsets = new WritingContext.OffsetFieldU32or64[Slots.Count]; long StartingPosition = SW.Position - (2 * sizeof(UInt32)); // Start a phase for writing out the superblob data SW.CreateNewPhase(); // Write the slot table, queuing up the individual slot writes SW.Write((UInt32)Slots.Count); foreach (KeyValuePair<UInt32, AbstractBlob> Slot in Slots) { SW.Write(Slot.Key); OffsetFieldU32or64 Offset = SW.WriteDeferredOffsetFrom(StartingPosition, Bits.Num._32); KeyValuePair<UInt32, AbstractBlob> LocalSlot = Slot; SW.CurrentPhase.PendingWrites.Enqueue(delegate(WritingContext Context) { if (Config.bCodeSignVerbose) { Console.WriteLine("Writing a slot. Offset={0}, SlotData={1}", Offset.WritePoint, LocalSlot.ToString()); } SW.CommitDeferredField(Offset); LocalSlot.Value.Write(Context); }); } // Force evaluation of the slots SW.ProcessEntirePhase(); }