Skip to content

Commit

Permalink
Merge branch 'GP-2008_ryanmkurtz_macho-exports' (Closes #2932)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmkurtz committed Jun 5, 2022
2 parents eb0a23a + 4dd4dd9 commit c6cb8a0
Show file tree
Hide file tree
Showing 14 changed files with 679 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.macho.commands.*;
import ghidra.app.util.opinion.DyldCacheUtils.SplitDyldCache;
import ghidra.program.model.data.*;
import ghidra.util.exception.DuplicateNameException;

Expand Down Expand Up @@ -135,14 +136,34 @@ public MachHeader(ByteProvider provider, long machHeaderStartIndexInProvider,
_commandIndex = _reader.getPointerIndex();
}

/**
* Parses this {@link MachHeader}'s {@link LoadCommand load commands}
*
* @return This {@link MachHeader}, for convenience
* @throws IOException If there was an IO-related error
* @throws MachException if the load command is invalid
*/
public MachHeader parse() throws IOException, MachException {
return parse(null);
}

/**
* Parses this {@link MachHeader}'s {@link LoadCommand load commands}
*
* @param splitDyldCache The {@link SplitDyldCache} that this header resides in. Could be null
* if a split DYLD cache is not being used.
* @return This {@link MachHeader}, for convenience
* @throws IOException If there was an IO-related error
* @throws MachException if the load command is invalid
*/
public MachHeader parse(SplitDyldCache splitDyldCache) throws IOException, MachException {
if (_parsed) {
return this;
}
long currentIndex = _commandIndex;
for (int i = 0; i < nCmds; ++i) {
_reader.setPointerIndex(currentIndex);
LoadCommand lc = LoadCommandFactory.getLoadCommand(_reader, this);
LoadCommand lc = LoadCommandFactory.getLoadCommand(_reader, this, splitDyldCache);
_commands.add(lc);
currentIndex += lc.getCommandSize();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,20 @@ public class DyldChainedFixupsCommand extends LinkEditDataCommand {

private DyldChainedFixupHeader chainHeader;

DyldChainedFixupsCommand(BinaryReader reader) throws IOException {
super(reader);

long ptrIndex = reader.getPointerIndex();
reader.setPointerIndex(getDataOffset());
chainHeader = new DyldChainedFixupHeader(reader);
reader.setPointerIndex(ptrIndex);
/**
* Creates and parses a new {@link DyldChainedFixupsCommand}
*
* @param loadCommandReader A {@link BinaryReader reader} that points to the start of the load
* command
* @param dataReader A {@link BinaryReader reader} that can read the data that the load command
* references. Note that this might be in a different underlying provider.
* @throws IOException if an IO-related error occurs while parsing
*/
DyldChainedFixupsCommand(BinaryReader loadCommandReader, BinaryReader dataReader)
throws IOException {
super(loadCommandReader, dataReader);

chainHeader = new DyldChainedFixupHeader(dataReader);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* ###
* 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 java.io.IOException;

import ghidra.app.util.bin.BinaryReader;

/**
* Represents a LC_DYLD_EXPORTS_TRIE command
*
* @see <a href="https://opensource.apple.com/source/xnu/xnu-7195.81.3/EXTERNAL_HEADERS/mach-o/loader.h.auto.html">mach-o/loader.h</a>
*/
public class DyldExportsTrieCommand extends LinkEditDataCommand {

private ExportTrie exportTrie;

/**
* Creates and parses a new {@link DyldExportsTrieCommand}
*
* @param loadCommandReader A {@link BinaryReader reader} that points to the start of the load
* command
* @param dataReader A {@link BinaryReader reader} that can read the data that the load command
* references. Note that this might be in a different underlying provider.
* @throws IOException if an IO-related error occurs while parsing
*/
DyldExportsTrieCommand(BinaryReader loadCommandReader, BinaryReader dataReader)
throws IOException {
super(loadCommandReader, dataReader);
exportTrie = dataoff > 0 && datasize > 0 ? new ExportTrie(dataReader) : new ExportTrie();
}

/**
* Gets the {@link ExportTrie}
*
* @return The {@link ExportTrie}
*/
public ExportTrie getExportTrie() {
return exportTrie;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,41 @@ public class DyldInfoCommand extends LoadCommand {
private int lazy_bind_size;
private int export_off;
private int export_size;

private ExportTrie exportTrie;

DyldInfoCommand(BinaryReader reader) throws IOException {
super(reader);

rebase_off = reader.readNextInt();
rebase_size = reader.readNextInt();
bind_off = reader.readNextInt();
bind_size = reader.readNextInt();
weak_bind_off = reader.readNextInt();
weak_bind_size = reader.readNextInt();
lazy_bind_off = reader.readNextInt();
lazy_bind_size = reader.readNextInt();
export_off = reader.readNextInt();
export_size = reader.readNextInt();
/**
* Creates and parses a new {@link DyldInfoCommand}
*
* @param loadCommandReader A {@link BinaryReader reader} that points to the start of the load
* command
* @param dataReader A {@link BinaryReader reader} that can read the data that the load command
* references. Note that this might be in a different underlying provider.
* @param header The {@link MachHeader header} associated with this load command
* @throws IOException if an IO-related error occurs while parsing
*/
DyldInfoCommand(BinaryReader loadCommandReader, BinaryReader dataReader, MachHeader header)
throws IOException {
super(loadCommandReader);

rebase_off = loadCommandReader.readNextInt();
rebase_size = loadCommandReader.readNextInt();
bind_off = loadCommandReader.readNextInt();
bind_size = loadCommandReader.readNextInt();
weak_bind_off = loadCommandReader.readNextInt();
weak_bind_size = loadCommandReader.readNextInt();
lazy_bind_off = loadCommandReader.readNextInt();
lazy_bind_size = loadCommandReader.readNextInt();
export_off = loadCommandReader.readNextInt();
export_size = loadCommandReader.readNextInt();

if (export_off > 0 && export_size > 0) {
dataReader.setPointerIndex(header.getStartIndex() + export_off);
exportTrie = new ExportTrie(dataReader);
}
else {
exportTrie = new ExportTrie();
}
}

@Override
Expand Down Expand Up @@ -202,4 +223,13 @@ public int getExportOffset() {
public int getExportSize() {
return export_size;
}

/**
* Gets the {@link ExportTrie}
*
* @return The {@link ExportTrie}
*/
public ExportTrie getExportTrie() {
return exportTrie;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public final class DyldInfoCommandConstants {
public final static int EXPORT_SYMBOL_FLAGS_KIND_MASK = 0x03;
public final static int EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00;
public final static int EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01;
public final static int EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE = 0x02;
public final static int EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION = 0x04;
public final static int EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION = 0x08;
public final static int EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS = 0x10;
public final static int EXPORT_SYMBOL_FLAGS_REEXPORT = 0x08;
public final static int EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER = 0x10;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,69 +63,76 @@ public class DynamicSymbolTableCommand extends LoadCommand {
private List<RelocationInfo> externalRelocations = new ArrayList<RelocationInfo>();
private List<RelocationInfo> localRelocations = new ArrayList<RelocationInfo>();

DynamicSymbolTableCommand(BinaryReader reader, MachHeader header) throws IOException {
super(reader);

ilocalsym = reader.readNextInt();
nlocalsym = reader.readNextInt();
iextdefsym = reader.readNextInt();
nextdefsym = reader.readNextInt();
iundefsym = reader.readNextInt();
nundefsym = reader.readNextInt();
tocoff = reader.readNextInt();
ntoc = reader.readNextInt();
modtaboff = reader.readNextInt();
nmodtab = reader.readNextInt();
extrefsymoff = reader.readNextInt();
nextrefsyms = reader.readNextInt();
indirectsymoff = reader.readNextInt();
nindirectsyms = reader.readNextInt();
extreloff = reader.readNextInt();
nextrel = reader.readNextInt();
locreloff = reader.readNextInt();
nlocrel = reader.readNextInt();

long index = reader.getPointerIndex();
/**
* Creates and parses a new {@link DynamicSymbolTableCommand}
*
* @param loadCommandReader A {@link BinaryReader reader} that points to the start of the load
* command
* @param dataReader A {@link BinaryReader reader} that can read the data that the load command
* references. Note that this might be in a different underlying provider.
* @param header The {@link MachHeader header} associated with this load command
* @throws IOException if an IO-related error occurs while parsing
*/
DynamicSymbolTableCommand(BinaryReader loadCommandReader, BinaryReader dataReader,
MachHeader header) throws IOException {
super(loadCommandReader);

ilocalsym = loadCommandReader.readNextInt();
nlocalsym = loadCommandReader.readNextInt();
iextdefsym = loadCommandReader.readNextInt();
nextdefsym = loadCommandReader.readNextInt();
iundefsym = loadCommandReader.readNextInt();
nundefsym = loadCommandReader.readNextInt();
tocoff = loadCommandReader.readNextInt();
ntoc = loadCommandReader.readNextInt();
modtaboff = loadCommandReader.readNextInt();
nmodtab = loadCommandReader.readNextInt();
extrefsymoff = loadCommandReader.readNextInt();
nextrefsyms = loadCommandReader.readNextInt();
indirectsymoff = loadCommandReader.readNextInt();
nindirectsyms = loadCommandReader.readNextInt();
extreloff = loadCommandReader.readNextInt();
nextrel = loadCommandReader.readNextInt();
locreloff = loadCommandReader.readNextInt();
nlocrel = loadCommandReader.readNextInt();

if (tocoff > 0) {
reader.setPointerIndex(header.getStartIndex() + tocoff);
dataReader.setPointerIndex(header.getStartIndex() + tocoff);
for (int i = 0; i < ntoc; ++i) {
tocList.add(new TableOfContents(reader));
tocList.add(new TableOfContents(dataReader));
}
}
if (modtaboff > 0) {
reader.setPointerIndex(header.getStartIndex() + modtaboff);
dataReader.setPointerIndex(header.getStartIndex() + modtaboff);
for (int i = 0; i < nmodtab; ++i) {
moduleList.add(new DynamicLibraryModule(reader, header));
moduleList.add(new DynamicLibraryModule(dataReader, header));
}
}
if (extrefsymoff > 0) {
reader.setPointerIndex(header.getStartIndex() + extrefsymoff);
dataReader.setPointerIndex(header.getStartIndex() + extrefsymoff);
for (int i = 0; i < nextrefsyms; ++i) {
referencedList.add(new DynamicLibraryReference(reader));
referencedList.add(new DynamicLibraryReference(dataReader));
}
}
if (indirectsymoff > 0) {
reader.setPointerIndex(header.getStartIndex() + indirectsymoff);
dataReader.setPointerIndex(header.getStartIndex() + indirectsymoff);
indirectSymbols = new int[nindirectsyms];
for (int i = 0; i < nindirectsyms; ++i) {
indirectSymbols[i] = reader.readNextInt();
indirectSymbols[i] = dataReader.readNextInt();
}
}
if (extreloff > 0) {
reader.setPointerIndex(header.getStartIndex() + extreloff);
dataReader.setPointerIndex(header.getStartIndex() + extreloff);
for (int i = 0; i < nextrel; ++i) {
externalRelocations.add(new RelocationInfo(reader));
externalRelocations.add(new RelocationInfo(dataReader));
}
}
if (locreloff > 0) {
reader.setPointerIndex(header.getStartIndex() + locreloff);
dataReader.setPointerIndex(header.getStartIndex() + locreloff);
for (int i = 0; i < nlocrel; ++i) {
localRelocations.add(new RelocationInfo(reader));
localRelocations.add(new RelocationInfo(dataReader));
}
}

reader.setPointerIndex(index);
}

/**
Expand Down
Loading

0 comments on commit c6cb8a0

Please sign in to comment.