mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-25 17:00:36 -09:00
GP-7175: Checking count values in Mach-O BindingTable.java and
RebaseTable.java
This commit is contained in:
@@ -18,8 +18,7 @@ package ghidra.app.util.bin.format.macho.commands;
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.macho.MachConstants;
|
||||
import ghidra.app.util.bin.format.macho.MachHeader;
|
||||
import ghidra.app.util.bin.format.macho.*;
|
||||
import ghidra.app.util.bin.format.macho.commands.dyld.*;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.program.flatapi.FlatProgramAPI;
|
||||
@@ -61,9 +60,10 @@ public class DyldInfoCommand extends LoadCommand {
|
||||
* 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
|
||||
* @throws MachException if the {@link DyldInfoCommand} is invalid
|
||||
*/
|
||||
DyldInfoCommand(BinaryReader loadCommandReader, BinaryReader dataReader, MachHeader header)
|
||||
throws IOException {
|
||||
throws IOException, MachException {
|
||||
super(loadCommandReader);
|
||||
|
||||
rebaseOff = loadCommandReader.readNextUnsignedInt();
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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.commands.DyldInfoCommandConstants;
|
||||
import ghidra.program.model.data.LEB128;
|
||||
@@ -31,10 +32,11 @@ import ghidra.program.model.data.LEB128;
|
||||
*/
|
||||
public class BindingTable extends OpcodeTable {
|
||||
|
||||
private static final int COUNT_LIMIT = 100_000;
|
||||
|
||||
private List<Binding> bindings = new ArrayList<>();
|
||||
private List<Binding> threadedBindings;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an empty {@link BindingTable}
|
||||
*/
|
||||
@@ -50,9 +52,10 @@ public class BindingTable extends OpcodeTable {
|
||||
* @param tableSize The size of the table, in bytes
|
||||
* @param lazy True if this is a lazy binding table; otherwise, false
|
||||
* @throws IOException if an IO-related error occurs while parsing
|
||||
* @throws MachException if the {@link BindingTable} is invalid
|
||||
*/
|
||||
public BindingTable(BinaryReader reader, MachHeader header, long tableSize, boolean lazy)
|
||||
throws IOException {
|
||||
throws IOException, MachException {
|
||||
this();
|
||||
|
||||
int pointerSize = header.getAddressSize();
|
||||
@@ -143,6 +146,10 @@ public class BindingTable extends OpcodeTable {
|
||||
case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: { // 0xC0
|
||||
ulebOffsets.add(reader.getPointerIndex() - origIndex);
|
||||
long count = reader.readNext(LEB128::unsigned);
|
||||
if (count < 0 || count > COUNT_LIMIT) {
|
||||
throw new MachException("BIND_OPCODE count exceeds limit (%s): %s"
|
||||
.formatted(COUNT_LIMIT, count));
|
||||
}
|
||||
ulebOffsets.add(reader.getPointerIndex() - origIndex);
|
||||
long skip = reader.readNext(LEB128::unsigned);
|
||||
for ( int i = 0 ; i < count ; ++i ) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.format.macho.MachException;
|
||||
import ghidra.app.util.bin.format.macho.MachHeader;
|
||||
import ghidra.program.model.data.LEB128;
|
||||
|
||||
@@ -30,6 +31,8 @@ import ghidra.program.model.data.LEB128;
|
||||
*/
|
||||
public class RebaseTable extends OpcodeTable {
|
||||
|
||||
private static final int COUNT_LIMIT = 100_000;
|
||||
|
||||
private List<Rebase> rebases = new ArrayList<>();
|
||||
|
||||
/**
|
||||
@@ -46,8 +49,10 @@ public class RebaseTable extends OpcodeTable {
|
||||
* @param header The header
|
||||
* @param tableSize The size of the table, in bytes
|
||||
* @throws IOException if an IO-related error occurs while parsing
|
||||
* @throws MachException if the {@link RebaseTable} is invalid
|
||||
*/
|
||||
public RebaseTable(BinaryReader reader, MachHeader header, long tableSize) throws IOException {
|
||||
public RebaseTable(BinaryReader reader, MachHeader header, long tableSize)
|
||||
throws IOException, MachException {
|
||||
this();
|
||||
|
||||
int pointerSize = header.getAddressSize();
|
||||
@@ -94,6 +99,10 @@ public class RebaseTable extends OpcodeTable {
|
||||
case REBASE_OPCODE_DO_REBASE_ULEB_TIMES: { // 0x60
|
||||
ulebOffsets.add(reader.getPointerIndex() - origIndex);
|
||||
int count = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
if (count < 0 || count > COUNT_LIMIT) {
|
||||
throw new MachException("REBASE_OPCODE count exceeds limit (%s): %s"
|
||||
.formatted(COUNT_LIMIT, count));
|
||||
}
|
||||
for (int i = 0; i < count; ++i) {
|
||||
rebases.add(new Rebase(rebase));
|
||||
rebase.segmentOffset += pointerSize;
|
||||
@@ -109,6 +118,10 @@ public class RebaseTable extends OpcodeTable {
|
||||
case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: { // 0x80
|
||||
ulebOffsets.add(reader.getPointerIndex() - origIndex);
|
||||
int count = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
if (count < 0 || count > COUNT_LIMIT) {
|
||||
throw new MachException("REBASE_OPCODE count exceeds limit (%s): %s"
|
||||
.formatted(COUNT_LIMIT, count));
|
||||
}
|
||||
ulebOffsets.add(reader.getPointerIndex() - origIndex);
|
||||
int skip = reader.readNextUnsignedVarIntExact(LEB128::unsigned);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
||||
Reference in New Issue
Block a user