GP-5371: MachoLoader now uses longs to model native uint32_t

This commit is contained in:
Ryan Kurtz 2025-02-12 12:05:25 -05:00
parent eaa8aeb0c8
commit bf92745d25
23 changed files with 242 additions and 223 deletions

View file

@ -4,9 +4,9 @@
* 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.
@ -31,7 +31,7 @@ public class BuildVersionCommand extends LoadCommand {
private int platform;
private int minos;
private int sdk;
private int ntools;
private long ntools;
private BuildToolVersion[] buildToolVersions;
BuildVersionCommand(BinaryReader reader) throws IOException {
@ -40,8 +40,8 @@ public class BuildVersionCommand extends LoadCommand {
platform = reader.readNextInt();
minos = reader.readNextInt();
sdk = reader.readNextInt();
ntools = reader.readNextInt();
buildToolVersions = new BuildToolVersion[ntools];
ntools = checkCount(reader.readNextUnsignedInt());
buildToolVersions = new BuildToolVersion[(int) ntools];
for (int i = 0; i < ntools; i++) {
buildToolVersions[i] = new BuildToolVersion(reader.readNextInt(), reader.readNextInt());
}
@ -58,7 +58,7 @@ public class BuildVersionCommand extends LoadCommand {
struct.add(DWORD, "sdk", null);
struct.add(DWORD, "ntools", null);
if (ntools > 0) {
struct.add(new ArrayDataType(buildToolVersionDataType, ntools,
struct.add(new ArrayDataType(buildToolVersionDataType, (int) ntools,
buildToolVersionDataType.getLength()), "build_tool_version[]", null);
}
struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY));
@ -82,7 +82,7 @@ public class BuildVersionCommand extends LoadCommand {
return sdk;
}
public int getNumTools() {
public long getNumTools() {
return ntools;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -35,16 +35,16 @@ import ghidra.util.task.TaskMonitor;
* Represents a dyld_info_command structure
*/
public class DyldInfoCommand extends LoadCommand {
private int rebaseOff;
private int rebaseSize;
private int bindOff;
private int bindSize;
private int weakBindOff;
private int weakBindSize;
private int lazyBindOff;
private int lazyBindSize;
private int exportOff;
private int exportSize;
private long rebaseOff;
private long rebaseSize;
private long bindOff;
private long bindSize;
private long weakBindOff;
private long weakBindSize;
private long lazyBindOff;
private long lazyBindSize;
private long exportOff;
private long exportSize;
private RebaseTable rebaseTable;
private BindingTable bindingTable;
@ -66,16 +66,16 @@ public class DyldInfoCommand extends LoadCommand {
throws IOException {
super(loadCommandReader);
rebaseOff = loadCommandReader.readNextInt();
rebaseSize = loadCommandReader.readNextInt();
bindOff = loadCommandReader.readNextInt();
bindSize = loadCommandReader.readNextInt();
weakBindOff = loadCommandReader.readNextInt();
weakBindSize = loadCommandReader.readNextInt();
lazyBindOff = loadCommandReader.readNextInt();
lazyBindSize = loadCommandReader.readNextInt();
exportOff = loadCommandReader.readNextInt();
exportSize = loadCommandReader.readNextInt();
rebaseOff = loadCommandReader.readNextUnsignedInt();
rebaseSize = loadCommandReader.readNextUnsignedInt();
bindOff = loadCommandReader.readNextUnsignedInt();
bindSize = loadCommandReader.readNextUnsignedInt();
weakBindOff = loadCommandReader.readNextUnsignedInt();
weakBindSize = loadCommandReader.readNextUnsignedInt();
lazyBindOff = loadCommandReader.readNextUnsignedInt();
lazyBindSize = loadCommandReader.readNextUnsignedInt();
exportOff = loadCommandReader.readNextUnsignedInt();
exportSize = loadCommandReader.readNextUnsignedInt();
if (rebaseOff > 0 && rebaseSize > 0) {
dataReader.setPointerIndex(header.getStartIndex() + rebaseOff);
@ -121,70 +121,70 @@ public class DyldInfoCommand extends LoadCommand {
/**
* {@return The rebase info offset}
*/
public int getRebaseOffset() {
public long getRebaseOffset() {
return rebaseOff;
}
/**
* {@return The rebase info size}
*/
public int getRebaseSize() {
public long getRebaseSize() {
return rebaseSize;
}
/**
* {@return The bind info offset}
*/
public int getBindOffset() {
public long getBindOffset() {
return bindOff;
}
/**
* {@return The bind info size}
*/
public int getBindSize() {
public long getBindSize() {
return bindSize;
}
/**
* {@return The weak bind info offset}
*/
public int getWeakBindOffset() {
public long getWeakBindOffset() {
return weakBindOff;
}
/**
* {@return The weak bind info size}
*/
public int getWeakBindSize() {
public long getWeakBindSize() {
return weakBindSize;
}
/**
* {@return The lazy bind info offset}
*/
public int getLazyBindOffset() {
public long getLazyBindOffset() {
return lazyBindOff;
}
/**
* {@return The lazy bind info size}
*/
public int getLazyBindSize() {
public long getLazyBindSize() {
return lazyBindSize;
}
/**
* {@return The export info offset}
*/
public int getExportOffset() {
public long getExportOffset() {
return exportOff;
}
/**
* {@return The export info size}
*/
public int getExportSize() {
public long getExportSize() {
return exportSize;
}

View file

@ -37,31 +37,31 @@ import ghidra.util.task.TaskMonitor;
*/
public class DynamicSymbolTableCommand extends LoadCommand {
private int ilocalsym;
private int nlocalsym;
private int iextdefsym;
private int nextdefsym;
private int iundefsym;
private int nundefsym;
private int tocoff;
private int ntoc;
private int modtaboff;
private int nmodtab;
private int extrefsymoff;
private int nextrefsyms;
private int indirectsymoff;
private int nindirectsyms;
private int extreloff;
private int nextrel;
private int locreloff;
private int nlocrel;
private long ilocalsym;
private long nlocalsym;
private long iextdefsym;
private long nextdefsym;
private long iundefsym;
private long nundefsym;
private long tocoff;
private long ntoc;
private long modtaboff;
private long nmodtab;
private long extrefsymoff;
private long nextrefsyms;
private long indirectsymoff;
private long nindirectsyms;
private long extreloff;
private long nextrel;
private long locreloff;
private long nlocrel;
private List<TableOfContents> tocList = new ArrayList<TableOfContents>();
private List<DynamicLibraryModule> moduleList = new ArrayList<DynamicLibraryModule>();
private List<DynamicLibraryReference> referencedList = new ArrayList<DynamicLibraryReference>();
private int[] indirectSymbols = new int[0];
private List<RelocationInfo> externalRelocations = new ArrayList<RelocationInfo>();
private List<RelocationInfo> localRelocations = new ArrayList<RelocationInfo>();
private List<TableOfContents> tocList = new ArrayList<>();
private List<DynamicLibraryModule> moduleList = new ArrayList<>();
private List<DynamicLibraryReference> referencedList = new ArrayList<>();
private List<Integer> indirectSymbols = new ArrayList<>();
private List<RelocationInfo> externalRelocations = new ArrayList<>();
private List<RelocationInfo> localRelocations = new ArrayList<>();
/**
* Creates and parses a new {@link DynamicSymbolTableCommand}
@ -77,59 +77,58 @@ public class DynamicSymbolTableCommand extends LoadCommand {
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();
ilocalsym = loadCommandReader.readNextUnsignedInt();
nlocalsym = checkCount(loadCommandReader.readNextUnsignedInt());
iextdefsym = loadCommandReader.readNextUnsignedInt();
nextdefsym = checkCount(loadCommandReader.readNextUnsignedInt());
iundefsym = loadCommandReader.readNextUnsignedInt();
nundefsym = checkCount(loadCommandReader.readNextUnsignedInt());
tocoff = loadCommandReader.readNextUnsignedInt();
ntoc = checkCount(loadCommandReader.readNextUnsignedInt());
modtaboff = loadCommandReader.readNextUnsignedInt();
nmodtab = checkCount(loadCommandReader.readNextUnsignedInt());
extrefsymoff = loadCommandReader.readNextUnsignedInt();
nextrefsyms = checkCount(loadCommandReader.readNextUnsignedInt());
indirectsymoff = loadCommandReader.readNextUnsignedInt();
nindirectsyms = checkCount(loadCommandReader.readNextUnsignedInt());
extreloff = loadCommandReader.readNextUnsignedInt();
nextrel = checkCount(loadCommandReader.readNextUnsignedInt());
locreloff = loadCommandReader.readNextUnsignedInt();
nlocrel = checkCount(loadCommandReader.readNextUnsignedInt());
if (tocoff > 0) {
dataReader.setPointerIndex(header.getStartIndex() + tocoff);
for (int i = 0; i < ntoc; ++i) {
for (long i = 0; i < ntoc; ++i) {
tocList.add(new TableOfContents(dataReader));
}
}
if (modtaboff > 0) {
dataReader.setPointerIndex(header.getStartIndex() + modtaboff);
for (int i = 0; i < nmodtab; ++i) {
for (long i = 0; i < nmodtab; ++i) {
moduleList.add(new DynamicLibraryModule(dataReader, header));
}
}
if (extrefsymoff > 0) {
dataReader.setPointerIndex(header.getStartIndex() + extrefsymoff);
for (int i = 0; i < nextrefsyms; ++i) {
for (long i = 0; i < nextrefsyms; ++i) {
referencedList.add(new DynamicLibraryReference(dataReader));
}
}
if (indirectsymoff > 0) {
dataReader.setPointerIndex(header.getStartIndex() + indirectsymoff);
indirectSymbols = new int[nindirectsyms];
for (int i = 0; i < nindirectsyms; ++i) {
indirectSymbols[i] = dataReader.readNextInt();
for (long i = 0; i < nindirectsyms; ++i) {
indirectSymbols.add(dataReader.readNextInt());
}
}
if (extreloff > 0) {
dataReader.setPointerIndex(header.getStartIndex() + extreloff);
for (int i = 0; i < nextrel; ++i) {
for (long i = 0; i < nextrel; ++i) {
externalRelocations.add(new RelocationInfo(dataReader));
}
}
if (locreloff > 0) {
dataReader.setPointerIndex(header.getStartIndex() + locreloff);
for (int i = 0; i < nlocrel; ++i) {
for (long i = 0; i < nlocrel; ++i) {
localRelocations.add(new RelocationInfo(dataReader));
}
}
@ -139,7 +138,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the index of the first local symbol.
* @return the index of the first local symbol
*/
public int getLocalSymbolIndex() {
public long getLocalSymbolIndex() {
return ilocalsym;
}
@ -147,7 +146,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the total number of local symbols.
* @return the total number of local symbols
*/
public int getLocalSymbolCount() {
public long getLocalSymbolCount() {
return nlocalsym;
}
@ -155,7 +154,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the index of the first external symbol.
* @return the index of the first external symbol
*/
public int getExternalSymbolIndex() {
public long getExternalSymbolIndex() {
return iextdefsym;
}
@ -163,7 +162,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the total number of external symbols.
* @return the total number of external symbols
*/
public int getExternalSymbolCount() {
public long getExternalSymbolCount() {
return nextdefsym;
}
@ -171,7 +170,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the index of the first undefined symbol.
* @return the index of the first undefined symbol
*/
public int getUndefinedSymbolIndex() {
public long getUndefinedSymbolIndex() {
return iundefsym;
}
@ -179,7 +178,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the total number of undefined symbols.
* @return the total number of undefined symbols
*/
public int getUndefinedSymbolCount() {
public long getUndefinedSymbolCount() {
return nundefsym;
}
@ -187,7 +186,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the byte index from the start of the file to the table of contents (TOC).
* @return the byte index of the TOC
*/
public int getTableOfContentsOffset() {
public long getTableOfContentsOffset() {
return tocoff;
}
@ -195,7 +194,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the number of entries in the table of contents.
* @return the number of entries in the table of contents
*/
public int getTableOfContentsSize() {
public long getTableOfContentsSize() {
return ntoc;
}
@ -207,7 +206,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the byte index from the start of the file to the module table.
* @return the byte index of the module table
*/
public int getModuleTableOffset() {
public long getModuleTableOffset() {
return modtaboff;
}
@ -215,7 +214,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the number of entries in the module table.
* @return the number of entries in the module table
*/
public int getModuleTableSize() {
public long getModuleTableSize() {
return nmodtab;
}
@ -227,7 +226,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the byte index from the start of the file to the external reference table.
* @return the byte index of the external reference table
*/
public int getReferencedSymbolTableOffset() {
public long getReferencedSymbolTableOffset() {
return extrefsymoff;
}
@ -235,7 +234,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the number of entries in the external reference table.
* @return the number of entries in the external reference table
*/
public int getReferencedSymbolTableSize() {
public long getReferencedSymbolTableSize() {
return nextrefsyms;
}
@ -247,7 +246,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the byte index from the start of the file to the indirect symbol table.
* @return the byte index of the indirect symbol table
*/
public int getIndirectSymbolTableOffset() {
public long getIndirectSymbolTableOffset() {
return indirectsymoff;
}
@ -255,11 +254,11 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the number of entries in the indirect symbol table.
* @return the number of entries in the indirect symbol table
*/
public int getIndirectSymbolTableSize() {
public long getIndirectSymbolTableSize() {
return nindirectsyms;
}
public int[] getIndirectSymbols() {
public List<Integer> getIndirectSymbols() {
return indirectSymbols;
}
@ -267,7 +266,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the byte index from the start of the file to the external relocation table.
* @return the byte index of the external relocation table
*/
public int getExternalRelocationOffset() {
public long getExternalRelocationOffset() {
return extreloff;
}
@ -275,7 +274,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the number of entries in the external relocation table.
* @return the number of entries in the external relocation table
*/
public int getExternalRelocationSize() {
public long getExternalRelocationSize() {
return nextrel;
}
@ -287,7 +286,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the byte index from the start of the file to the local relocation table.
* @return the byte index of the local relocation table
*/
public int getLocalRelocationOffset() {
public long getLocalRelocationOffset() {
return locreloff;
}
@ -295,7 +294,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
* Returns the number of entries in the local relocation table.
* @return the number of entries in the local relocation table
*/
public int getLocalRelocationSize() {
public long getLocalRelocationSize() {
return nlocrel;
}
@ -309,7 +308,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
}
@Override
public int getLinkerDataSize() {
public long getLinkerDataSize() {
return nindirectsyms * Integer.BYTES;
}
@ -373,7 +372,7 @@ public class DynamicSymbolTableCommand extends LoadCommand {
ReferenceManager referenceManager = program.getReferenceManager();
try {
for (int i = 0; i < nindirectsyms; i++) {
int nlistIndex = indirectSymbols[i];
int nlistIndex = indirectSymbols.get(i);
Address dataAddr = indirectSymbolTableAddr.add(i * DWORD.getLength());
DataUtilities.createData(program, dataAddr, DWORD, -1,
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
@ -472,19 +471,19 @@ public class DynamicSymbolTableCommand extends LoadCommand {
api.createFragment(parentModule, "INDIRECT_SYMBOLS", start, length);
for (int i = 0; i < indirectSymbols.length; ++i) {
for (int i = 0; i < indirectSymbols.size(); ++i) {
if (monitor.isCancelled()) {
return;
}
Address addr = start.add(i * SIZEOF_DWORD);
NList symbol = header.getFirstLoadCommand(SymbolTableCommand.class).getSymbolAt(
indirectSymbols[i]);
indirectSymbols.get(i));
if (symbol != null) {
api.setEOLComment(addr, symbol.getString());
}
}
api.createDwords(start, getIndirectSymbolTableSize());
api.createDwords(start, (int) getIndirectSymbolTableSize());
}
private void markupExternalRelocations(FlatProgramAPI api, Address baseAddress,

View file

@ -4,9 +4,9 @@
* 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.
@ -26,8 +26,8 @@ import ghidra.util.exception.DuplicateNameException;
* Represents an encryption_info_command structure
*/
public class EncryptedInformationCommand extends LoadCommand {
private int cryptoff;
private int cryptsize;
private long cryptoff;
private long cryptsize;
private int cryptid;
private boolean is32bit;
@ -36,8 +36,8 @@ public class EncryptedInformationCommand extends LoadCommand {
super(reader);
this.is32bit = is32bit;
cryptoff = reader.readNextInt();
cryptsize = reader.readNextInt();
cryptoff = reader.readNextUnsignedInt();
cryptsize = reader.readNextUnsignedInt();
cryptid = reader.readNextInt();
}
@ -45,11 +45,11 @@ public class EncryptedInformationCommand extends LoadCommand {
return cryptid;
}
public int getCryptOffset() {
public long getCryptOffset() {
return cryptoff;
}
public int getCryptSize() {
public long getCryptSize() {
return cryptsize;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -33,7 +33,7 @@ import ghidra.util.task.TaskMonitor;
*/
public class FixedVirtualMemoryFileCommand extends LoadCommand {
private LoadCommandString name;
private int header_addr;
private long header_addr;
public FixedVirtualMemoryFileCommand(BinaryReader reader) throws IOException {
super(reader);
@ -51,7 +51,7 @@ public class FixedVirtualMemoryFileCommand extends LoadCommand {
* Returns the file's virtual address.
* @return the file's virtual address
*/
public int getHeaderAddress() {
public long getHeaderAddress() {
return header_addr;
}

View file

@ -34,8 +34,8 @@ import ghidra.util.task.TaskMonitor;
* Represents a linkedit_data_command structure
*/
public class LinkEditDataCommand extends LoadCommand {
protected int dataoff;
protected int datasize;
protected long dataoff;
protected long datasize;
protected BinaryReader dataReader;
/**
@ -51,8 +51,8 @@ public class LinkEditDataCommand extends LoadCommand {
LinkEditDataCommand(BinaryReader loadCommandReader, BinaryReader dataReader)
throws IOException {
super(loadCommandReader);
this.dataoff = loadCommandReader.readNextInt();
this.datasize = loadCommandReader.readNextInt();
this.dataoff = loadCommandReader.readNextUnsignedInt();
this.datasize = loadCommandReader.readNextUnsignedInt();
this.dataReader = dataReader;
this.dataReader.setPointerIndex(dataoff);
}
@ -63,7 +63,7 @@ public class LinkEditDataCommand extends LoadCommand {
}
@Override
public int getLinkerDataSize() {
public long getLinkerDataSize() {
return datasize;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -29,13 +29,13 @@ import ghidra.util.exception.DuplicateNameException;
*/
public class LinkerOptionCommand extends LoadCommand {
private int count;
private long count;
private List<String> linkerOptions;
LinkerOptionCommand(BinaryReader reader) throws IOException {
super(reader);
count = reader.readNextInt();
linkerOptions = new ArrayList<>(count);
count = checkCount(reader.readNextUnsignedInt());
linkerOptions = new ArrayList<>();
BinaryReader stringReader = reader.clone();
for (int i = 0; i < count; i++) {
String str = stringReader.readNextAsciiString();

View file

@ -16,6 +16,7 @@
package ghidra.app.util.bin.format.macho.commands;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.app.cmd.formats.MachoBinaryAnalysisCommand;
import ghidra.app.util.bin.BinaryReader;
@ -101,7 +102,7 @@ public abstract class LoadCommand implements StructConverter {
*
* @return The file size of this load command's "linker data", or 0 if it has no linker data
*/
public int getLinkerDataSize() {
public long getLinkerDataSize() {
return 0;
}
@ -171,7 +172,7 @@ public abstract class LoadCommand implements StructConverter {
* @return The converted {@link Address}, or null if there is no corresponding {@link Address}
*/
protected Address fileOffsetToAddress(Program program, MachHeader header, long fileOffset,
int size) {
long size) {
if (fileOffset != 0 && size != 0) {
AddressSpace space = program.getAddressFactory().getDefaultAddressSpace();
SegmentCommand segment = getContainingSegment(header, fileOffset);
@ -183,6 +184,25 @@ public abstract class LoadCommand implements StructConverter {
return null;
}
/**
* Checks to make sure the given count value isn't larger than {@link Integer#MAX_VALUE}.
* <p>
* Count values are typically {@code uint32_t}, so we store them as {@code long}s. But, we
* usually end up storing the items in an array or {@link ArrayList}, which can't exceed the
* size of an {@code int}.
*
* @param count The count value to check
* @return The original count value
* @throws IOException if the given count value exceeds {@link Integer#MAX_VALUE}
*/
protected long checkCount(long count) throws IOException {
if (count > Integer.MAX_VALUE) {
throw new IOException("Count value 0x%x in %s is greater than Integer.MAX_VALUE"
.formatted(count, getClass().getSimpleName()));
}
return count;
}
/**
* Gets the {@link SegmentCommand segment} that contains the give file offset
*

View file

@ -4,9 +4,9 @@
* 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.
@ -33,13 +33,13 @@ import ghidra.util.task.TaskMonitor;
*/
public class PreboundDynamicLibraryCommand extends LoadCommand {
private LoadCommandString name;
private int nmodules;
private long nmodules;
private LoadCommandString linkedModules;
PreboundDynamicLibraryCommand(BinaryReader reader) throws IOException {
super(reader);
name = new LoadCommandString(reader, this);
nmodules = reader.readNextInt();
nmodules = checkCount(reader.readNextUnsignedInt());
linkedModules = new LoadCommandString(reader, this);
}
@ -67,7 +67,7 @@ public class PreboundDynamicLibraryCommand extends LoadCommand {
* Returns number of modules in library.
* @return number of modules in library
*/
public int getNumberOfModules() {
public long getNumberOfModules() {
return nmodules;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -44,7 +44,7 @@ public class SegmentCommand extends LoadCommand {
private long filesize;
private int maxprot;
private int initprot;
private int nsects;
private long nsects;
private int flags;
private boolean is32bit;
@ -69,10 +69,10 @@ public class SegmentCommand extends LoadCommand {
}
maxprot = reader.readNextInt();
initprot = reader.readNextInt();
nsects = reader.readNextInt();
nsects = checkCount(reader.readNextUnsignedInt());
flags = reader.readNextInt();
for (int i = 0; i < nsects; ++i) {
for (long i = 0; i < nsects; ++i) {
sections.add(new Section(reader, is32bit));
}
}
@ -194,7 +194,7 @@ public class SegmentCommand extends LoadCommand {
return (initprot & SegmentConstants.PROTECTION_X) != 0;
}
public int getNumberOfSections() {
public long getNumberOfSections() {
return nsects;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -26,18 +26,18 @@ import ghidra.app.util.bin.format.macho.MachException;
* @see <a href="https://opensource.apple.com/source/xnu/xnu-4570.71.2/EXTERNAL_HEADERS/mach-o/loader.h.auto.html">mach-o/loader.h</a>
*/
public class SymbolCommand extends ObsoleteCommand {
private int offset;
private int size;
private long offset;
private long size;
SymbolCommand(BinaryReader reader) throws IOException, MachException {
super(reader);
}
public int getOffset() {
public long getOffset() {
return offset;
}
public int getSize() {
public long getSize() {
return size;
}

View file

@ -38,9 +38,9 @@ import ghidra.util.task.TaskMonitor;
*/
public class SymbolTableCommand extends LoadCommand {
private long symoff;
private int nsyms;
private long nsyms;
private long stroff;
private int strsize;
private long strsize;
private List<NList> symbols = new ArrayList<NList>();
@ -59,11 +59,11 @@ public class SymbolTableCommand extends LoadCommand {
super(loadCommandReader);
symoff = loadCommandReader.readNextUnsignedInt();
nsyms = loadCommandReader.readNextInt();
nsyms = checkCount(loadCommandReader.readNextUnsignedInt());
stroff = loadCommandReader.readNextUnsignedInt();
strsize = loadCommandReader.readNextInt();
strsize = loadCommandReader.readNextUnsignedInt();
List<NList> nlistList = new ArrayList<>(nsyms);
List<NList> nlistList = new ArrayList<>((int) nsyms);
dataReader.setPointerIndex(header.getStartIndex() + symoff);
for (int i = 0; i < nsyms; ++i) {
nlistList.add(new NList(dataReader, header.is32bit()));
@ -98,7 +98,7 @@ public class SymbolTableCommand extends LoadCommand {
* An integer indicating the number of entries in the symbol table.
* @return the number of entries in the symbol table
*/
public int getNumberOfSymbols() {
public long getNumberOfSymbols() {
return nsyms;
}
@ -115,7 +115,7 @@ public class SymbolTableCommand extends LoadCommand {
* An integer indicating the size (in bytes) of the string table.
* @return string table size in bytes
*/
public int getStringTableSize() {
public long getStringTableSize() {
return strsize;
}
@ -174,7 +174,7 @@ public class SymbolTableCommand extends LoadCommand {
}
@Override
public int getLinkerDataSize() {
public long getLinkerDataSize() {
return NList.getSize(symbols);
}

View file

@ -4,9 +4,9 @@
* 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.
@ -35,18 +35,18 @@ import ghidra.util.task.TaskMonitor;
* Represents a twolevel_hints_command structure
*/
public class TwoLevelHintsCommand extends LoadCommand {
private int offset;
private int nhints;
private List<TwoLevelHint> hints = new ArrayList<TwoLevelHint>();
private long offset;
private long nhints;
private List<TwoLevelHint> hints = new ArrayList<>();
TwoLevelHintsCommand(BinaryReader reader) throws IOException {
super(reader);
offset = reader.readNextInt();
nhints = reader.readNextInt();
offset = reader.readNextUnsignedInt();
nhints = checkCount(reader.readNextUnsignedInt());
long index = reader.getPointerIndex();
reader.setPointerIndex(offset);
for (int i = 0; i < nhints; ++i) {
for (long i = 0; i < nhints; ++i) {
hints.add(new TwoLevelHint(reader));
}
reader.setPointerIndex(index);
@ -60,7 +60,7 @@ public class TwoLevelHintsCommand extends LoadCommand {
* Returns the offset to the hint table.
* @return the offset to the hint table
*/
public int getOffset() {
public long getOffset() {
return offset;
}
@ -68,7 +68,7 @@ public class TwoLevelHintsCommand extends LoadCommand {
* Returns the number of hints in the hint table.
* @return the number of hints in the hint table
*/
public int getNumberOfHints() {
public long getNumberOfHints() {
return nhints;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -38,11 +38,11 @@ import ghidra.util.task.TaskMonitor;
*/
public class DyldChainedFixupHeader implements StructConverter {
private int fixupsVersion;
private int startsOffset;
private int importsOffset;
private int symbolsOffset;
private int importsCount;
private long fixupsVersion;
private long startsOffset;
private long importsOffset;
private long symbolsOffset;
private long importsCount;
private int importsFormat;
private int symbolsFormat;
@ -58,11 +58,11 @@ public class DyldChainedFixupHeader implements StructConverter {
public DyldChainedFixupHeader(BinaryReader reader) throws IOException {
long ptrIndex = reader.getPointerIndex();
fixupsVersion = reader.readNextInt();
startsOffset = reader.readNextInt();
importsOffset = reader.readNextInt();
symbolsOffset = reader.readNextInt();
importsCount = reader.readNextInt();
fixupsVersion = reader.readNextUnsignedInt();
startsOffset = reader.readNextUnsignedInt();
importsOffset = reader.readNextUnsignedInt();
symbolsOffset = reader.readNextUnsignedInt();
importsCount = reader.readNextUnsignedInt();
importsFormat = reader.readNextInt();
symbolsFormat = reader.readNextInt();
@ -134,23 +134,23 @@ public class DyldChainedFixupHeader implements StructConverter {
return struct;
}
public int getFixupsVersion() {
public long getFixupsVersion() {
return fixupsVersion;
}
public int getStartsOffset() {
public long getStartsOffset() {
return startsOffset;
}
public int getImportsOffset() {
public long getImportsOffset() {
return importsOffset;
}
public int getSymbolsOffset() {
public long getSymbolsOffset() {
return symbolsOffset;
}
public int getImportsCount() {
public long getImportsCount() {
return importsCount;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -29,7 +29,7 @@ import ghidra.app.util.bin.format.macho.commands.dyld.BindingTable.Binding;
*/
public class DyldChainedImports {
private int importsCount;
private long importsCount;
private int importsFormat;
private long importsOffset;
private DyldChainedImport[] chainedImports;
@ -57,7 +57,7 @@ public class DyldChainedImports {
}
}
public int getImportsCount() {
public long getImportsCount() {
return importsCount;
}

View file

@ -4,9 +4,9 @@
* 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.
@ -38,7 +38,7 @@ import ghidra.util.task.TaskMonitor;
public class CodeSignatureGenericBlob implements StructConverter {
protected int magic;
protected int length;
protected long length;
protected long base;
@ -51,7 +51,7 @@ public class CodeSignatureGenericBlob implements StructConverter {
public CodeSignatureGenericBlob(BinaryReader reader) throws IOException {
base = reader.getPointerIndex();
magic = reader.readNextInt();
length = reader.readNextInt();
length = reader.readNextUnsignedInt();
}
/**
@ -64,7 +64,7 @@ public class CodeSignatureGenericBlob implements StructConverter {
/**
* {@return the length}
*/
public int getLength() {
public long getLength() {
return length;
}
@ -84,7 +84,7 @@ public class CodeSignatureGenericBlob implements StructConverter {
return;
}
try {
DataType dt = new ArrayDataType(BYTE, length - 8, 1);
DataType dt = new ArrayDataType(BYTE, (int) length - 8, 1);
Address hashAddr = address.add(toDataType().getLength());
DataUtilities.createData(program, hashAddr, dt, -1,
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);

View file

@ -4,9 +4,9 @@
* 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.
@ -51,7 +51,7 @@ public class BindingTable extends OpcodeTable {
* @param lazy True if this is a lazy binding table; otherwise, false
* @throws IOException if an IO-related error occurs while parsing
*/
public BindingTable(BinaryReader reader, MachHeader header, int tableSize, boolean lazy)
public BindingTable(BinaryReader reader, MachHeader header, long tableSize, boolean lazy)
throws IOException {
this();

View file

@ -4,9 +4,9 @@
* 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.
@ -79,7 +79,7 @@ public class ClassicBindProcessor extends AbstractClassicProcessor {
int indirectOffset = section.getReserved1();
long count = section.getSize() / program.getDefaultPointerSize();
for (int i = 0; i < count; ++i) {
int symbolIndex = command.getIndirectSymbols()[indirectOffset + i];
int symbolIndex = command.getIndirectSymbols().get(indirectOffset + i);
if (symbolIndex != DynamicSymbolTableConstants.INDIRECT_SYMBOL_LOCAL) {
NList nList = symbolTableCommand.getSymbolAt(symbolIndex);
if (nList == null) {

View file

@ -4,9 +4,9 @@
* 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.
@ -15,13 +15,13 @@
*/
package ghidra.app.util.bin.format.macho.commands.dyld;
import java.util.List;
import ghidra.app.util.bin.format.macho.*;
import ghidra.app.util.bin.format.macho.commands.*;
import ghidra.program.model.listing.Program;
import ghidra.util.task.TaskMonitor;
import java.util.List;
public class ClassicLazyBindProcessor extends AbstractClassicProcessor {
public ClassicLazyBindProcessor(MachHeader header, Program program) {
@ -50,7 +50,7 @@ public class ClassicLazyBindProcessor extends AbstractClassicProcessor {
int indirectOffset = section.getReserved1();
long count = section.getSize() / program.getDefaultPointerSize();
for (int i = 0; i < count; ++i) {
int symbolIndex = command.getIndirectSymbols()[indirectOffset + i];
int symbolIndex = command.getIndirectSymbols().get(indirectOffset + i);
NList nList = symbolTableCommand.getSymbolAt(symbolIndex);
boolean isWeak =
(nList.getDescription() & NListConstants.DESC_N_WEAK_REF) != 0;
@ -68,7 +68,7 @@ public class ClassicLazyBindProcessor extends AbstractClassicProcessor {
int indirectOffset = section.getReserved1();
long count = section.getSize() / 5;
for (int i = 0; i < count; ++i) {
int symbolIndex = command.getIndirectSymbols()[indirectOffset + i];
int symbolIndex = command.getIndirectSymbols().get(indirectOffset + i);
if (symbolIndex != DynamicSymbolTableConstants.INDIRECT_SYMBOL_ABS) {
NList nList = symbolTableCommand.getSymbolAt(symbolIndex);
boolean isWeak =

View file

@ -4,9 +4,9 @@
* 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.
@ -47,7 +47,7 @@ public class RebaseTable extends OpcodeTable {
* @param tableSize The size of the table, in bytes
* @throws IOException if an IO-related error occurs while parsing
*/
public RebaseTable(BinaryReader reader, MachHeader header, int tableSize) throws IOException {
public RebaseTable(BinaryReader reader, MachHeader header, long tableSize) throws IOException {
this();
int pointerSize = header.getAddressSize();

View file

@ -4,9 +4,9 @@
* 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.
@ -25,11 +25,11 @@ import ghidra.util.exception.DuplicateNameException;
public class ThreadStateHeader implements StructConverter {
private int flavor;
private int count;
private long count;
ThreadStateHeader(BinaryReader reader) throws IOException {
flavor = reader.readNextInt();
count = reader.readNextInt();
count = reader.readNextUnsignedInt();
}
/**
@ -44,7 +44,7 @@ public class ThreadStateHeader implements StructConverter {
* Returns the count of longs in thread state.
* @return the count of longs in thread state
*/
public int getCount() {
public long getCount() {
return count;
}

View file

@ -660,8 +660,8 @@ public class MachoProgramBuilder {
if (dynamicCommand == null) {
return;
}
int[] indirectSymbols = dynamicCommand.getIndirectSymbols();
if (indirectSymbols.length == 0) {
List<Integer> indirectSymbols = dynamicCommand.getIndirectSymbols();
if (indirectSymbols.size() == 0) {
return;
}
@ -687,7 +687,7 @@ public class MachoProgramBuilder {
if (monitor.isCancelled()) {
break;
}
int symbolIndex = indirectSymbols[i];
int symbolIndex = indirectSymbols.get(i);
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
if (symbol == null) {
continue;

View file

@ -99,7 +99,7 @@ public class ExtractedMacho {
symbolTable.addSymbols(getExtraSymbols());
}
long offset = cmd.getLinkerDataOffset();
int size = cmd.getLinkerDataSize();
long size = cmd.getLinkerDataSize();
if (offset == 0 || size == 0) {
continue;
}