mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 05:38:17 +08:00
GP-1036 Improved RTTI handling of null pointer values. Changed IBO
pointers to return null for 0 value to retain backward compatibility. Improved datatype drag onto root to preserve source category path.
This commit is contained in:
+6
@@ -338,6 +338,12 @@ public class DataTypeTreeCopyMoveTask extends Task {
|
|||||||
DataTypeManager nodeDtm = dataType.getDataTypeManager();
|
DataTypeManager nodeDtm = dataType.getDataTypeManager();
|
||||||
boolean sameManager = (dtm == nodeDtm);
|
boolean sameManager = (dtm == nodeDtm);
|
||||||
DataType newDt = !sameManager ? dataType.clone(nodeDtm) : dataType.copy(nodeDtm);
|
DataType newDt = !sameManager ? dataType.clone(nodeDtm) : dataType.copy(nodeDtm);
|
||||||
|
|
||||||
|
if (!sameManager && toCategory.isRoot()) {
|
||||||
|
// preserve use of source category when copy to root
|
||||||
|
toCategory = dtm.createCategory(dataType.getCategoryPath());
|
||||||
|
}
|
||||||
|
|
||||||
if (sameManager && newDt.getCategoryPath().equals(toCategory.getCategoryPath())) {
|
if (sameManager && newDt.getCategoryPath().equals(toCategory.getCategoryPath())) {
|
||||||
renameAsCopy(toCategory, newDt);
|
renameAsCopy(toCategory, newDt);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -138,7 +138,7 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Address spareDataAddress = getSpareDataAddress();
|
Address spareDataAddress = getSpareDataAddress();
|
||||||
if (spareDataAddress != null && spareDataAddress.getOffset() != 0L &&
|
if (spareDataAddress != null && spareDataAddress.getOffset() != 0 &&
|
||||||
!loadedAndInitializedSet.contains(spareDataAddress)) {
|
!loadedAndInitializedSet.contains(spareDataAddress)) {
|
||||||
throw new InvalidDataTypeException(getName() + " data type at " + getAddress() +
|
throw new InvalidDataTypeException(getName() + " data type at " + getAddress() +
|
||||||
" doesn't point to a spare data address in a loaded and initialized memory block.");
|
" doesn't point to a spare data address in a loaded and initialized memory block.");
|
||||||
@@ -360,8 +360,7 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
|
|||||||
Address vfTableAddress;
|
Address vfTableAddress;
|
||||||
// component 0 is either vf table pointer or hash value.
|
// component 0 is either vf table pointer or hash value.
|
||||||
vfTableAddress = EHDataTypeUtilities.getAddress(getDataType(), VF_TABLE_OR_HASH_ORDINAL, getMemBuffer());
|
vfTableAddress = EHDataTypeUtilities.getAddress(getDataType(), VF_TABLE_OR_HASH_ORDINAL, getMemBuffer());
|
||||||
|
return (vfTableAddress != null && vfTableAddress.getOffset() != 0) ? vfTableAddress : null;
|
||||||
return vfTableAddress.getOffset() != 0 ? vfTableAddress : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -393,7 +392,7 @@ public class TypeDescriptorModel extends AbstractCreateDataTypeModel {
|
|||||||
// component 1 is the spare data.
|
// component 1 is the spare data.
|
||||||
Address spareAddress =
|
Address spareAddress =
|
||||||
EHDataTypeUtilities.getAddress(getDataType(), SPARE_ORDINAL, getMemBuffer());
|
EHDataTypeUtilities.getAddress(getDataType(), SPARE_ORDINAL, getMemBuffer());
|
||||||
return spareAddress.getOffset() != 0 ? spareAddress : null;
|
return (spareAddress != null && spareAddress.getOffset() != 0) ? spareAddress : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+1
-1
@@ -122,7 +122,7 @@ public class Rtti1Model extends AbstractCreateRttiDataModel {
|
|||||||
// First component is either a direct reference or an image base offset.
|
// First component is either a direct reference or an image base offset.
|
||||||
Address rtti0Address = getReferencedAddress(program, startAddress);
|
Address rtti0Address = getReferencedAddress(program, startAddress);
|
||||||
if (rtti0Address == null) {
|
if (rtti0Address == null) {
|
||||||
invalid(); // throws Exception
|
invalid("Invalid TypeDescriptor reference (pTypeDescriptor)."); // throws Exception
|
||||||
}
|
}
|
||||||
rtti0Model = new TypeDescriptorModel(program, rtti0Address, validationOptions);
|
rtti0Model = new TypeDescriptorModel(program, rtti0Address, validationOptions);
|
||||||
if (validateReferredToData) {
|
if (validateReferredToData) {
|
||||||
|
|||||||
@@ -241,6 +241,9 @@ public class SettingsImpl implements Settings, Serializable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearAllSettings() {
|
public void clearAllSettings() {
|
||||||
|
if (map.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (checkSetting(null, null)) {
|
if (checkSetting(null, null)) {
|
||||||
map.clear();
|
map.clear();
|
||||||
changed();
|
changed();
|
||||||
|
|||||||
+13
-4
@@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.program.database.data;
|
package ghidra.program.database.data;
|
||||||
|
|
||||||
import ghidra.program.model.address.AddressFactory;
|
import ghidra.docking.settings.Settings;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,12 +60,21 @@ public class PointerTypedefInspector {
|
|||||||
if (!pointerTypeDef.isPointer()) {
|
if (!pointerTypeDef.isPointer()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Settings settings = pointerTypeDef.getDefaultSettings();
|
||||||
String spaceName =
|
String spaceName =
|
||||||
AddressSpaceSettingsDefinition.DEF.getValue(pointerTypeDef.getDefaultSettings());
|
AddressSpaceSettingsDefinition.DEF.getValue(settings);
|
||||||
if (spaceName == null) {
|
if (spaceName == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return addrFactory.getAddressSpace(spaceName);
|
AddressSpace addressSpace = addrFactory.getAddressSpace(spaceName);
|
||||||
|
if (addressSpace instanceof SegmentedAddressSpace) {
|
||||||
|
// Other settings do not apply when SegmentedAddressSpace is used
|
||||||
|
// see PointerDataType.getAddressValue(MemBuffer, int, Settings)
|
||||||
|
return addressSpace;
|
||||||
|
}
|
||||||
|
// Address space setting ignored if Pointer Type has been specified
|
||||||
|
PointerType choice = PointerTypeSettingsDefinition.DEF.getType(settings);
|
||||||
|
return choice == PointerType.DEFAULT ? addressSpace : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-1
@@ -41,7 +41,9 @@ public class DataTypeMnemonicSettingsDefinition implements EnumSettingsDefinitio
|
|||||||
/**
|
/**
|
||||||
* Returns the format based on the specified settings
|
* Returns the format based on the specified settings
|
||||||
* @param settings the instance settings.
|
* @param settings the instance settings.
|
||||||
* @return the format value (HEX, DECIMAL, BINARY, OCTAL, CHAR)
|
* @return the mnemonic style (DEFAULT, ASSEMBLY, CSPEC).
|
||||||
|
* The ASSEMBLY style is returned if no setting has been made.
|
||||||
|
* The DEFAULT style corresponds to the use of {@link DataType#getName()}.
|
||||||
*/
|
*/
|
||||||
public int getMnemonicStyle(Settings settings) {
|
public int getMnemonicStyle(Settings settings) {
|
||||||
if (settings == null) {
|
if (settings == null) {
|
||||||
|
|||||||
+35
-29
@@ -368,6 +368,7 @@ public class PointerDataType extends BuiltIn implements Pointer {
|
|||||||
Program program = mem.getProgram();
|
Program program = mem.getProgram();
|
||||||
String spaceName = AddressSpaceSettingsDefinition.DEF.getValue(settings);
|
String spaceName = AddressSpaceSettingsDefinition.DEF.getValue(settings);
|
||||||
if (spaceName != null) {
|
if (spaceName != null) {
|
||||||
|
// this space may be ignored if pointer type specified
|
||||||
targetSpace = program.getAddressFactory().getAddressSpace(spaceName);
|
targetSpace = program.getAddressFactory().getAddressSpace(spaceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,12 +378,13 @@ public class PointerDataType extends BuiltIn implements Pointer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (targetSpace instanceof SegmentedAddressSpace) {
|
if (targetSpace instanceof SegmentedAddressSpace) {
|
||||||
// ignore other settings
|
// ignore other settings with SegmentedAddressSpace use
|
||||||
return getAddressValue(buf, size, targetSpace);
|
return getAddressValue(buf, size, targetSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
Long offset = getStoredOffset(buf, size);
|
Long offset = getStoredOffset(buf, size);
|
||||||
if (offset == null) {
|
if (offset == null) {
|
||||||
|
// Insufficient bytes
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +405,13 @@ public class PointerDataType extends BuiltIn implements Pointer {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
PointerType choice = PointerTypeSettingsDefinition.DEF.getType(settings);
|
PointerType choice = PointerTypeSettingsDefinition.DEF.getType(settings);
|
||||||
|
// Address space setting ignored if Pointer Type has been specified
|
||||||
if (choice == PointerType.IMAGE_BASE_RELATIVE && mem != null) {
|
if (choice == PointerType.IMAGE_BASE_RELATIVE && mem != null) {
|
||||||
|
if (addrOffset == 0) {
|
||||||
|
// Done for consistency with old ImageBaseOffsetDataType.
|
||||||
|
// A 0 relative offset is considerd invalid (NaP)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// must ignore AddressSpaceSettingsDefinition
|
// must ignore AddressSpaceSettingsDefinition
|
||||||
Address imageBase = mem.getProgram().getImageBase();
|
Address imageBase = mem.getProgram().getImageBase();
|
||||||
targetSpace = imageBase.getAddressSpace();
|
targetSpace = imageBase.getAddressSpace();
|
||||||
@@ -464,10 +472,16 @@ public class PointerDataType extends BuiltIn implements Pointer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Long offset = getStoredOffset(buf, size);
|
||||||
|
if (offset == null) {
|
||||||
|
// Insufficient bytes
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (targetSpace instanceof SegmentedAddressSpace) {
|
if (targetSpace instanceof SegmentedAddressSpace) {
|
||||||
try {
|
try {
|
||||||
// NOTE: conversion assumes a little-endian space
|
// NOTE: conversion assumes a little-endian space
|
||||||
return getSegmentedAddressValue(buf, size);
|
return getSegmentedAddressValue(buf, size, offset);
|
||||||
}
|
}
|
||||||
catch (AddressOutOfBoundsException e) {
|
catch (AddressOutOfBoundsException e) {
|
||||||
// offset too large
|
// offset too large
|
||||||
@@ -482,14 +496,13 @@ public class PointerDataType extends BuiltIn implements Pointer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Long offset = getStoredOffset(buf, size);
|
|
||||||
if (offset != null) {
|
|
||||||
try {
|
try {
|
||||||
return targetSpace.getAddress(offset, true);
|
return targetSpace.getAddress(offset, true);
|
||||||
}
|
}
|
||||||
catch (AddressOutOfBoundsException e) {
|
catch (AddressOutOfBoundsException e) {
|
||||||
// offset too large
|
// offset too large
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -503,27 +516,20 @@ public class PointerDataType extends BuiltIn implements Pointer {
|
|||||||
* @return address value returned as segmented Address object or null for
|
* @return address value returned as segmented Address object or null for
|
||||||
* unsupported pointer length or meory access error occurs.
|
* unsupported pointer length or meory access error occurs.
|
||||||
*/
|
*/
|
||||||
private static Address getSegmentedAddressValue(MemBuffer buf, int dataLen) {
|
private static Address getSegmentedAddressValue(MemBuffer buf, int dataLen, long storedOffset) {
|
||||||
SegmentedAddress a = (SegmentedAddress) buf.getAddress();
|
SegmentedAddress a = (SegmentedAddress) buf.getAddress();
|
||||||
int segment = a.getSegment();
|
int segment = a.getSegment();
|
||||||
int offset = 0;
|
int offset;
|
||||||
try {
|
switch (dataLen) {
|
||||||
switch (dataLen) {
|
case 2: // near pointer
|
||||||
case 2: // near pointer
|
offset = (int) (storedOffset & 0xffff);
|
||||||
offset = buf.getUnsignedShort(0);
|
break;
|
||||||
break;
|
case 4: // far pointer
|
||||||
case 4: // far pointer
|
segment = (int) ((storedOffset >> 16) & 0xffff);
|
||||||
long value = buf.getUnsignedInt(0);
|
offset = (int) (storedOffset & 0xffff);
|
||||||
segment = (int) (value >> 16);
|
break;
|
||||||
offset = (int) (value & 0xffff);
|
default:
|
||||||
break;
|
return null;
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (MemoryAccessException e) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
SegmentedAddressSpace space = (SegmentedAddressSpace) a.getAddressSpace();
|
SegmentedAddressSpace space = (SegmentedAddressSpace) a.getAddressSpace();
|
||||||
SegmentedAddress addr = space.getAddress(segment, offset);
|
SegmentedAddress addr = space.getAddress(segment, offset);
|
||||||
|
|||||||
+2
-1
@@ -43,7 +43,8 @@ public class PointerTypeSettingsDefinition
|
|||||||
/**
|
/**
|
||||||
* Returns the format based on the specified settings
|
* Returns the format based on the specified settings
|
||||||
* @param settings the instance settings or null for default value.
|
* @param settings the instance settings or null for default value.
|
||||||
* @return the format value (HEX, DECIMAL, BINARY, OCTAL, CHAR)
|
* @return the {@link PointerType}. {@link PointerType#DEFAULT} will be returned
|
||||||
|
* if no setting has been made.
|
||||||
*/
|
*/
|
||||||
public PointerType getType(Settings settings) {
|
public PointerType getType(Settings settings) {
|
||||||
if (settings == null) {
|
if (settings == null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user