mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/GP-331_jmlagor_Fix_processing_arrays_that_are_not_primitive_types_in_CIL_metadata--SQUASHED' into patch
This commit is contained in:
commit
4a947eb261
1 changed files with 98 additions and 39 deletions
|
@ -201,8 +201,7 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
|
|
||||||
ELEMENT_TYPE_MODIFIER(0x40), // TODO: this value is ORed with the following 4, Could be changed when Enums support ORing.
|
ELEMENT_TYPE_MODIFIER(0x40), // TODO: this value is ORed with the following 4, Could be changed when Enums support ORing.
|
||||||
ELEMENT_TYPE_SENTINAL(0x41),
|
ELEMENT_TYPE_SENTINAL(0x41),
|
||||||
ELEMENT_TYPE_PINNED(0x45)
|
ELEMENT_TYPE_PINNED(0x45);
|
||||||
;
|
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
|
@ -217,9 +216,10 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
public static CliElementType fromInt(int id) {
|
public static CliElementType fromInt(int id) {
|
||||||
CliElementType[] values = CliElementType.values();
|
CliElementType[] values = CliElementType.values();
|
||||||
for (CliElementType value : values) {
|
for (CliElementType value : values) {
|
||||||
if (value.id == id)
|
if (value.id == id) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,12 +275,53 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CliTypeArray extends CliSigType {
|
public class CliTypeArray extends CliSigType {
|
||||||
private CliElementType arrayType;
|
private CliSigType arrayType;
|
||||||
private CliArrayShape arrayShape;
|
private CliArrayShape arrayShape;
|
||||||
|
|
||||||
public CliTypeArray(BinaryReader reader, CliElementType typeCode) throws IOException {
|
public CliTypeArray(BinaryReader reader, CliElementType typeCode)
|
||||||
|
throws IOException, InvalidInputException {
|
||||||
super(typeCode);
|
super(typeCode);
|
||||||
arrayType = CliElementType.fromInt(reader.readNextByte());
|
CliElementType valueCode = CliElementType.fromInt(reader.readNextByte());
|
||||||
|
|
||||||
|
switch (valueCode) {
|
||||||
|
case ELEMENT_TYPE_VALUETYPE:
|
||||||
|
arrayType = new CliTypeValueType(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_CLASS:
|
||||||
|
arrayType = new CliTypeClass(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_FNPTR:
|
||||||
|
arrayType = new CliTypeFnPtr(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_GENERICINST:
|
||||||
|
arrayType = new CliTypeGenericInst(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_MVAR:
|
||||||
|
case ELEMENT_TYPE_VAR:
|
||||||
|
arrayType = new CliTypeVarOrMvar(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_PTR:
|
||||||
|
arrayType = new CliTypePtr(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_SZARRAY: // Single dimensional, zero-based array, e.g. a vector
|
||||||
|
arrayType = new CliTypeSzArray(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ELEMENT_TYPE_ARRAY:
|
||||||
|
arrayType = new CliTypeArray(reader, typeCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
arrayType = new CliTypePrimitive(valueCode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
arrayShape = new CliArrayShape(reader);
|
arrayShape = new CliArrayShape(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +336,12 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
StructureDataType struct = new StructureDataType(new CategoryPath(PATH), "Array", 0);
|
StructureDataType struct = new StructureDataType(new CategoryPath(PATH), "Array", 0);
|
||||||
struct.add(CliTypeCodeDataType.dataType, "Array",
|
struct.add(CliTypeCodeDataType.dataType, "Array",
|
||||||
String.format("Fixed value: 0x%x", CliElementType.ELEMENT_TYPE_ARRAY.id()));
|
String.format("Fixed value: 0x%x", CliElementType.ELEMENT_TYPE_ARRAY.id()));
|
||||||
|
if (arrayType instanceof CliTypePrimitive) {
|
||||||
struct.add(CliTypeCodeDataType.dataType, "Type", "Type of array");
|
struct.add(CliTypeCodeDataType.dataType, "Type", "Type of array");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct.add(arrayType.getDefinitionDataType(), "ValueType", "Class token");
|
||||||
|
}
|
||||||
struct.add(arrayShape.getDefinitionDataType(), "ArrayShape", null);
|
struct.add(arrayShape.getDefinitionDataType(), "ArrayShape", null);
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
@ -322,13 +368,17 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
CliAbstractTable table =
|
CliAbstractTable table =
|
||||||
stream.getTable(CliIndexTypeDefOrRef.getTableName(encodedType));
|
stream.getTable(CliIndexTypeDefOrRef.getTableName(encodedType));
|
||||||
if (table == null)
|
if (table == null) {
|
||||||
return "[ErrorRetrievingTable]";
|
return "[ErrorRetrievingTable]";
|
||||||
CliAbstractTableRow row = table.getRow(CliIndexTypeDefOrRef.getRowIndex(encodedType));
|
}
|
||||||
if (row == null)
|
CliAbstractTableRow row =
|
||||||
|
table.getRow(CliIndexTypeDefOrRef.getRowIndex(encodedType));
|
||||||
|
if (row == null) {
|
||||||
return "[ErrorRetrievingRow]";
|
return "[ErrorRetrievingRow]";
|
||||||
if (shortRep)
|
}
|
||||||
|
if (shortRep) {
|
||||||
return row.getShortRepresentation();
|
return row.getShortRepresentation();
|
||||||
|
}
|
||||||
return row.getRepresentation();
|
return row.getRepresentation();
|
||||||
}
|
}
|
||||||
return "[ErrorRepresentingClassReference]";
|
return "[ErrorRepresentingClassReference]";
|
||||||
|
@ -396,8 +446,7 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
private int countSizeBytes;
|
private int countSizeBytes;
|
||||||
private List<CliSigType> argTypes = new ArrayList<>();
|
private List<CliSigType> argTypes = new ArrayList<>();
|
||||||
|
|
||||||
public CliTypeGenericInst(BinaryReader reader, CliElementType typeCode)
|
public CliTypeGenericInst(BinaryReader reader, CliElementType typeCode) throws IOException {
|
||||||
throws IOException {
|
|
||||||
super(typeCode);
|
super(typeCode);
|
||||||
firstType = CliElementType.fromInt(reader.readNextByte()); // Should be Class or ValueType
|
firstType = CliElementType.fromInt(reader.readNextByte()); // Should be Class or ValueType
|
||||||
long origIndex = reader.getPointerIndex();
|
long origIndex = reader.getPointerIndex();
|
||||||
|
@ -421,21 +470,24 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
String argTypesRep = "";
|
String argTypesRep = "";
|
||||||
for (int i = 0; i < genArgCount; i++) {
|
for (int i = 0; i < genArgCount; i++) {
|
||||||
argTypesRep += argTypes.get(i).getRepresentation();
|
argTypesRep += argTypes.get(i).getRepresentation();
|
||||||
if (i != genArgCount - 1)
|
if (i != genArgCount - 1) {
|
||||||
argTypesRep += ", ";
|
argTypesRep += ", ";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String typeRep = Integer.toHexString(encodedType);
|
String typeRep = Integer.toHexString(encodedType);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
try {
|
try {
|
||||||
CliAbstractTableRow row =
|
CliAbstractTableRow row =
|
||||||
stream.getTable(CliIndexTypeDefOrRef.getTableName(encodedType)).getRow(
|
stream.getTable(CliIndexTypeDefOrRef.getTableName(encodedType))
|
||||||
CliIndexTypeDefOrRef.getRowIndex(encodedType));
|
.getRow(CliIndexTypeDefOrRef.getRowIndex(encodedType));
|
||||||
if (shortRep)
|
if (shortRep) {
|
||||||
typeRep = row.getShortRepresentation();
|
typeRep = row.getShortRepresentation();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
typeRep = row.getRepresentation();
|
typeRep = row.getRepresentation();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (InvalidInputException e) {
|
catch (InvalidInputException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -481,8 +533,7 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
private int number;
|
private int number;
|
||||||
private int numberBytes;
|
private int numberBytes;
|
||||||
|
|
||||||
public CliTypeVarOrMvar(BinaryReader reader, CliElementType typeCode)
|
public CliTypeVarOrMvar(BinaryReader reader, CliElementType typeCode) throws IOException {
|
||||||
throws IOException {
|
|
||||||
super(typeCode);
|
super(typeCode);
|
||||||
long origIndex = reader.getPointerIndex();
|
long origIndex = reader.getPointerIndex();
|
||||||
number = decodeCompressedUnsignedInt(reader);
|
number = decodeCompressedUnsignedInt(reader);
|
||||||
|
@ -555,17 +606,20 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
@Override
|
@Override
|
||||||
public String getRepresentation(CliStreamMetadata stream) {
|
public String getRepresentation(CliStreamMetadata stream) {
|
||||||
String typeRep;
|
String typeRep;
|
||||||
if (stream == null)
|
if (stream == null) {
|
||||||
typeRep = type.getRepresentation();
|
typeRep = type.getRepresentation();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
typeRep = type.getRepresentation(stream);
|
typeRep = type.getRepresentation(stream);
|
||||||
|
}
|
||||||
|
|
||||||
String modsRep = "";
|
String modsRep = "";
|
||||||
for (CliCustomMod mod : customMods) {
|
for (CliCustomMod mod : customMods) {
|
||||||
modsRep += mod.toString() + ", ";
|
modsRep += mod.toString() + ", ";
|
||||||
}
|
}
|
||||||
if (customMods.size() > 0)
|
if (customMods.size() > 0) {
|
||||||
modsRep.substring(0, modsRep.length() - 2); // Remove last comma+space
|
modsRep.substring(0, modsRep.length() - 2); // Remove last comma+space
|
||||||
|
}
|
||||||
return String.format("SzArray %s %s", modsRep, typeRep);
|
return String.format("SzArray %s %s", modsRep, typeRep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,8 +644,7 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
private int encodedType;
|
private int encodedType;
|
||||||
private int typeBytes;
|
private int typeBytes;
|
||||||
|
|
||||||
public CliTypeValueType(BinaryReader reader, CliElementType typeCode)
|
public CliTypeValueType(BinaryReader reader, CliElementType typeCode) throws IOException {
|
||||||
throws IOException {
|
|
||||||
super(typeCode);
|
super(typeCode);
|
||||||
long origIndex = reader.getPointerIndex();
|
long origIndex = reader.getPointerIndex();
|
||||||
encodedType = decodeCompressedUnsignedInt(reader);
|
encodedType = decodeCompressedUnsignedInt(reader);
|
||||||
|
@ -607,8 +660,8 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
public String getRepresentation(CliStreamMetadata stream, boolean shortRep) {
|
public String getRepresentation(CliStreamMetadata stream, boolean shortRep) {
|
||||||
try {
|
try {
|
||||||
CliAbstractTableRow row =
|
CliAbstractTableRow row =
|
||||||
stream.getTable(CliIndexTypeDefOrRef.getTableName(encodedType)).getRow(
|
stream.getTable(CliIndexTypeDefOrRef.getTableName(encodedType))
|
||||||
CliIndexTypeDefOrRef.getRowIndex(encodedType));
|
.getRow(CliIndexTypeDefOrRef.getRowIndex(encodedType));
|
||||||
return "ValueType " +
|
return "ValueType " +
|
||||||
(shortRep ? row.getShortRepresentation() : row.getRepresentation());
|
(shortRep ? row.getShortRepresentation() : row.getRepresentation());
|
||||||
}
|
}
|
||||||
|
@ -638,13 +691,13 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CliSigType readCliType(BinaryReader reader)
|
public CliSigType readCliType(BinaryReader reader) throws IOException, InvalidInputException {
|
||||||
throws IOException, InvalidInputException {
|
|
||||||
byte typeByte = reader.readNextByte();
|
byte typeByte = reader.readNextByte();
|
||||||
CliElementType typeCode = CliElementType.fromInt(typeByte);
|
CliElementType typeCode = CliElementType.fromInt(typeByte);
|
||||||
if (typeCode == null)
|
if (typeCode == null) {
|
||||||
throw new InvalidInputException("TypeCode not found at reader index " +
|
throw new InvalidInputException("TypeCode not found at reader index " +
|
||||||
reader.getPointerIndex() + ". Are you in the right place? (" + typeByte + ")");
|
reader.getPointerIndex() + ". Are you in the right place? (" + typeByte + ")");
|
||||||
|
}
|
||||||
switch (typeCode) {
|
switch (typeCode) {
|
||||||
case ELEMENT_TYPE_ARRAY:
|
case ELEMENT_TYPE_ARRAY:
|
||||||
return new CliTypeArray(reader, typeCode);
|
return new CliTypeArray(reader, typeCode);
|
||||||
|
@ -756,8 +809,9 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRepresentation() {
|
public String getRepresentation() {
|
||||||
if (constraint == CliElementType.ELEMENT_TYPE_PINNED)
|
if (constraint == CliElementType.ELEMENT_TYPE_PINNED) {
|
||||||
return constraint.toString();
|
return constraint.toString();
|
||||||
|
}
|
||||||
return String.format("Invalid Constraint (%s - %x)", constraint.toString(),
|
return String.format("Invalid Constraint (%s - %x)", constraint.toString(),
|
||||||
constraint.id());
|
constraint.id());
|
||||||
}
|
}
|
||||||
|
@ -801,10 +855,12 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
for (CliCustomMod mod : customMods) {
|
for (CliCustomMod mod : customMods) {
|
||||||
rep += mod.getRepresentation() + "; ";
|
rep += mod.getRepresentation() + "; ";
|
||||||
}
|
}
|
||||||
if (customMods.size() > 0)
|
if (customMods.size() > 0) {
|
||||||
rep = rep.substring(0, rep.length() - 2) + " ";
|
rep = rep.substring(0, rep.length() - 2) + " ";
|
||||||
if (byRef)
|
}
|
||||||
|
if (byRef) {
|
||||||
rep += "byref ";
|
rep += "byref ";
|
||||||
|
}
|
||||||
rep += getRepresentationOf(type, stream, shortRep);
|
rep += getRepresentationOf(type, stream, shortRep);
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
@ -834,8 +890,9 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
for (CliCustomMod mod : customMods) {
|
for (CliCustomMod mod : customMods) {
|
||||||
struct.add(mod.getDefinitionDataType(), "CustomMod", null);
|
struct.add(mod.getDefinitionDataType(), "CustomMod", null);
|
||||||
}
|
}
|
||||||
if (byRef)
|
if (byRef) {
|
||||||
struct.add(BYTE, "BYREF", "By reference");
|
struct.add(BYTE, "BYREF", "By reference");
|
||||||
|
}
|
||||||
struct.add(type.getDefinitionDataType(), "Type", null);
|
struct.add(type.getDefinitionDataType(), "Type", null);
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
@ -905,13 +962,15 @@ public abstract class CliAbstractSig extends CliBlob implements CliRepresentable
|
||||||
new StructureDataType(new CategoryPath(PATH), "ArrayShape", 0);
|
new StructureDataType(new CategoryPath(PATH), "ArrayShape", 0);
|
||||||
struct.add(getDataTypeForBytes(rankBytes), "Rank", "Number of dimensions in array");
|
struct.add(getDataTypeForBytes(rankBytes), "Rank", "Number of dimensions in array");
|
||||||
struct.add(getDataTypeForBytes(numSizesBytes), "NumSizes", "Number of sizes to follow");
|
struct.add(getDataTypeForBytes(numSizesBytes), "NumSizes", "Number of sizes to follow");
|
||||||
for (int i = 0; i < sizeBytes.length; i++)
|
for (int i = 0; i < sizeBytes.length; i++) {
|
||||||
struct.add(getDataTypeForBytes(sizeBytes[i]), "Size" + i, "Coded integer size");
|
struct.add(getDataTypeForBytes(sizeBytes[i]), "Size" + i, "Coded integer size");
|
||||||
|
}
|
||||||
struct.add(getDataTypeForBytes(numLoBoundsBytes), "NumLoBounds",
|
struct.add(getDataTypeForBytes(numLoBoundsBytes), "NumLoBounds",
|
||||||
"Number of lower bounds in array");
|
"Number of lower bounds in array");
|
||||||
for (int i = 0; i < loBoundBytes.length; i++)
|
for (int i = 0; i < loBoundBytes.length; i++) {
|
||||||
struct.add(getDataTypeForBytes(loBoundBytes[i]), "LoBound" + i,
|
struct.add(getDataTypeForBytes(loBoundBytes[i]), "LoBound" + i,
|
||||||
"Coded integer lower bound");
|
"Coded integer lower bound");
|
||||||
|
}
|
||||||
return struct;
|
return struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue