mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 13:16:48 +08:00
Merge remote-tracking branch 'origin/GP-2518_ghizard_PDB_Handle_VTShape--SQUASHED'
This commit is contained in:
+13
-13
@@ -35,26 +35,24 @@ public class FieldListTypeApplier extends MsTypeApplier {
|
||||
private List<MsTypeApplier> methodList = new ArrayList<>();
|
||||
private boolean isEmpty;
|
||||
|
||||
// return can be null
|
||||
static FieldListTypeApplier getFieldListApplierSpecial(DefaultPdbApplicator applicator,
|
||||
RecordNumber recordNumber) throws PdbException {
|
||||
MsTypeApplier applier =
|
||||
applicator.getApplierOrNoTypeSpec(recordNumber, FieldListTypeApplier.class);
|
||||
FieldListTypeApplier fieldListApplier = null;
|
||||
if (applier instanceof FieldListTypeApplier) {
|
||||
return (FieldListTypeApplier) applicator.getApplierOrNoTypeSpec(recordNumber,
|
||||
FieldListTypeApplier.class);
|
||||
if (applier instanceof FieldListTypeApplier fieldListApplier) {
|
||||
return fieldListApplier;
|
||||
}
|
||||
try {
|
||||
if (recordNumber.getCategory() == RecordCategory.TYPE) {
|
||||
fieldListApplier = new FieldListTypeApplier(applicator,
|
||||
// Only the NoType spec should fall through to here
|
||||
if (recordNumber.getCategory() == RecordCategory.TYPE) {
|
||||
try {
|
||||
return new FieldListTypeApplier(applicator,
|
||||
applicator.getPdb().getTypeRecord(recordNumber), true);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
applicator.appendLogMsg(e.getMessage());
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
applicator.appendLogMsg(e.getMessage());
|
||||
}
|
||||
return fieldListApplier;
|
||||
throw new PdbException("Problem creating field list");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +103,9 @@ public class FieldListTypeApplier extends MsTypeApplier {
|
||||
|
||||
@Override
|
||||
void apply() throws PdbException, CancelledException {
|
||||
dataType = applyFieldListMsType((AbstractFieldListMsType) msType);
|
||||
if (!isEmpty()) {
|
||||
dataType = applyFieldListMsType((AbstractFieldListMsType) msType);
|
||||
}
|
||||
}
|
||||
|
||||
List<MsTypeApplier> getBaseClassList() {
|
||||
|
||||
-9
@@ -89,16 +89,7 @@ public class PointerTypeApplier extends MsTypeApplier {
|
||||
private DataType getUnderlyingType(AbstractPointerMsType type) {
|
||||
MsTypeApplier underlyingApplier =
|
||||
applicator.getTypeApplier(type.getUnderlyingRecordNumber());
|
||||
|
||||
DataType underlyingType = underlyingApplier.getCycleBreakType();
|
||||
if (underlyingType == null) {
|
||||
// TODO: we have seen underlyingTypeApplier is for NoTypeApplier for VtShapeMsType
|
||||
// Figure it out, and perhaps create an applier that creates a structure or something?
|
||||
underlyingType = applicator.getPdbPrimitiveTypeApplicator().getVoidType();
|
||||
applicator.appendLogMsg(
|
||||
"PDB Warning: No type conversion for " + underlyingApplier.getMsType().toString() +
|
||||
" as underlying type for pointer. Using void.");
|
||||
}
|
||||
return underlyingType;
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -112,9 +112,9 @@ public class TypeApplierFactory {
|
||||
applier =
|
||||
new MemberFunctionTypeApplier(applicator, (MemberFunction16MsType) type);
|
||||
break;
|
||||
// case VtShapeMsType.PDB_ID:
|
||||
// applier = new VtShapeTypeApplier(applicator, (VtShapeMsType) type);
|
||||
// break;
|
||||
case VtShapeMsType.PDB_ID:
|
||||
applier = new VtShapeTypeApplier(applicator, (VtShapeMsType) type);
|
||||
break;
|
||||
// case Cobol016MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
@@ -381,7 +381,7 @@ public class TypeApplierFactory {
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
|
||||
// 0x1500 block
|
||||
// 0x1500 block
|
||||
// case TypeServerMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
@@ -472,7 +472,7 @@ public class TypeApplierFactory {
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
|
||||
// 0x1600 block
|
||||
// 0x1600 block
|
||||
// case FunctionIdMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
|
||||
+11
-6
@@ -21,6 +21,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.RecordNumber;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.VoidDataType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
@@ -68,20 +69,24 @@ public class VirtualFunctionTablePointerTypeApplier extends MsTypeApplier {
|
||||
|
||||
@Override
|
||||
void apply() throws PdbException, CancelledException {
|
||||
if (msType instanceof AbstractVirtualFunctionTablePointerMsType) {
|
||||
if (msType instanceof AbstractVirtualFunctionTablePointerWithOffsetMsType vftPtrWOffset) {
|
||||
dataType = applyPointer(
|
||||
((AbstractVirtualFunctionTablePointerMsType) msType).getPointerTypeRecordNumber());
|
||||
vftPtrWOffset.getPointerTypeRecordNumber());
|
||||
}
|
||||
else if (msType instanceof AbstractVirtualFunctionTablePointerMsType vftPtr) {
|
||||
dataType = applyPointer(vftPtr.getPointerTypeRecordNumber());
|
||||
}
|
||||
else {
|
||||
dataType = applyPointer(
|
||||
((AbstractVirtualFunctionTablePointerWithOffsetMsType) msType).getPointerTypeRecordNumber());
|
||||
dataType = VoidDataType.dataType;
|
||||
applicator.appendLogMsg(
|
||||
"PDB Warning: Type not handled: " + msType.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private DataType applyPointer(RecordNumber pointerTypeRecordNumber) {
|
||||
MsTypeApplier rawApplier = applicator.getTypeApplier(pointerTypeRecordNumber);
|
||||
if (rawApplier instanceof PointerTypeApplier) {
|
||||
return rawApplier.getDataType();
|
||||
if (rawApplier instanceof PointerTypeApplier pointerApplier) {
|
||||
return pointerApplier.getDataType();
|
||||
}
|
||||
applicator.appendLogMsg("cannot process " + rawApplier.getClass().getSimpleName() + "for " +
|
||||
getClass().getSimpleName());
|
||||
|
||||
+60
-17
@@ -57,40 +57,83 @@ public class VtShapeTypeApplier extends MsTypeApplier {
|
||||
|
||||
@Override
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// Note that focused investigation as shown that both the VTShape as well as the pointer
|
||||
// to the particular VTShapes are not specific to one class; they can be shared by
|
||||
// totally unrelated classes; moreover, no duplicates of any VTShape or pointer to a
|
||||
// particular VTShape were found either. Because of this, for now, the VTShape is going
|
||||
// into an anonymous types category.
|
||||
dataType = createVtShape((VtShapeMsType) msType);
|
||||
}
|
||||
|
||||
// TODO: We are creating a structure for the vtshape. Is there anything different we would
|
||||
// like to do instead?
|
||||
private DataType createVtShape(VtShapeMsType msShape) throws CancelledException {
|
||||
// We are creating a structure for the vtshape.
|
||||
private DataType createVtShape(VtShapeMsType msShape)
|
||||
throws CancelledException {
|
||||
List<VtShapeDescriptorMsProperty> list = msShape.getDescriptorList();
|
||||
// TODO: what are correct/appropriate CategoryPath and name
|
||||
StructureDataType shape = new StructureDataType(applicator.getAnonymousTypesCategory(),
|
||||
"vtshape" + index, 0, applicator.getDataTypeManager());
|
||||
List<DefaultPdbUniversalMember> members = new ArrayList<>();
|
||||
int offset = 0;
|
||||
int defaultSize = applicator.getDataTypeManager().getDataOrganization().getPointerSize();
|
||||
// Since each element has its own property, we have to assume there can be mixed
|
||||
// properties in the table, thus each element must be set separately.
|
||||
// However, note that the data types referenced by the symbols (e.g., GDATAx) at the
|
||||
// vftable locations in memory seem to have these as an array of constant pointers to
|
||||
// functions with no argument and void return; to me, this does not quite agree with what
|
||||
// we have here where each element having its own pointer property. For now,
|
||||
// using a structure here. Moreover, we might want to eventually fix-up the arrays put
|
||||
// down with the GDATAx symbols with structures that contain pointers to func specs that
|
||||
// match the real function signatures at each element.
|
||||
for (VtShapeDescriptorMsProperty descriptor : list) {
|
||||
DataType elementType;
|
||||
switch (descriptor) {
|
||||
case NEAR:
|
||||
// near16:
|
||||
// 16-bit offset
|
||||
elementType = Undefined2DataType.dataType;
|
||||
break;
|
||||
case FAR:
|
||||
// far16:
|
||||
// 16-bit segment
|
||||
// 16-bit offset
|
||||
elementType = Undefined4DataType.dataType;
|
||||
break;
|
||||
case NEAR32:
|
||||
// near32:
|
||||
// 32-bit offset
|
||||
elementType = Undefined4DataType.dataType;
|
||||
break;
|
||||
case FAR32:
|
||||
// far32:
|
||||
// 16-bit segment
|
||||
// 32-bit offset
|
||||
elementType = Undefined6DataType.dataType;
|
||||
break;
|
||||
// lump remaining together; we do not know about thin, outer, or meta
|
||||
case UNUSED:
|
||||
// Special message for unused, followed by fall through case
|
||||
applicator.appendLogMsg("PDB Warning: UNUSED propery found in VTShape.");
|
||||
case THIN:
|
||||
case OUTER:
|
||||
case META:
|
||||
case NEAR32:
|
||||
case FAR32:
|
||||
Pointer pointer = new PointerDataType(applicator.getDataTypeManager());
|
||||
DefaultPdbUniversalMember member =
|
||||
new DefaultPdbUniversalMember(applicator, "", pointer, offset);
|
||||
offset += pointer.getLength();
|
||||
members.add(member);
|
||||
break;
|
||||
case UNUSED:
|
||||
offset += applicator.getDataOrganization().getPointerSize();
|
||||
break;
|
||||
default:
|
||||
// If any element type is not know, we will not return a full shape structure
|
||||
// Instead, we return void type.
|
||||
applicator.appendLogMsg(
|
||||
"PDB Warning: No type conversion for " + msShape.toString() +
|
||||
" as underlying type for pointer. Using void.");
|
||||
return VoidDataType.dataType;
|
||||
}
|
||||
int size = elementType.getLength();
|
||||
if (size == defaultSize) {
|
||||
elementType = PointerDataType.dataType;
|
||||
}
|
||||
DefaultPdbUniversalMember member =
|
||||
new DefaultPdbUniversalMember(applicator, "", elementType, offset);
|
||||
offset += size;
|
||||
members.add(member);
|
||||
}
|
||||
int size = applicator.getDataOrganization().getPointerSize() * msShape.getCount();
|
||||
if (!DefaultCompositeMember.applyDataTypeMembers(shape, false, size, members,
|
||||
// offset has the total size at this point
|
||||
if (!DefaultCompositeMember.applyDataTypeMembers(shape, false, offset, members,
|
||||
msg -> Msg.warn(this, msg), applicator.getCancelOnlyWrappingMonitor())) {
|
||||
CompositeTypeApplier.clearComponents(shape);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user