From ac0d7f6d43dc88346f8450648251cba511f0ddff Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Tue, 24 May 2022 13:53:33 -0400 Subject: [PATCH] GP-2071: Refactoring Mach-O things --- .../app/util/bin/format/macho/MachHeader.java | 4 +- .../macho/commands/BuildVersionCommand.java | 6 +- .../commands/DyldChainedFixupsCommand.java | 2 +- .../macho/commands/DyldInfoCommand.java | 6 +- .../macho/commands/DynamicLibraryCommand.java | 6 +- .../macho/commands/DynamicLinkerCommand.java | 8 +- .../commands/DynamicSymbolTableCommand.java | 4 +- .../commands/EncryptedInformationCommand.java | 6 +- .../macho/commands/EntryPointCommand.java | 6 +- .../macho/commands/FileSetEntryCommand.java | 93 +-- .../FixedVirtualMemoryFileCommand.java | 6 +- .../macho/commands/LinkEditDataCommand.java | 8 +- .../macho/commands/LinkerOptionCommand.java | 6 +- .../format/macho/commands/LoadCommand.java | 33 +- .../macho/commands/LoadCommandFactory.java | 142 +++++ .../macho/commands/LoadCommandString.java | 4 +- .../macho/commands/LoadCommandTypes.java | 251 +++----- .../macho/commands/ObsoleteCommand.java | 2 +- .../commands/PrebindChecksumCommand.java | 6 +- .../PreboundDynamicLibraryCommand.java | 6 +- .../macho/commands/RoutinesCommand.java | 6 +- .../format/macho/commands/RunPathCommand.java | 6 +- .../format/macho/commands/SegmentCommand.java | 6 +- .../macho/commands/SourceVersionCommand.java | 6 +- .../macho/commands/SubClientCommand.java | 6 +- .../macho/commands/SubFrameworkCommand.java | 6 +- .../macho/commands/SubLibraryCommand.java | 6 +- .../macho/commands/SubUmbrellaCommand.java | 6 +- .../macho/commands/SymbolTableCommand.java | 6 +- .../macho/commands/TwoLevelHintsCommand.java | 6 +- .../commands/UnsupportedLoadCommand.java | 2 +- .../format/macho/commands/UuidCommand.java | 6 +- .../macho/commands/VersionMinCommand.java | 8 +- .../commands/dyld/AbstractDyldInfoState.java | 2 +- ...stants.java => MachoPrelinkConstants.java} | 2 +- .../{PrelinkMap.java => MachoPrelinkMap.java} | 18 +- ...inkParser.java => MachoPrelinkParser.java} | 61 +- .../macho/threadcommand/ThreadCommand.java | 6 +- .../app/util/opinion/DyldCacheLoader.java | 24 +- .../util/opinion/DyldCacheProgramBuilder.java | 25 +- .../ghidra/app/util/opinion/MachoLoader.java | 51 +- .../opinion/MachoPrelinkProgramBuilder.java | 599 ++++-------------- .../app/util/opinion/MachoPrelinkUtils.java | 44 +- .../app/util/opinion/MachoProgramBuilder.java | 409 +++++++++++- ...ystem.java => MachoPrelinkFileSystem.java} | 36 +- .../fileformats/FileFormatsPlugin.java | 4 +- 46 files changed, 977 insertions(+), 985 deletions(-) create mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandFactory.java rename Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/{PrelinkConstants.java => MachoPrelinkConstants.java} (98%) rename Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/{PrelinkMap.java => MachoPrelinkMap.java} (82%) rename Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/{PrelinkParser.java => MachoPrelinkParser.java} (82%) rename Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/prelink/{PrelinkFileSystem.java => MachoPrelinkFileSystem.java} (91%) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/MachHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/MachHeader.java index fb8e4c107c..428523dc97 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/MachHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/MachHeader.java @@ -27,7 +27,7 @@ import ghidra.util.exception.DuplicateNameException; /** * Represents a mach_header structure. * - * @see mach-o/loader.h + * @see mach-o/loader.h */ public class MachHeader implements StructConverter { private int magic; @@ -142,7 +142,7 @@ public class MachHeader implements StructConverter { long currentIndex = _commandIndex; for (int i = 0; i < nCmds; ++i) { _reader.setPointerIndex(currentIndex); - LoadCommand lc = LoadCommandTypes.getLoadCommand(_reader, this); + LoadCommand lc = LoadCommandFactory.getLoadCommand(_reader, this); _commands.add(lc); currentIndex += lc.getCommandSize(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java index 9cab240917..5383e4f445 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java @@ -30,9 +30,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a build_version_command structure. - * - * @see mach-o/loader.h + * Represents a build_version_command structure */ public class BuildVersionCommand extends LoadCommand { @@ -43,7 +41,7 @@ public class BuildVersionCommand extends LoadCommand { private BuildToolVersion[] buildToolVersions; BuildVersionCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); platform = reader.readNextInt(); minos = reader.readNextInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldChainedFixupsCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldChainedFixupsCommand.java index 06dc772aae..f4a2fba95c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldChainedFixupsCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldChainedFixupsCommand.java @@ -30,7 +30,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a LC_DYLD_CHAINED_FIXUPS command. + * Represents a dyld_chained_fixups_command structure * * @see mach-o/loader.h */ diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommand.java index 78e48c2d81..d48d3760eb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DyldInfoCommand.java @@ -29,9 +29,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a dyld_info_command structure. - * - * @see mach-o/loader.h + * Represents a dyld_info_command structure */ public class DyldInfoCommand extends LoadCommand { private int rebase_off; @@ -46,7 +44,7 @@ public class DyldInfoCommand extends LoadCommand { private int export_size; DyldInfoCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); rebase_off = reader.readNextInt(); rebase_size = reader.readNextInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLibraryCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLibraryCommand.java index 4f2661052a..d084dc58d5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLibraryCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLibraryCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a dylib_command structure. - * - * @see mach-o/loader.h + * Represents a dylib_command structure */ public class DynamicLibraryCommand extends LoadCommand { private DynamicLibrary dylib; DynamicLibraryCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); dylib = new DynamicLibrary(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLinkerCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLinkerCommand.java index 3aa38c6729..31caddc390 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLinkerCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicLinkerCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a dylinker_command structure. - * - * @see mach-o/loader.h + * Represents a dylinker_command structure */ public class DynamicLinkerCommand extends LoadCommand { private LoadCommandString name; - public DynamicLinkerCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + DynamicLinkerCommand(BinaryReader reader) throws IOException { + super(reader); name = new LoadCommandString(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java index 17fd34c5fb..47196b4827 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/DynamicSymbolTableCommand.java @@ -34,8 +34,6 @@ import ghidra.util.task.TaskMonitor; /** * Represents a dysymtab_command structure. - * - * @see mach-o/loader.h */ public class DynamicSymbolTableCommand extends LoadCommand { @@ -66,7 +64,7 @@ public class DynamicSymbolTableCommand extends LoadCommand { private List localRelocations = new ArrayList(); DynamicSymbolTableCommand(BinaryReader reader, MachHeader header) throws IOException { - initLoadCommand(reader); + super(reader); ilocalsym = reader.readNextInt(); nlocalsym = reader.readNextInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EncryptedInformationCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EncryptedInformationCommand.java index de8551b9c6..ed0c72481f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EncryptedInformationCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EncryptedInformationCommand.java @@ -29,9 +29,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents an encryption_info_command structure. - * - * @see mach-o/loader.h + * Represents an encryption_info_command structure */ public class EncryptedInformationCommand extends LoadCommand { private int cryptoff; @@ -41,7 +39,7 @@ public class EncryptedInformationCommand extends LoadCommand { private boolean is32bit; EncryptedInformationCommand(BinaryReader reader, boolean is32bit) throws IOException { - initLoadCommand(reader); + super(reader); this.is32bit = is32bit; cryptoff = reader.readNextInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EntryPointCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EntryPointCommand.java index 1eff7b9547..6e1f81f3e8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EntryPointCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/EntryPointCommand.java @@ -29,16 +29,14 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents an entry_point_command structure. - * - * @see mach-o/loader.h + * Represents an entry_point_command structure */ public class EntryPointCommand extends LoadCommand { private long entryOffset; private long stackSize; EntryPointCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); entryOffset = reader.readNextLong(); stackSize = reader.readNextLong(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FileSetEntryCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FileSetEntryCommand.java index 06a83492b1..91b6ad79cd 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FileSetEntryCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FileSetEntryCommand.java @@ -29,52 +29,63 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a kext_command - * - * @see mach-o/loader.h + * Represents a fileset_entry_command */ public class FileSetEntryCommand extends LoadCommand { private long vmaddr; private long fileoff; - private String entryName; - private long unknown; + private LoadCommandString entryId; + private int reserved; - boolean is32bit; - - public FileSetEntryCommand(BinaryReader reader, boolean is32bit) throws IOException { - initLoadCommand(reader); - this.is32bit = is32bit; - - if (is32bit) { - vmaddr = reader.readNextUnsignedInt(); - fileoff = reader.readNextUnsignedInt(); - unknown = reader.readNextUnsignedInt(); - } - else { - vmaddr = reader.readNextLong(); - fileoff = reader.readNextLong(); - unknown = reader.readNextLong(); - } - - int stringSize = this.getCommandSize() - (8 + 3 * (is32bit ? 4 : 8)); - entryName = reader.readNextAsciiString(stringSize); - } - - public String getFileSetEntryName() { - return entryName; + /** + * Creates and parses a new {@link FileSetEntryCommand} + * + * @param reader A {@link BinaryReader reader} that points to the start of the load command + * @throws IOException if an IO-related error occurs while parsing + */ + FileSetEntryCommand(BinaryReader reader) throws IOException { + super(reader); + vmaddr = reader.readNextLong(); + fileoff = reader.readNextLong(); + entryId = new LoadCommandString(reader, this); + reserved = reader.readNextInt(); } + /** + * Gets the virtual address of the DYLIB + * + * @return The virtual address of the DYLIB + */ public long getVMaddress() { return vmaddr; } + /** + * Gets the file offset of the DYLIB + * + * @return the file offset of the DYLIB + */ public long getFileOffset() { return fileoff; } - public long getUnknown() { - return unknown; + /** + * Gets the identifier of the DYLIB + * + * @return the identifier of the DYLIB + */ + public LoadCommandString getFileSetEntryId() { + return entryId; + } + + /** + * Gets the reserved field (should just be padding) + * + * @return The reserved field + */ + public int getReserved() { + return reserved; } @Override @@ -82,20 +93,10 @@ public class FileSetEntryCommand extends LoadCommand { StructureDataType struct = new StructureDataType(getCommandName(), 0); struct.add(DWORD, "cmd", null); struct.add(DWORD, "cmdsize", null); - - if (is32bit) { - struct.add(DWORD, "vmaddr", null); - struct.add(DWORD, "fileoff", null); - struct.add(DWORD, "unknown", null); - } - else { - struct.add(QWORD, "vmaddr", null); - struct.add(QWORD, "fileoff", null); - struct.add(QWORD, "unknown", null); - } - int stringSize = getCommandSize() - (8 + 3 * (is32bit ? 4 : 8)); - struct.add(new StringDataType(), stringSize, "fileSetEntryname", null); - + struct.add(QWORD, "vmaddr", null); + struct.add(QWORD, "fileoff", null); + struct.add(entryId.toDataType(), "entry_id", null); + struct.add(DWORD, "reserved", null); struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY)); return struct; } @@ -115,7 +116,7 @@ public class FileSetEntryCommand extends LoadCommand { Address addr = baseAddress.getNewAddress(getStartIndex()); DataType fileSetEntryDT = toDataType(); api.createData(addr, fileSetEntryDT); - api.setPlateComment(addr, getFileSetEntryName()); + api.setPlateComment(addr, entryId.getString()); } } catch (Exception e) { @@ -125,6 +126,6 @@ public class FileSetEntryCommand extends LoadCommand { @Override public String toString() { - return getFileSetEntryName(); + return entryId.getString(); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FixedVirtualMemoryFileCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FixedVirtualMemoryFileCommand.java index 26b0d3d03a..00a2bb6885 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FixedVirtualMemoryFileCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/FixedVirtualMemoryFileCommand.java @@ -29,16 +29,14 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a fvmfile_command structure. - * - * @see mach-o/loader.h + * Represents a fvmfile_command structure */ public class FixedVirtualMemoryFileCommand extends LoadCommand { private LoadCommandString name; private int header_addr; public FixedVirtualMemoryFileCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); } /** diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkEditDataCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkEditDataCommand.java index c5b739059a..1febe20200 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkEditDataCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkEditDataCommand.java @@ -29,16 +29,14 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a linkedit_data_command structure. - * - * @see mach-o/loader.h + * Represents a linkedit_data_command structure */ public class LinkEditDataCommand extends LoadCommand { private int dataoff; private int datasize; LinkEditDataCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); dataoff = reader.readNextInt(); datasize = reader.readNextInt(); } @@ -66,7 +64,7 @@ public class LinkEditDataCommand extends LoadCommand { Address address = baseAddress.getNewAddress(getStartIndex()); api.createData(address, toDataType()); api.setPlateComment(address, - LoadCommandTypes.getLoadCommentTypeName(getCommandType())); + LoadCommandTypes.getLoadCommandName(getCommandType())); //TODO markup actual data diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkerOptionCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkerOptionCommand.java index e292cf261e..d5b5c2e0fc 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkerOptionCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LinkerOptionCommand.java @@ -31,9 +31,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a linker_option_command structure - * - * @see mach-o/loader.h + * Represents a linker_option_command structure */ public class LinkerOptionCommand extends LoadCommand { @@ -41,7 +39,7 @@ public class LinkerOptionCommand extends LoadCommand { private List linkerOptions; LinkerOptionCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); count = reader.readNextInt(); linkerOptions = new ArrayList<>(count); long readerIndex = reader.getPointerIndex(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommand.java index bb6990be68..4ad8722f56 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommand.java @@ -28,23 +28,30 @@ import ghidra.program.model.listing.ProgramModule; import ghidra.util.task.TaskMonitor; /** - * Represents a load_command structure. + * Represents a load_command structure * - * @see mach-o/loader.h + * @see mach-o/loader.h */ public abstract class LoadCommand implements StructConverter { private long startIndex; private int cmd; private int cmdsize; - protected void initLoadCommand(BinaryReader reader) throws IOException { + /** + * Creates a new {@link LoadCommand} + * + * @param reader A {@link BinaryReader} that points to the start of the load command + * @throws IOException if there was an IO-related error + */ + public LoadCommand(BinaryReader reader) throws IOException { startIndex = reader.getPointerIndex(); cmd = reader.readNextInt(); cmdsize = reader.readNextInt(); } /** - * Returns the binary start index of this load command. + * Returns the binary start index of this load command + * * @return the binary start index of this load command */ public long getStartIndex() { @@ -52,29 +59,33 @@ public abstract class LoadCommand implements StructConverter { } /** - * Type of load command - * @return type of load command + * Gets the type of this load command + * + * @return The type of this load command */ public int getCommandType() { return cmd; } /** - * Total size of command in bytes - * @return total size of command in bytes + * Gets the size of this load command in bytes + * + * @return The size of this load command in bytes */ public int getCommandSize() { return cmdsize; } /** - * Returns the name of this command. - * @return the name of this command + * Gets the name of this load command + * + * @return The name of this load command */ public abstract String getCommandName(); /** - * Mark-up the program with the data structures for this load command. + * Marks-up the program with the data structures for this load command + * * @param header the mach header * @param api the flat program api * @param baseAddress the base address to apply the mark-up diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandFactory.java new file mode 100644 index 0000000000..605b0f9719 --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandFactory.java @@ -0,0 +1,142 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.bin.format.macho.commands; + +import static ghidra.app.util.bin.format.macho.commands.LoadCommandTypes.*; + +import java.io.IOException; + +import ghidra.app.util.bin.BinaryReader; +import ghidra.app.util.bin.format.macho.MachException; +import ghidra.app.util.bin.format.macho.MachHeader; +import ghidra.app.util.bin.format.macho.threadcommand.ThreadCommand; +import ghidra.util.Msg; + +/** + * A factory used to create {@link LoadCommand}s + */ +public class LoadCommandFactory { + + /** + * Creates a {@link LoadCommand} + * + * @param reader A {@link BinaryReader} positioned at the start of the load command to create + * @param header The {@link MachHeader} that contains the load command to create + * @return A {@link LoadCommand} + * @throws IOException if there was an IO-related error + * @throws MachException if there was a problem parsing the load command + */ + public static LoadCommand getLoadCommand(BinaryReader reader, MachHeader header) + throws IOException, MachException { + int type = reader.peekNextInt(); + switch (type) { + case LC_SEGMENT: + return new SegmentCommand(reader, header.is32bit()); + case LC_SYMTAB: + return new SymbolTableCommand(reader, header); + case LC_SYMSEG: + return new SymbolCommand(reader); + case LC_THREAD: + case LC_UNIXTHREAD: + return new ThreadCommand(reader, header); + case LC_LOADFVMLIB: + case LC_IDFVMLIB: + return new FixedVirtualMemorySharedLibraryCommand(reader); + case LC_IDENT: + return new IdentCommand(reader); + case LC_FVMFILE: + return new FixedVirtualMemoryFileCommand(reader); + case LC_PREPAGE: + return new UnsupportedLoadCommand(reader, type); + case LC_DYSYMTAB: + return new DynamicSymbolTableCommand(reader, header); + case LC_LOAD_DYLIB: + case LC_ID_DYLIB: + case LC_LOAD_UPWARD_DYLIB: + case LC_DYLD_ENVIRONMENT: + return new DynamicLibraryCommand(reader); + case LC_LOAD_DYLINKER: + case LC_ID_DYLINKER: + return new DynamicLinkerCommand(reader); + case LC_PREBOUND_DYLIB: + return new PreboundDynamicLibraryCommand(reader); + case LC_ROUTINES: + return new RoutinesCommand(reader, header.is32bit()); + case LC_SUB_FRAMEWORK: + return new SubFrameworkCommand(reader); + case LC_SUB_UMBRELLA: + return new SubUmbrellaCommand(reader); + case LC_SUB_CLIENT: + return new SubClientCommand(reader); + case LC_SUB_LIBRARY: + return new SubLibraryCommand(reader); + case LC_TWOLEVEL_HINTS: + return new TwoLevelHintsCommand(reader); + case LC_PREBIND_CKSUM: + return new PrebindChecksumCommand(reader); + case LC_LOAD_WEAK_DYLIB: + return new DynamicLibraryCommand(reader); + case LC_SEGMENT_64: + return new SegmentCommand(reader, header.is32bit()); + case LC_ROUTINES_64: + return new RoutinesCommand(reader, header.is32bit()); + case LC_UUID: + return new UuidCommand(reader); + case LC_RPATH: + return new RunPathCommand(reader); + case LC_CODE_SIGNATURE: + case LC_SEGMENT_SPLIT_INFO: + case LC_DATA_IN_CODE: + case LC_OPTIMIZATION_HINT: + case LC_DYLIB_CODE_SIGN_DRS: + return new LinkEditDataCommand(reader); + case LC_REEXPORT_DYLIB: + return new DynamicLibraryCommand(reader); + case LC_ENCRYPTION_INFO: + case LC_ENCRYPTION_INFO_64: + return new EncryptedInformationCommand(reader, header.is32bit()); + case LC_DYLD_INFO: + case LC_DYLD_INFO_ONLY: + return new DyldInfoCommand(reader); + case LC_VERSION_MIN_MACOSX: + case LC_VERSION_MIN_IPHONEOS: + case LC_VERSION_MIN_TVOS: + case LC_VERSION_MIN_WATCHOS: + return new VersionMinCommand(reader); + case LC_FUNCTION_STARTS: + return new FunctionStartsCommand(reader); + case LC_MAIN: + return new EntryPointCommand(reader); + case LC_SOURCE_VERSION: + return new SourceVersionCommand(reader); + case LC_LAZY_LOAD_DYLIB: + return new DynamicLibraryCommand(reader); + case LC_LINKER_OPTIONS: + return new LinkerOptionCommand(reader); + case LC_BUILD_VERSION: + return new BuildVersionCommand(reader); + case LC_DYLD_EXPORTS_TRIE: + return new LinkEditDataCommand(reader); + case LC_DYLD_CHAINED_FIXUPS: + return new DyldChainedFixupsCommand(reader); + case LC_FILESET_ENTRY: + return new FileSetEntryCommand(reader); + default: + Msg.warn(header, "Unsupported load command " + Integer.toHexString(type)); + return new UnsupportedLoadCommand(reader, type); + } + } +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandString.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandString.java index 80ed7f5f63..7025f492e4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandString.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandString.java @@ -24,9 +24,9 @@ import ghidra.program.model.data.*; import ghidra.util.exception.DuplicateNameException; /** - * Represents an lc_str union. + * Represents an lc_str union * - * @see mach-o/loader.h + * @see LoadCommand */ public class LoadCommandString implements StructConverter { private int offset; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandTypes.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandTypes.java index bca6384ef6..9763616400 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandTypes.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/LoadCommandTypes.java @@ -16,296 +16,209 @@ */ package ghidra.app.util.bin.format.macho.commands; -import java.io.IOException; import java.lang.reflect.Field; -import ghidra.app.util.bin.BinaryReader; -import ghidra.app.util.bin.format.macho.MachException; -import ghidra.app.util.bin.format.macho.MachHeader; -import ghidra.app.util.bin.format.macho.threadcommand.ThreadCommand; -import ghidra.util.Msg; - /** - * Constants for the cmd field of all load commands, the type + * {@link LoadCommand} types */ public final class LoadCommandTypes { - public static LoadCommand getLoadCommand(BinaryReader reader, MachHeader header) - throws IOException, MachException { - int type = reader.peekNextInt(); - switch (type) { - case LC_SEGMENT: { - return new SegmentCommand(reader, header.is32bit()); - } - case LC_SYMTAB: { - return new SymbolTableCommand(reader, header); - } - case LC_SYMSEG: { - return new SymbolCommand(reader); - } - case LC_THREAD: - case LC_UNIXTHREAD: { - return new ThreadCommand(reader, header); - } - case LC_LOADFVMLIB: - case LC_IDFVMLIB: { - return new FixedVirtualMemorySharedLibraryCommand(reader); - } - case LC_IDENT: { - return new IdentCommand(reader); - } - case LC_FVMFILE: { - return new FixedVirtualMemoryFileCommand(reader); - } - case LC_PREPAGE: { - return new UnsupportedLoadCommand(reader, type); - } - case LC_DYSYMTAB: { - return new DynamicSymbolTableCommand(reader, header); - } - case LC_LOAD_DYLIB: - case LC_ID_DYLIB: - case LC_LOAD_UPWARD_DYLIB: - case LC_DYLD_ENVIRONMENT: { - return new DynamicLibraryCommand(reader); - } - case LC_LOAD_DYLINKER: - case LC_ID_DYLINKER: { - return new DynamicLinkerCommand(reader); - } - case LC_PREBOUND_DYLIB: { - return new PreboundDynamicLibraryCommand(reader); - } - case LC_ROUTINES: { - return new RoutinesCommand(reader, header.is32bit()); - } - case LC_SUB_FRAMEWORK: { - return new SubFrameworkCommand(reader); - } - case LC_SUB_UMBRELLA: { - return new SubUmbrellaCommand(reader); - } - case LC_SUB_CLIENT: { - return new SubClientCommand(reader); - } - case LC_SUB_LIBRARY: { - return new SubLibraryCommand(reader); - } - case LC_TWOLEVEL_HINTS: { - return new TwoLevelHintsCommand(reader); - } - case LC_PREBIND_CKSUM: { - return new PrebindChecksumCommand(reader); - } - case LC_LOAD_WEAK_DYLIB: { - return new DynamicLibraryCommand(reader); - } - case LC_SEGMENT_64: { - return new SegmentCommand(reader, header.is32bit()); - } - case LC_ROUTINES_64: { - return new RoutinesCommand(reader, header.is32bit()); - } - case LC_UUID: { - return new UuidCommand(reader); - } - case LC_RPATH: { - return new RunPathCommand(reader); - } - case LC_CODE_SIGNATURE: - case LC_SEGMENT_SPLIT_INFO: - case LC_DATA_IN_CODE: - case LC_OPTIMIZATION_HINT: - case LC_DYLIB_CODE_SIGN_DRS: { - return new LinkEditDataCommand(reader); - } - case LC_REEXPORT_DYLIB: { - return new DynamicLibraryCommand(reader); - } - case LC_ENCRYPTION_INFO: - case LC_ENCRYPTION_INFO_64: { - return new EncryptedInformationCommand(reader, header.is32bit()); - } - case LC_DYLD_INFO: - case LC_DYLD_INFO_ONLY: { - return new DyldInfoCommand(reader); - } - case LC_VERSION_MIN_MACOSX: - case LC_VERSION_MIN_IPHONEOS: - case LC_VERSION_MIN_TVOS: - case LC_VERSION_MIN_WATCHOS: { - return new VersionMinCommand(reader); - } - case LC_FUNCTION_STARTS: { - return new FunctionStartsCommand(reader); - } - case LC_MAIN: { - return new EntryPointCommand(reader); - } - case LC_SOURCE_VERSION: { - return new SourceVersionCommand(reader); - } - case LC_LAZY_LOAD_DYLIB: { - return new DynamicLibraryCommand(reader); - } - case LC_BUILD_VERSION: { - return new BuildVersionCommand(reader); - } - case LC_LINKER_OPTIONS: { - return new LinkerOptionCommand(reader); - } - - case LC_DYLD_EXPORTS_TRIE: - return new LinkEditDataCommand(reader); - - case LC_DYLD_CHAINED_FIXUPS: - return new DyldChainedFixupsCommand(reader); - - case LC_FILESET_ENTRY: - return new FileSetEntryCommand(reader, header.is32bit()); - - default: { - Msg.warn(header, "Unsupported load command " + Integer.toHexString(type)); - return new UnsupportedLoadCommand(reader, type); - } - } - } - //@formatter:off - + /** + * After MacOS X 10.1 when a new load command is added that is required to be + * understood by the dynamic linker for the image to execute properly the + * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic + * linker sees such a load command it it does not understand will issue a + * "unknown load command required for execution" error and refuse to use the + * image. Other load commands without this bit that are not understood will + * simply be ignored. + */ public final static int LC_REQ_DYLD = 0x80000000; /** segment of this file to be mapped */ public final static int LC_SEGMENT = 0x1; + /** link-edit stab symbol table info */ public final static int LC_SYMTAB = 0x2; + /** link-edit gdb symbol table info (obsolete) */ public final static int LC_SYMSEG = 0x3; + /** thread */ public final static int LC_THREAD = 0x4; + /** unix thread (includes a stack) */ public final static int LC_UNIXTHREAD = 0x5; + /** load a specified fixed VM shared library */ public final static int LC_LOADFVMLIB = 0x6; + /** fixed VM shared library identification */ public final static int LC_IDFVMLIB = 0x7; + /** object identification info (obsolete) */ public final static int LC_IDENT = 0x8; + /** fixed VM file inclusion (internal use) */ public final static int LC_FVMFILE = 0x9; + /** prepage command (internal use) */ public final static int LC_PREPAGE = 0xa; + /** dynamic link-edit symbol table info */ public final static int LC_DYSYMTAB = 0xb; + /** load a dynamically linked shared library */ public final static int LC_LOAD_DYLIB = 0xc; + /** dynamically linked shared lib ident */ public final static int LC_ID_DYLIB = 0xd; + /** load a dynamic linker */ public final static int LC_LOAD_DYLINKER = 0xe; + /** dynamic linker identification */ public final static int LC_ID_DYLINKER = 0xf; + /** modules prebound for a dynamically linked shared library */ public final static int LC_PREBOUND_DYLIB = 0x10; + /** image routines */ public final static int LC_ROUTINES = 0x11; + /** sub framework */ public final static int LC_SUB_FRAMEWORK = 0x12; + /** sub umbrella */ public final static int LC_SUB_UMBRELLA = 0x13; + /** sub client */ public final static int LC_SUB_CLIENT = 0x14; + /** sub library */ public final static int LC_SUB_LIBRARY = 0x15; + /** two-level namespace lookup hints */ public final static int LC_TWOLEVEL_HINTS = 0x16; + /** prebind checksum */ public final static int LC_PREBIND_CKSUM = 0x17; + /** load a dynamically linked shared library that is allowed to be missing (all symbols are weak imported) */ public final static int LC_LOAD_WEAK_DYLIB = 0x18 | LC_REQ_DYLD; + /** 64-bit segment of this file to be mapped */ public final static int LC_SEGMENT_64 = 0x19; + /** 64-bit image routines */ public final static int LC_ROUTINES_64 = 0x1a; + /** specifies the 128 bit UUID for an image */ public final static int LC_UUID = 0x1b; + /** Run path additions */ public final static int LC_RPATH = 0x1c | LC_REQ_DYLD; + /** local of code signature */ public final static int LC_CODE_SIGNATURE = 0x1d; + /** local of info to split segments */ public final static int LC_SEGMENT_SPLIT_INFO = 0x1e; + /** load and re-export dylib */ public final static int LC_REEXPORT_DYLIB = 0x1f | LC_REQ_DYLD; + /** Delay load of dylib until first use */ public final static int LC_LAZY_LOAD_DYLIB = 0x20; + /** encrypted segment information */ public final static int LC_ENCRYPTION_INFO = 0x21; + /** compressed dyld information */ public final static int LC_DYLD_INFO = 0x22; + /** compressed dyld information only */ public final static int LC_DYLD_INFO_ONLY = 0x22 | LC_REQ_DYLD; + /** Load upward dylib */ public final static int LC_LOAD_UPWARD_DYLIB = 0x23 | LC_REQ_DYLD; + /** Build for MacOSX min OS version */ public final static int LC_VERSION_MIN_MACOSX = 0x24; + /** Build for iPhoneOS min OS version */ public final static int LC_VERSION_MIN_IPHONEOS = 0x25; + /** Compressed table of function start addresses */ public final static int LC_FUNCTION_STARTS = 0x26; + /** String for DYLD to treat environment variable */ public final static int LC_DYLD_ENVIRONMENT = 0x27; + /** Replacement for LC_UNIXTHREAD */ public final static int LC_MAIN = 0x28 | LC_REQ_DYLD; + /** Table of non-instructions in __text */ public final static int LC_DATA_IN_CODE = 0x29; + /** Source version used to build binary */ public final static int LC_SOURCE_VERSION = 0x2a; + /** Code signing DRs copied from linked dylibs */ public final static int LC_DYLIB_CODE_SIGN_DRS = 0x2b; + /** 64-bit encrypted segment information */ public final static int LC_ENCRYPTION_INFO_64 = 0x2c; + /** Linker options in MH_OBJECT files */ public final static int LC_LINKER_OPTIONS = 0x2d; + /** Optimization hints in MH_OBJECT files */ public final static int LC_OPTIMIZATION_HINT = 0x2e; + /** Build for AppleTV min OS version */ public final static int LC_VERSION_MIN_TVOS = 0x2f; + /** Build for Watch min OS version */ public final static int LC_VERSION_MIN_WATCHOS = 0x30; + /** Arbitrary data included within a Mach-O file */ public final static int LC_NOTE = 0x31; + /** Build for platform min OS version */ public final static int LC_BUILD_VERSION = 0x32; - /** used with LinkeditDataCommand, payload is trie **/ + + /** Used with linkedit_data_command, payload is trie **/ public final static int LC_DYLD_EXPORTS_TRIE = 0x33 | LC_REQ_DYLD; - /** used with LinkeditDataCommand **/ + + /** Used with linkedit_data_command **/ public final static int LC_DYLD_CHAINED_FIXUPS = 0x34 | LC_REQ_DYLD; - /** used with fileset_entry_command **/ + + /** Used with fileset_entry_command **/ public final static int LC_FILESET_ENTRY = 0x35 | LC_REQ_DYLD; //@formatter:on /** - * Returns a string for the given load command type. - * @param type the load command type - * @return a string for the given load command type + * Gets the name of the given load command type + * + * @param type The load command type + * @return The name of the given load command type */ - public final static String getLoadCommentTypeName(int type) { - Field[] fields = LoadCommandTypes.class.getDeclaredFields(); - for (Field field : fields) { - if (field.getName().startsWith("LC_")) { - try { - Integer value = (Integer) field.get(null); - if (type == value) { - return field.getName(); - } - } - catch (Exception e) { - break; + public final static String getLoadCommandName(int type) { + for (Field field : LoadCommandTypes.class.getDeclaredFields()) { + if (!field.getName().startsWith("LC_")) { + continue; + } + try { + Integer value = (Integer) field.get(null); + if (type == value) { + return field.getName(); } } + catch (Exception e) { + break; + } } return "Unknown load command type: " + Integer.toHexString(type); } - } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/ObsoleteCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/ObsoleteCommand.java index 1cb5df8fea..208987502d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/ObsoleteCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/ObsoleteCommand.java @@ -30,7 +30,7 @@ import ghidra.util.task.TaskMonitor; public abstract class ObsoleteCommand extends LoadCommand { public ObsoleteCommand(BinaryReader reader) throws IOException, MachException { - initLoadCommand(reader); + super(reader); throw new ObsoleteException(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PrebindChecksumCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PrebindChecksumCommand.java index ba5e669409..06824b88f2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PrebindChecksumCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PrebindChecksumCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a prebind_cksum_command structure. - * - * @see mach-o/loader.h + * Represents a prebind_cksum_command structure */ public class PrebindChecksumCommand extends LoadCommand { private int cksum; PrebindChecksumCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); cksum = reader.readNextInt(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PreboundDynamicLibraryCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PreboundDynamicLibraryCommand.java index dce809ed3b..6809f99a75 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PreboundDynamicLibraryCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/PreboundDynamicLibraryCommand.java @@ -29,9 +29,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a prebound_dylib_command structure. - * - * @see mach-o/loader.h + * Represents a prebound_dylib_command structure */ public class PreboundDynamicLibraryCommand extends LoadCommand { private LoadCommandString name; @@ -39,7 +37,7 @@ public class PreboundDynamicLibraryCommand extends LoadCommand { private LoadCommandString linkedModules; PreboundDynamicLibraryCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); name = new LoadCommandString(reader, this); nmodules = reader.readNextInt(); linkedModules = new LoadCommandString(reader, this); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RoutinesCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RoutinesCommand.java index 19051da5d7..8ea66e8e81 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RoutinesCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RoutinesCommand.java @@ -29,9 +29,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a routines_command and routines_command_64 structure. - * - * @see mach-o/loader.h + * Represents a routines_command and routines_command_64 structure */ public class RoutinesCommand extends LoadCommand { private long init_address; @@ -46,7 +44,7 @@ public class RoutinesCommand extends LoadCommand { private boolean is32bit; RoutinesCommand(BinaryReader reader, boolean is32bit) throws IOException { - initLoadCommand(reader); + super(reader); this.is32bit = is32bit; if (is32bit) { init_address = reader.readNextUnsignedInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RunPathCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RunPathCommand.java index d2594913a9..97abb38dac 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RunPathCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/RunPathCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a rpath_command structure. - * - * @see mach-o/loader.h + * Represents a rpath_command structure */ public class RunPathCommand extends LoadCommand { private LoadCommandString path; RunPathCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); path = new LoadCommandString(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SegmentCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SegmentCommand.java index 441e3cf2cb..4579ab9e72 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SegmentCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SegmentCommand.java @@ -31,9 +31,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a segment_command and segment_command_64 structure. - * - * @see mach-o/loader.h + * Represents a segment_command and segment_command_64 structure */ public class SegmentCommand extends LoadCommand { @@ -51,7 +49,7 @@ public class SegmentCommand extends LoadCommand { private List
sections = new ArrayList
(); public SegmentCommand(BinaryReader reader, boolean is32bit) throws IOException { - initLoadCommand(reader); + super(reader); this.is32bit = is32bit; segname = reader.readNextAsciiString(MachConstants.NAME_LENGTH); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SourceVersionCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SourceVersionCommand.java index 617e6dd28f..be1584a6c4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SourceVersionCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SourceVersionCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a source_version_command structure. - * - * @see mach-o/loader.h + * Represents a source_version_command structure */ public class SourceVersionCommand extends LoadCommand { private long version; SourceVersionCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); version = reader.readNextLong(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubClientCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubClientCommand.java index 9ff47589f4..c7ed9fc987 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubClientCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubClientCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a sub_client_command structure. - * - * @see mach-o/loader.h + * Represents a sub_client_command structure */ public class SubClientCommand extends LoadCommand { private LoadCommandString client; SubClientCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); client = new LoadCommandString(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubFrameworkCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubFrameworkCommand.java index f3fd5919cb..ba803f852f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubFrameworkCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubFrameworkCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a sub_framework_command structure. - * - * @see mach-o/loader.h + * Represents a sub_framework_command structure */ public class SubFrameworkCommand extends LoadCommand { private LoadCommandString umbrella; SubFrameworkCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); umbrella = new LoadCommandString(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubLibraryCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubLibraryCommand.java index adb3c0cfbc..08b552a56b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubLibraryCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubLibraryCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a sub_library_command structure. - * - * @see mach-o/loader.h + * Represents a sub_library_command structure */ public class SubLibraryCommand extends LoadCommand { private LoadCommandString sub_library; SubLibraryCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); sub_library = new LoadCommandString(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubUmbrellaCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubUmbrellaCommand.java index 3f96b3f4c3..f54a03834f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubUmbrellaCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SubUmbrellaCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a sub_umbrella_command structure. - * - * @see mach-o/loader.h + * Represents a sub_umbrella_command structure */ public class SubUmbrellaCommand extends LoadCommand { private LoadCommandString sub_umbrella; SubUmbrellaCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); sub_umbrella = new LoadCommandString(reader, this); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java index f6fe83c37b..c007c5706d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SymbolTableCommand.java @@ -36,9 +36,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a symtab_command structure. - * - * @see mach-o/loader.h + * Represents a symtab_command structure */ public class SymbolTableCommand extends LoadCommand { private int symoff; @@ -49,7 +47,7 @@ public class SymbolTableCommand extends LoadCommand { private List symbols = new ArrayList(); public SymbolTableCommand(BinaryReader reader, MachHeader header) throws IOException { - initLoadCommand(reader); + super(reader); symoff = reader.readNextInt(); nsyms = reader.readNextInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/TwoLevelHintsCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/TwoLevelHintsCommand.java index 2eddd99937..23d67f2a4f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/TwoLevelHintsCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/TwoLevelHintsCommand.java @@ -32,9 +32,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a twolevel_hints_command structure. - * - * @see mach-o/loader.h + * Represents a twolevel_hints_command structure */ public class TwoLevelHintsCommand extends LoadCommand { private int offset; @@ -42,7 +40,7 @@ public class TwoLevelHintsCommand extends LoadCommand { private List hints = new ArrayList(); TwoLevelHintsCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); offset = reader.readNextInt(); nhints = reader.readNextInt(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UnsupportedLoadCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UnsupportedLoadCommand.java index daad2680f8..e53e23f786 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UnsupportedLoadCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UnsupportedLoadCommand.java @@ -32,7 +32,7 @@ public class UnsupportedLoadCommand extends LoadCommand { private int type; UnsupportedLoadCommand(BinaryReader reader, int type) throws IOException { - initLoadCommand(reader); + super(reader); this.type = type; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UuidCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UuidCommand.java index 97b559393c..bcd46deaee 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UuidCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/UuidCommand.java @@ -29,15 +29,13 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a uuid_command structure. - * - * @see mach-o/loader.h + * Represents a uuid_command structure */ public class UuidCommand extends LoadCommand { private byte[] uuid; UuidCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); uuid = reader.readNextByteArray(16); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/VersionMinCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/VersionMinCommand.java index c309b69e1a..1f09e7d5d0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/VersionMinCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/VersionMinCommand.java @@ -29,9 +29,7 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a version_min_command structure. - * - * @see mach-o/loader.h + * Represents a version_min_command structure */ public class VersionMinCommand extends LoadCommand { @@ -39,7 +37,7 @@ public class VersionMinCommand extends LoadCommand { private int sdk; VersionMinCommand(BinaryReader reader) throws IOException { - initLoadCommand(reader); + super(reader); version = reader.readNextInt(); sdk = reader.readNextInt(); @@ -61,7 +59,7 @@ public class VersionMinCommand extends LoadCommand { Address addr = baseAddress.getNewAddress(getStartIndex()); api.createData(addr, toDataType()); api.setPlateComment(addr, - LoadCommandTypes.getLoadCommentTypeName(getCommandType())); + LoadCommandTypes.getLoadCommandName(getCommandType())); } } catch (Exception e) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/dyld/AbstractDyldInfoState.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/dyld/AbstractDyldInfoState.java index dd50d7e023..d5c45eb746 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/dyld/AbstractDyldInfoState.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/dyld/AbstractDyldInfoState.java @@ -147,7 +147,7 @@ abstract public class AbstractDyldInfoState { header.getLoadCommands(FileSetEntryCommand.class); for (FileSetEntryCommand fileSetEntryCommand : fileSetEntries) { if (fileSetEntryCommand.getFileOffset() == segment.getFileOffset()) { - return fileSetEntryCommand.getFileSetEntryName(); + return fileSetEntryCommand.getFileSetEntryId().getString(); } } return segment.getSegmentName(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkConstants.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkConstants.java similarity index 98% rename from Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkConstants.java rename to Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkConstants.java index 66db904991..5153b7bd52 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkConstants.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkConstants.java @@ -20,7 +20,7 @@ package ghidra.app.util.bin.format.macho.prelink; * http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/libkern/libkern/prelink.h * */ -public final class PrelinkConstants { +public final class MachoPrelinkConstants { public static final String TITLE = "iOS Prelink"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkMap.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkMap.java similarity index 82% rename from Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkMap.java rename to Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkMap.java index 5055df321d..c9ed74e59a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkMap.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkMap.java @@ -17,7 +17,7 @@ package ghidra.app.util.bin.format.macho.prelink; import java.util.*; -public class PrelinkMap { +public class MachoPrelinkMap { private Map map = new HashMap(); @@ -30,12 +30,12 @@ public class PrelinkMap { public void put( String key, boolean value ) { map.put( key, value ); } - public void put( String key, PrelinkMap value ) { + public void put( String key, MachoPrelinkMap value ) { map.put( key, value ); } public String getPrelinkBundlePath() { - Object value = map.get( PrelinkConstants.kPrelinkBundlePathKey ); + Object value = map.get( MachoPrelinkConstants.kPrelinkBundlePathKey ); if ( value instanceof String ) { return (String)value; } @@ -43,7 +43,7 @@ public class PrelinkMap { } public String getPrelinkUUID() { - Object value = map.get( PrelinkConstants.kPrelinkInterfaceUUIDKey ); + Object value = map.get( MachoPrelinkConstants.kPrelinkInterfaceUUIDKey ); if ( value instanceof String ) { return (String)value; } @@ -51,7 +51,7 @@ public class PrelinkMap { } public long getPrelinkKmodInfo() { - Object value = map.get( PrelinkConstants.kPrelinkKmodInfoKey ); + Object value = map.get( MachoPrelinkConstants.kPrelinkKmodInfoKey ); if ( value instanceof Long ) { return (Long)value; } @@ -62,7 +62,7 @@ public class PrelinkMap { } public long getPrelinkExecutable() { - Object value = map.get( PrelinkConstants.kPrelinkExecutableKey ); + Object value = map.get( MachoPrelinkConstants.kPrelinkExecutableKey ); if ( value instanceof Long ) { return (Long)value; } @@ -73,7 +73,7 @@ public class PrelinkMap { } public long getPrelinkExecutableSize() { - Object value = map.get( PrelinkConstants.kPrelinkExecutableSizeKey ); + Object value = map.get( MachoPrelinkConstants.kPrelinkExecutableSizeKey ); if ( value instanceof Long ) { return (Long)value; } @@ -84,7 +84,7 @@ public class PrelinkMap { } public long getPrelinkExecutableLoadAddr() { - Object value = map.get( PrelinkConstants.kPrelinkExecutableLoadKey ); + Object value = map.get( MachoPrelinkConstants.kPrelinkExecutableLoadKey ); if ( value instanceof Long ) { return (Long)value; } @@ -95,7 +95,7 @@ public class PrelinkMap { } public long getPrelinkModuleIndex() { - Object value = map.get(PrelinkConstants.kPrelinkModuleIndexKey); + Object value = map.get(MachoPrelinkConstants.kPrelinkModuleIndexKey); if (value instanceof Long) { return (Long) value; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkParser.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkParser.java similarity index 82% rename from Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkParser.java rename to Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkParser.java index f9b38df283..01e5e716b9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/PrelinkParser.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/prelink/MachoPrelinkParser.java @@ -26,11 +26,10 @@ import ghidra.app.util.bin.format.macho.MachHeader; import ghidra.app.util.bin.format.macho.Section; import ghidra.app.util.bin.format.macho.commands.SegmentCommand; import ghidra.util.NumericUtilities; -import ghidra.util.SystemUtilities; import ghidra.util.task.TaskMonitor; import ghidra.util.xml.XmlUtilities; -public class PrelinkParser { +public class MachoPrelinkParser { private static final String TAG_DATA = "data"; private static final String TAG_FALSE = "false"; @@ -47,12 +46,12 @@ public class PrelinkParser { private MachHeader mainHeader; private ByteProvider provider; - public PrelinkParser(MachHeader mainHeader, ByteProvider provider) { + public MachoPrelinkParser(MachHeader mainHeader, ByteProvider provider) { this.mainHeader = mainHeader; this.provider = provider; } - public List parse(TaskMonitor monitor) + public List parse(TaskMonitor monitor) throws IOException, JDOMException, NoPreLinkSectionException { InputStream inputStream = findPrelinkInputStream(); @@ -62,7 +61,7 @@ public class PrelinkParser { Document doc = sax.build(inputStream); Element root = doc.getRootElement(); - List list = new ArrayList(); + List list = new ArrayList(); if (root.getName().equals(TAG_ARRAY)) { // iOS version before 4.x process(root.getChildren(), list, monitor); @@ -87,7 +86,7 @@ public class PrelinkParser { return list; } - private void processTopDict(TaskMonitor monitor, List list, + private void processTopDict(TaskMonitor monitor, List list, Element dictRootElement) { Iterator iterator = dictRootElement.getChildren().iterator(); while (iterator.hasNext()) { @@ -101,22 +100,22 @@ public class PrelinkParser { } } - private void processKey(TaskMonitor monitor, List list, Iterator iterator, + private void processKey(TaskMonitor monitor, List list, Iterator iterator, Element element) { String value = element.getValue(); - if (value.equals(PrelinkConstants.kPrelinkPersonalitiesKey)) { + if (value.equals(MachoPrelinkConstants.kPrelinkPersonalitiesKey)) { Element arrayElement = (Element) iterator.next(); if (arrayElement.getChildren().size() == 0) { //should be empty... } } - else if (value.equals(PrelinkConstants.kPrelinkInfoDictionaryKey)) { + else if (value.equals(MachoPrelinkConstants.kPrelinkInfoDictionaryKey)) { Element arrayElement = (Element) iterator.next(); process(arrayElement.getChildren(), list, monitor); } } - private void process(List children, List list, TaskMonitor monitor) { + private void process(List children, List list, TaskMonitor monitor) { monitor.setMessage("Processing prelink information..."); for (int i = 0; i < children.size(); ++i) { @@ -125,14 +124,14 @@ public class PrelinkParser { } Element element = (Element) children.get(i); if (element.getName().equals(TAG_DICT)) { - PrelinkMap map = processElement(element, monitor); + MachoPrelinkMap map = processElement(element, monitor); list.add(map); } } } - private PrelinkMap processElement(Element parentElement, TaskMonitor monitor) { - PrelinkMap map = new PrelinkMap(); + private MachoPrelinkMap processElement(Element parentElement, TaskMonitor monitor) { + MachoPrelinkMap map = new MachoPrelinkMap(); Iterator iterator = parentElement.getChildren().iterator(); while (iterator.hasNext()) { if (monitor.isCancelled()) { @@ -150,7 +149,7 @@ public class PrelinkParser { return map; } - private String processValue(Element keyElement, Element valueElement, PrelinkMap map, + private String processValue(Element keyElement, Element valueElement, MachoPrelinkMap map, TaskMonitor monitor) { String key = keyElement.getValue(); if (valueElement.getName().equals(TAG_STRING)) { @@ -172,7 +171,7 @@ public class PrelinkParser { return valueElement.getValue(); } else if (valueElement.getName().equals(TAG_DICT)) { - PrelinkMap dictMap = processElement(valueElement, monitor); + MachoPrelinkMap dictMap = processElement(valueElement, monitor); map.put(key, dictMap); return dictMap.toString(); } @@ -187,7 +186,7 @@ public class PrelinkParser { } } - private String processString(PrelinkMap map, String key, Element valueElement) { + private String processString(MachoPrelinkMap map, String key, Element valueElement) { String value = valueElement.getValue(); String id = valueElement.getAttributeValue("ID"); String idref = valueElement.getAttributeValue("IDREF"); @@ -204,7 +203,7 @@ public class PrelinkParser { return value; } - private String processInteger(PrelinkMap map, String key, Element valueElement) { + private String processInteger(MachoPrelinkMap map, String key, Element valueElement) { String value = valueElement.getValue(); String id = valueElement.getAttributeValue("ID"); String idref = valueElement.getAttributeValue("IDREF"); @@ -214,6 +213,7 @@ public class PrelinkParser { numericValue = NumericUtilities.parseHexLong(value); } catch (Exception e) { + // do nothing } if (id != null) { @@ -229,7 +229,7 @@ public class PrelinkParser { return value; } - private String processArray(Element arrayElement, PrelinkMap map, TaskMonitor monitor) { + private String processArray(Element arrayElement, MachoPrelinkMap map, TaskMonitor monitor) { if (!arrayElement.getName().equals(TAG_ARRAY)) { throw new RuntimeException("not an array element"); } @@ -257,9 +257,9 @@ public class PrelinkParser { InputStream prelinkInputStream = null; List segments = mainHeader.getLoadCommands(SegmentCommand.class); for (SegmentCommand segment : segments) { - if (segment.getSegmentName().equals(PrelinkConstants.kPrelinkSegment_iOS_1x) || - segment.getSegmentName().equals(PrelinkConstants.kPrelinkInfoSegment)) { - Section section = segment.getSectionByName(PrelinkConstants.kPrelinkInfoSection); + if (segment.getSegmentName().equals(MachoPrelinkConstants.kPrelinkSegment_iOS_1x) || + segment.getSegmentName().equals(MachoPrelinkConstants.kPrelinkInfoSegment)) { + Section section = segment.getSectionByName(MachoPrelinkConstants.kPrelinkInfoSection); if (section != null && section.getSize() > 0) { byte[] bytes = provider.readBytes(section.getOffset(), section.getSize() - 1); @@ -283,8 +283,6 @@ public class PrelinkParser { } // - debug(bytes); - //fix bytes so XML will parse... prelinkInputStream = new ByteArrayInputStream(trimmed.getBytes()); @@ -297,21 +295,4 @@ public class PrelinkParser { } return prelinkInputStream; } - - private void debug(byte[] bytes) { - try { - if (SystemUtilities.isInDevelopmentMode()) { - File file = File.createTempFile("__PRELINK_INFO", ".xml"); - OutputStream out = new FileOutputStream(file); - try { - out.write(bytes); - } - finally { - out.close(); - } - } - } - catch (Exception e) { - } - } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/threadcommand/ThreadCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/threadcommand/ThreadCommand.java index 7d9a27dba7..162fa5cea6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/threadcommand/ThreadCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/threadcommand/ThreadCommand.java @@ -30,16 +30,14 @@ import ghidra.util.exception.DuplicateNameException; import ghidra.util.task.TaskMonitor; /** - * Represents a thread_command structure. - * - * @see mach-o/loader.h + * Represents a thread_command structure */ public class ThreadCommand extends LoadCommand { private ThreadStateHeader threadStateHeader; private ThreadState threadState; public ThreadCommand(BinaryReader reader, MachHeader header) throws IOException { - initLoadCommand(reader); + super(reader); threadStateHeader = new ThreadStateHeader(reader); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java index d382fbf293..e1f5cc5fbf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/DyldCacheLoader.java @@ -48,12 +48,12 @@ public class DyldCacheLoader extends AbstractLibrarySupportLoader { /** Default value for loader option to create memory blocks for DYLIB sections */ static final boolean CREATE_DYLIB_SECTIONS_OPTION_DEFAULT = false; - /** Loader option to add relocation entries for each fixed chain pointer */ - static final String ADD_RELOCATION_ENTRIES_OPTION_NAME = - "Add relocation entries for fixed chain pointers"; + /** Loader option to add relocation entries for chained fixups */ + static final String ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME = + "Add relocation entries for chained fixups"; - /** Default value for loader option add relocation entries */ - static final boolean ADD_RELOCATION_ENTRIES_OPTION_DEFAULT = false; + /** Default value for loader option add chained fixups relocation entries */ + static final boolean ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT = false; /** Loader option to combine split DYLD Cache files (.1, .2, .symbol, etc) into one program */ static final String COMBINE_SPLIT_FILES_OPTION_NAME = @@ -98,7 +98,7 @@ public class DyldCacheLoader extends AbstractLibrarySupportLoader { DyldCacheProgramBuilder.buildProgram(program, provider, MemoryBlockUtils.createFileBytes(program, provider, monitor), shouldProcessSymbols(options), shouldCreateDylibSections(options), - shouldAddRelocationEntries(options), shouldCombineSplitFiles(options), log, + shouldAddChainedFixupsRelocations(options), shouldCombineSplitFiles(options), log, monitor); } catch (CancelledException e) { @@ -120,9 +120,9 @@ public class DyldCacheLoader extends AbstractLibrarySupportLoader { list.add( new Option(CREATE_DYLIB_SECTIONS_OPTION_NAME, CREATE_DYLIB_SECTIONS_OPTION_DEFAULT, Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-createDylibSections")); - list.add(new Option(ADD_RELOCATION_ENTRIES_OPTION_NAME, - ADD_RELOCATION_ENTRIES_OPTION_DEFAULT, Boolean.class, - Loader.COMMAND_LINE_ARG_PREFIX + "-addRelocationEntries")); + list.add(new Option(ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_NAME, + ADD_CHAINED_FIXUPS_RELOCATIONS_OPTION_DEFAULT, Boolean.class, + Loader.COMMAND_LINE_ARG_PREFIX + "-addChainedFixupsRelocations")); list.add(new Option(COMBINE_SPLIT_FILES_OPTION_NAME, COMBINE_SPLIT_FILES_OPTION_DEFAULT, Boolean.class, Loader.COMMAND_LINE_ARG_PREFIX + "-combineSplitFiles")); } @@ -139,9 +139,9 @@ public class DyldCacheLoader extends AbstractLibrarySupportLoader { CREATE_DYLIB_SECTIONS_OPTION_DEFAULT); } - private boolean shouldAddRelocationEntries(List