public static MachLoadCommand CreateFromStream(ReadingContext SR) { long StartingStreamPosition = SR.Position; // Read the code and size (common to all commands) UInt32 CommandCode = SR.ReadUInt32(); UInt32 CommandSize = SR.ReadUInt32(); UInt32 EffectiveCommand = CommandCode & ~(1 << 31); MachLoadCommand Result; switch (EffectiveCommand) { case LC_SEGMENT: Result = new MachLoadCommandSegment(Bits.Num._32); break; case LC_SEGMENT_64: Result = new MachLoadCommandSegment(Bits.Num._64); break; case LC_SYMTAB: Result = new MachLoadCommandSymbolTable(); break; case LC_THREAD: case LC_UNIXTHREAD: Result = new MachLoadCommandMainThreadInfo(); break; case LC_DYSYMTAB: Result = new MachLoadCommandDynamicSymbolTable(); break; case LC_LOAD_DYLIB: case LC_LOAD_WEAK_DYLIB: case LC_ID_DYLIB: Result = new MachLoadCommandDylib(); break; case LC_LOAD_DYLINKER: case LC_ID_DYLINKER: Result = new MachLoadCommandDynamicLinkerName(); break; case LC_UUID: Result = new MachLoadCommandUUID(); break; case LC_CODE_SIGNATURE: Result = new MachLoadCommandCodeSignature(); break; case LC_ENCRYPTION_INFO: Result = new MachLoadCommandEncryptedSegmentInfo(); break; case LC_DYLD_INFO: Result = new MachLoadCommandDynamicLoaderInfo(); break; default: Result = new MachLoadCommandOpaque(); break; } // MSB of CommandCode is LC_REQ_DYLD or 0, indicating if the command can (theoretically) be ignored // or is critical to loading Result.StartingLoadOffset = StartingStreamPosition; Result.Command = EffectiveCommand; Result.RequiredForDynamicLoad = (CommandCode >> 31) != 0; Result.UnpackageData(SR, (int)CommandSize); SR.VerifyStreamPosition(StartingStreamPosition, CommandSize); return Result; }
public void Read(ReadingContext SR) { long ExpectedStreamPosition = 0; int NumInt = 7; // Read the header Magic = SR.ReadUInt32(); CpuType = SR.ReadUInt32(); CpuSubType = SR.ReadUInt32(); FileType = SR.ReadUInt32(); UInt32 NumCommands = SR.ReadUInt32(); UInt32 SizeOfCommands = SR.ReadUInt32(); Flags = SR.ReadUInt32(); if (Magic == MH_MAGIC_64) { Reserved64 = SR.ReadUInt32(); NumInt++; } SR.VerifyStreamPosition(ref ExpectedStreamPosition, NumInt * sizeof(UInt32)); // Read the commands Commands.Clear(); for (int LoadCommandIndex = 0; LoadCommandIndex < NumCommands; ++LoadCommandIndex) { MachLoadCommand Command = MachLoadCommand.CreateFromStream(SR); Commands.Add(Command); if (Config.bCodeSignVerbose) { Console.WriteLine(" Read command: {0}", Command.ToString()); } } SR.VerifyStreamPosition(ref ExpectedStreamPosition, SizeOfCommands); }