mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-28 15:11:44 +00:00
Merge remote-tracking branch 'origin/GP-258_dev747368_fix_pe_securitycertificate--SQUASHED' into Ghidra_9.2
This commit is contained in:
commit
8dfe8ca13a
@ -72,7 +72,7 @@ public class BinaryReader {
|
||||
* @param newIndex the new index
|
||||
* @return a clone of this reader positioned at the new index
|
||||
*/
|
||||
public BinaryReader clone(int newIndex) {
|
||||
public BinaryReader clone(long newIndex) {
|
||||
BinaryReader clone = new BinaryReader(provider, isLittleEndian());
|
||||
clone.converter = converter;
|
||||
clone.currentIndex = newIndex;
|
||||
@ -643,21 +643,6 @@ public class BinaryReader {
|
||||
return readInt(index) & NumberUtil.UNSIGNED_INT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the INTEGER at <code>index</code>, after coercing it into the range
|
||||
* [minClamp-maxClamp].
|
||||
*
|
||||
* @param index the index where the INTEGER begins
|
||||
* @param minClamp minimum value that will be returned
|
||||
* @param maxClamp maximum value that will be returned
|
||||
* @return the INTEGER
|
||||
* @exception IOException if an I/O error occurs
|
||||
*/
|
||||
public int readInt(long index, int minClamp, int maxClamp) throws IOException {
|
||||
int i = readInt(index);
|
||||
return clampInt(i, minClamp, maxClamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signed LONG at <code>index</code>.
|
||||
* @param index the index where the LONG begins
|
||||
@ -801,27 +786,4 @@ public class BinaryReader {
|
||||
return provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified integer after it has been forced to be within the range of
|
||||
* [minClamp-maxClamp].
|
||||
* <p>
|
||||
* @param i value to force into range
|
||||
* @param minClamp minimum value the integer is allowed to take (inclusive)
|
||||
* @param maxClamp maximum value the integer is allowed to take (inclusive)
|
||||
* @return value of {@code i} if it is within the range [min-max], otherwise min if {@code i} is less than min
|
||||
* or max if {@code i} is greater than max.
|
||||
*/
|
||||
private int clampInt(int i, int minClamp, int maxClamp) {
|
||||
if (maxClamp < minClamp) {
|
||||
throw new IllegalArgumentException("maxClamp < minClamp not allowed");
|
||||
}
|
||||
if (i < minClamp) {
|
||||
i = minClamp;
|
||||
}
|
||||
else if (i > maxClamp) {
|
||||
i = maxClamp;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
/* ###
|
||||
* 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;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ClampPropertiesLookup {
|
||||
public static final String CLAMP_PROPERTIES_FILENAME = "formats/clamp.properties";
|
||||
|
||||
private static boolean UNINITIALIZED = true;
|
||||
private static Properties properties = null;
|
||||
|
||||
public static long getClampValue(String clampKey, long defaultValue) {
|
||||
initialize();
|
||||
try {
|
||||
String property = properties.getProperty(clampKey);
|
||||
if (property != null) {
|
||||
try {
|
||||
long value = Long.parseLong(property);
|
||||
return value;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
// no such property
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static synchronized void initialize() {
|
||||
if (UNINITIALIZED) {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
ResourceFile propertiesFile =
|
||||
Application.getModuleDataFile(CLAMP_PROPERTIES_FILENAME);
|
||||
properties = new Properties();
|
||||
inputStream = propertiesFile.getInputStream();
|
||||
properties.load(inputStream);
|
||||
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Msg.warn(ClampPropertiesLookup.class, "couldn't find clamp properties file");
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.warn(ClampPropertiesLookup.class, "IOException reading clamp properties file",
|
||||
e);
|
||||
}
|
||||
finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// yeah well we tried
|
||||
}
|
||||
}
|
||||
}
|
||||
UNINITIALIZED = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,9 +19,8 @@ import java.io.IOException;
|
||||
|
||||
import ghidra.app.util.bin.BinaryReader;
|
||||
import ghidra.app.util.bin.StructConverter;
|
||||
import ghidra.app.util.bin.format.ClampPropertiesLookup;
|
||||
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.NumericUtilities;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
@ -78,34 +77,45 @@ public class SecurityCertificate implements StructConverter {
|
||||
private short wCertificateType;
|
||||
private byte [] bCertificate;
|
||||
|
||||
static SecurityCertificate createSecurityCertificate(
|
||||
FactoryBundledWithBinaryReader reader, int index)
|
||||
throws IOException {
|
||||
SecurityCertificate securityCertificate = (SecurityCertificate) reader.getFactory().create(SecurityCertificate.class);
|
||||
securityCertificate.initSecurityCertificate(reader, index);
|
||||
return securityCertificate;
|
||||
}
|
||||
/**
|
||||
* Read a SecurityCertificate.
|
||||
*
|
||||
* @param reader BinaryReader to use
|
||||
* @param index offset where the SecurityCertificate starts
|
||||
* @param sizeLimit maximum number of bytes that can be read from the reader
|
||||
* @return new SecurityCertificate, or null if invalid or bad data
|
||||
* @throws IOException if io error when reading data
|
||||
*/
|
||||
static SecurityCertificate read(BinaryReader reader, long index, int sizeLimit)
|
||||
throws IOException {
|
||||
if (sizeLimit < 8) {
|
||||
return null;
|
||||
}
|
||||
reader = reader.clone(index);
|
||||
|
||||
SecurityCertificate result = new SecurityCertificate();
|
||||
result.dwLength = reader.readNextInt();
|
||||
result.wRevision = reader.readNextShort();
|
||||
result.wCertificateType = reader.readNextShort();
|
||||
|
||||
if (result.dwLength < 8 || sizeLimit < result.dwLength) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int certByteCount = result.dwLength - 4 - 2 - 2;
|
||||
result.bCertificate = reader.readNextByteArray(certByteCount);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* DO NOT USE THIS CONSTRUCTOR, USE create*(GenericFactory ...) FACTORY METHODS INSTEAD.
|
||||
*/
|
||||
public SecurityCertificate() {}
|
||||
|
||||
private void initSecurityCertificate(FactoryBundledWithBinaryReader reader, int index) throws IOException {
|
||||
int i = index;
|
||||
|
||||
int maxDwLength = (int) ClampPropertiesLookup.getClampValue("ghidra.app.util.bin.format.pe.SecurityCertificate.dwLength.max", 30000);
|
||||
dwLength = reader.readInt (i, 8, maxDwLength); i += BinaryReader.SIZEOF_INT;
|
||||
if (dwLength < 0) return;
|
||||
wRevision = reader.readShort(i); i += BinaryReader.SIZEOF_SHORT;
|
||||
wCertificateType = reader.readShort(i); i += BinaryReader.SIZEOF_SHORT;
|
||||
bCertificate = reader.readByteArray(i, dwLength-4-2-2);
|
||||
}
|
||||
|
||||
int getNumberOfBytesConsumed() {
|
||||
return dwLength + BinaryReader.SIZEOF_INT +
|
||||
2 * BinaryReader.SIZEOF_SHORT;
|
||||
}
|
||||
int getNumberOfBytesConsumed() {
|
||||
return (int) NumericUtilities.getUnsignedAlignedValue(dwLength, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length, in bytes, of the signature.
|
||||
@ -166,7 +176,8 @@ public class SecurityCertificate implements StructConverter {
|
||||
/**
|
||||
* @see ghidra.app.util.bin.StructConverter#toDataType()
|
||||
*/
|
||||
public DataType toDataType() throws DuplicateNameException {
|
||||
@Override
|
||||
public DataType toDataType() throws DuplicateNameException {
|
||||
StructureDataType struct = new StructureDataType(NAME+"_"+dwLength, 0);
|
||||
struct.add(DWORD,"dwLength",null);
|
||||
struct.add( WORD,"wRevision",null);
|
||||
|
@ -56,7 +56,9 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||
private void initSecurityDataDirectory(NTHeader ntHeader, FactoryBundledWithBinaryReader reader) throws IOException {
|
||||
processDataDirectory(ntHeader, reader);
|
||||
|
||||
if (certificates == null) certificates = new SecurityCertificate[0];
|
||||
if (certificates == null) {
|
||||
certificates = new SecurityCertificate[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +101,7 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||
|
||||
@Override
|
||||
public boolean parse() throws IOException {
|
||||
List<SecurityCertificate> list = new ArrayList<SecurityCertificate>();
|
||||
List<SecurityCertificate> list = new ArrayList<>();
|
||||
|
||||
// Sanity check...
|
||||
// Sometimes the cert address is not valid
|
||||
@ -114,16 +116,21 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||
|
||||
int certOffset = getVirtualAddress();
|
||||
int certSize = getSize();
|
||||
if (certOffset + certSize > reader.length()) {
|
||||
Msg.warn(this, "Certificate length " + certSize + " exceeds EOF.");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (certSize > 0 && certSize < NTHeader.MAX_SANE_COUNT) {
|
||||
SecurityCertificate cert = SecurityCertificate.createSecurityCertificate(reader, certOffset);
|
||||
if (cert.getLength() < 0) {
|
||||
SecurityCertificate cert = SecurityCertificate.read(reader, certOffset, certSize);
|
||||
if (cert == null) {
|
||||
return false;
|
||||
}
|
||||
list.add(cert);
|
||||
|
||||
certOffset += cert.getNumberOfBytesConsumed();
|
||||
certSize -= cert.getNumberOfBytesConsumed();
|
||||
int certBytesUsed = cert.getNumberOfBytesConsumed();
|
||||
certOffset += certBytesUsed;
|
||||
certSize -= certBytesUsed;
|
||||
}
|
||||
|
||||
certificates = new SecurityCertificate[list.size()];
|
||||
@ -147,6 +154,7 @@ public class SecurityDataDirectory extends DataDirectory implements ByteArrayCon
|
||||
/**
|
||||
* @see ghidra.app.util.bin.ByteArrayConverter#toBytes(ghidra.util.DataConverter)
|
||||
*/
|
||||
@Override
|
||||
public byte [] toBytes(DataConverter dc) {
|
||||
try {
|
||||
return reader.readByteArray( virtualAddress, size );
|
||||
|
Loading…
Reference in New Issue
Block a user