Skip to content

Commit 9397b24

Browse files
committed
types: fragment type API support (C++, Python)
1 parent db98ed6 commit 9397b24

File tree

6 files changed

+383
-20
lines changed

6 files changed

+383
-20
lines changed

binaryninjaapi.h

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10676,22 +10676,6 @@ namespace BinaryNinja {
1067610676

1067710677
/*! Retrieve the Type Class for this Structure
1067810678

10679-
One of:
10680-
10681-
VoidTypeClass
10682-
BoolTypeClass
10683-
IntegerTypeClass
10684-
FloatTypeClass
10685-
StructureTypeClass
10686-
EnumerationTypeClass
10687-
PointerTypeClass
10688-
ArrayTypeClass
10689-
FunctionTypeClass
10690-
VarArgsTypeClass
10691-
ValueTypeClass
10692-
NamedTypeReferenceClass
10693-
WideCharTypeClass
10694-
1069510679
\return The type class
1069610680
*/
1069710681
BNTypeClass GetClass() const;
@@ -10801,6 +10785,14 @@ namespace BinaryNinja {
1080110785
BNPointerBaseType GetPointerBaseType() const;
1080210786
int64_t GetPointerBaseOffset() const;
1080310787

10788+
uint64_t GetFragmentOriginalOffsetBytes() const;
10789+
size_t GetFragmentOriginalWidthBytes() const;
10790+
size_t GetFragmentStartBit() const;
10791+
size_t GetFragmentWidthBits() const;
10792+
size_t GetFragmentTruncatedStartBits() const;
10793+
size_t GetFragmentWrapBit() const;
10794+
BNEndianness GetFragmentEndianness() const;
10795+
1080410796
std::set<BNPointerSuffix> GetPointerSuffix() const;
1080510797
std::string GetPointerSuffixString() const;
1080610798
std::vector<InstructionTextToken> GetPointerSuffixTokens(uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
@@ -10917,6 +10909,33 @@ namespace BinaryNinja {
1091710909
const Confidence<bool>& cnst = Confidence<bool>(false, 0),
1091810910
const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType);
1091910911

10912+
/*! Create a Fragment type, which represents a bounded load from an existing type
10913+
10914+
\param width Width of the fragment in bytes
10915+
\param type Type that this fragment was loaded from
10916+
\param offset Offset into type that this fragment represents
10917+
\param endianness Endianness of the load operation creating the fragment
10918+
\return The created type
10919+
*/
10920+
static Ref<Type> FragmentType(size_t width, const Confidence<Ref<Type>>& type, uint64_t offset, BNEndianness endianness);
10921+
10922+
/*! Create a Fragment type, which represents a bounded load from an existing type
10923+
10924+
\param width Width of the fragment in its current storage location; can be larger/smaller than the original fragment load
10925+
\param type Type that this fragment was loaded from
10926+
\param originalFragmentOffsetBytes Offset into type that this fragment represents
10927+
\param originalFragmentWidthBytes Width of the initial load that created the fragment
10928+
\param endianness Endianness of the load operation creating the fragment
10929+
\param fragmentStartBit Logical bit position inside the fragment container where fragment data starts (0 = lsb of fragment type)
10930+
\param fragmentWidthBits Number of remaining contiguous bits still represented in the fragment type
10931+
\param fragmentTruncatedStartBits Number of low-order bits of fragment data lost
10932+
\param wrapBit Logical bit position inside the fragment container where fragment data wraps around (0 = irrelevant)
10933+
\return The created type
10934+
*/
10935+
static Ref<Type> FragmentType(size_t width, const Confidence<Ref<Type>>& type,
10936+
uint64_t originalFragmentOffsetBytes, size_t originalFragmentWidthBytes, BNEndianness endianness,
10937+
size_t fragmentStartBit, size_t fragmentWidthBits, size_t fragmentTruncatedStartBits, size_t wrapBit = 0);
10938+
1092010939
/*! Create an Array Type
1092110940

1092210941
\param type Type for Elements contained in this Array
@@ -11217,12 +11236,28 @@ namespace BinaryNinja {
1121711236
BNPointerBaseType GetPointerBaseType() const;
1121811237
int64_t GetPointerBaseOffset() const;
1121911238

11239+
uint64_t GetFragmentOriginalOffsetBytes() const;
11240+
size_t GetFragmentOriginalWidthBytes() const;
11241+
size_t GetFragmentStartBit() const;
11242+
size_t GetFragmentWidthBits() const;
11243+
size_t GetFragmentTruncatedStartBits() const;
11244+
size_t GetFragmentWrapBit() const;
11245+
BNEndianness GetFragmentEndianness() const;
11246+
1122011247
TypeBuilder& SetOffset(uint64_t offset);
1122111248
TypeBuilder& SetFunctionCanReturn(const Confidence<bool>& canReturn);
1122211249
TypeBuilder& SetPure(const Confidence<bool>& pure);
1122311250
TypeBuilder& SetParameters(const std::vector<FunctionParameter>& params);
1122411251
TypeBuilder& SetPointerBase(BNPointerBaseType baseType, int64_t baseOffset);
1122511252

11253+
TypeBuilder& SetFragmentOriginalOffsetBytes(uint64_t offset);
11254+
TypeBuilder& SetFragmentOriginalWidthBytes(size_t size);
11255+
TypeBuilder& SetFragmentStartBit(size_t startBit);
11256+
TypeBuilder& SetFragmentWidthBits(size_t widthBits);
11257+
TypeBuilder& SetFragmentTruncatedStartBits(size_t truncatedBits);
11258+
TypeBuilder& SetFragmentWrapBit(size_t wrapBit);
11259+
TypeBuilder& SetFragmentEndianness(BNEndianness endianness);
11260+
1122611261
std::set<BNPointerSuffix> GetPointerSuffix() const;
1122711262
std::string GetPointerSuffixString() const;
1122811263
std::vector<InstructionTextToken> GetPointerSuffixTokens(uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
@@ -11274,6 +11309,10 @@ namespace BinaryNinja {
1127411309
static TypeBuilder PointerType(size_t width, const Confidence<Ref<Type>>& type,
1127511310
const Confidence<bool>& cnst = Confidence<bool>(false, 0),
1127611311
const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType);
11312+
static TypeBuilder FragmentType(size_t width, const Confidence<Ref<Type>>& type, uint64_t offset, BNEndianness endianness);
11313+
static TypeBuilder FragmentType(size_t width, const Confidence<Ref<Type>>& type,
11314+
uint64_t originalFragmentOffsetBytes, size_t originalFragmentWidthBytes, BNEndianness endianness,
11315+
size_t fragmentStartBit, size_t fragmentWidthBits, size_t fragmentTruncatedStartBits, size_t wrapBit = 0);
1127711316
static TypeBuilder ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem);
1127811317
static TypeBuilder FunctionType(const Confidence<Ref<Type>>& returnValue,
1127911318
const Confidence<Ref<CallingConvention>>& callingConvention, const std::vector<FunctionParameter>& params,

binaryninjacore.h

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 163
40+
#define BN_CURRENT_CORE_ABI_VERSION 164
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 163
47+
#define BN_MINIMUM_CORE_ABI_VERSION 164
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -871,7 +871,8 @@ extern "C"
871871
VarArgsTypeClass = 9,
872872
ValueTypeClass = 10,
873873
NamedTypeReferenceClass = 11,
874-
WideCharTypeClass = 12
874+
WideCharTypeClass = 12,
875+
FragmentTypeClass = 13,
875876
};
876877

877878
BN_ENUM(uint8_t, BNNamedTypeReferenceClass)
@@ -7006,6 +7007,11 @@ extern "C"
70067007
BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType);
70077008
BINARYNINJACOREAPI BNType* BNCreatePointerTypeOfWidth(size_t width, const BNTypeWithConfidence* const type,
70087009
BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType);
7010+
BINARYNINJACOREAPI BNType* BNCreateFragmentType(size_t width, const BNTypeWithConfidence* const type,
7011+
uint64_t offset, BNEndianness endianness);
7012+
BINARYNINJACOREAPI BNType* BNCreateFragmentTypeBits(size_t width, const BNTypeWithConfidence* const type,
7013+
uint64_t originalFragmentOffsetBytes, size_t originalFragmentWidthBytes, BNEndianness endianness,
7014+
size_t fragmentStartBit, size_t fragmentWidthBits, size_t fragmentTruncatedStartBits, size_t wrapBit);
70097015
BINARYNINJACOREAPI BNType* BNCreateArrayType(const BNTypeWithConfidence* const type, uint64_t elem);
70107016
BINARYNINJACOREAPI BNType* BNCreateFunctionType(BNTypeWithConfidence* returnValue, BNCallingConventionWithConfidence* callingConvention,
70117017
BNFunctionParameter* params, size_t paramCount, BNBoolWithConfidence* varArg,
@@ -7041,6 +7047,11 @@ extern "C"
70417047
BINARYNINJACOREAPI BNTypeBuilder* BNCreatePointerTypeBuilderOfWidth(size_t width,
70427048
const BNTypeWithConfidence* const type, BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl,
70437049
BNReferenceType refType);
7050+
BINARYNINJACOREAPI BNTypeBuilder* BNCreateFragmentTypeBuilder(size_t width, const BNTypeWithConfidence* const type,
7051+
uint64_t offset, BNEndianness endianness);
7052+
BINARYNINJACOREAPI BNTypeBuilder* BNCreateFragmentTypeBuilderBits(size_t width, const BNTypeWithConfidence* const type,
7053+
uint64_t originalFragmentOffsetBytes, size_t originalFragmentWidthBytes, BNEndianness endianness,
7054+
size_t fragmentStartBit, size_t fragmentWidthBits, size_t fragmentTruncatedStartBits, size_t wrapBit);
70447055
BINARYNINJACOREAPI BNTypeBuilder* BNCreateArrayTypeBuilder(const BNTypeWithConfidence* const type, uint64_t elem);
70457056
BINARYNINJACOREAPI BNTypeBuilder* BNCreateFunctionTypeBuilder(BNTypeWithConfidence* returnValue, BNCallingConventionWithConfidence* callingConvention,
70467057
BNFunctionParameter* params, size_t paramCount, BNBoolWithConfidence* varArg,
@@ -7078,6 +7089,13 @@ extern "C"
70787089
BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type);
70797090
BINARYNINJACOREAPI uint64_t BNGetTypeElementCount(BNType* type);
70807091
BINARYNINJACOREAPI uint64_t BNGetTypeOffset(BNType* type);
7092+
BINARYNINJACOREAPI uint64_t BNGetTypeFragmentOriginalOffsetBytes(BNType* type);
7093+
BINARYNINJACOREAPI size_t BNGetTypeFragmentOriginalWidthBytes(BNType* type);
7094+
BINARYNINJACOREAPI size_t BNGetTypeFragmentStartBit(BNType* type);
7095+
BINARYNINJACOREAPI size_t BNGetTypeFragmentWidthBits(BNType* type);
7096+
BINARYNINJACOREAPI size_t BNGetTypeFragmentTruncatedStartBits(BNType* type);
7097+
BINARYNINJACOREAPI size_t BNGetTypeFragmentWrapBit(BNType* type);
7098+
BINARYNINJACOREAPI BNEndianness BNGetTypeFragmentEndianness(BNType* type);
70817099
BINARYNINJACOREAPI BNOffsetWithConfidence BNGetTypeStackAdjustment(BNType* type);
70827100
BINARYNINJACOREAPI BNQualifiedName BNTypeGetStructureName(BNType* type);
70837101
BINARYNINJACOREAPI BNNamedTypeReference* BNGetRegisteredTypeName(BNType* type);
@@ -7145,8 +7163,22 @@ extern "C"
71457163
BINARYNINJACOREAPI void BNSetTypeBuilderNamedTypeReference(BNTypeBuilder* type, BNNamedTypeReference* ntr);
71467164
BINARYNINJACOREAPI uint64_t BNGetTypeBuilderElementCount(BNTypeBuilder* type);
71477165
BINARYNINJACOREAPI uint64_t BNGetTypeBuilderOffset(BNTypeBuilder* type);
7166+
BINARYNINJACOREAPI uint64_t BNGetTypeBuilderFragmentOriginalOffsetBytes(BNTypeBuilder* type);
7167+
BINARYNINJACOREAPI size_t BNGetTypeBuilderFragmentOriginalWidthBytes(BNTypeBuilder* type);
7168+
BINARYNINJACOREAPI size_t BNGetTypeBuilderFragmentStartBit(BNTypeBuilder* type);
7169+
BINARYNINJACOREAPI size_t BNGetTypeBuilderFragmentWidthBits(BNTypeBuilder* type);
7170+
BINARYNINJACOREAPI size_t BNGetTypeBuilderFragmentTruncatedStartBits(BNTypeBuilder* type);
7171+
BINARYNINJACOREAPI size_t BNGetTypeBuilderFragmentWrapBit(BNTypeBuilder* type);
7172+
BINARYNINJACOREAPI BNEndianness BNGetTypeBuilderFragmentEndianness(BNTypeBuilder* type);
71487173
BINARYNINJACOREAPI void BNSetTypeBuilderOffset(BNTypeBuilder* type, uint64_t offset);
71497174
BINARYNINJACOREAPI void BNSetTypeBuilderPointerBase(BNTypeBuilder* type, BNPointerBaseType baseType, int64_t baseOffset);
7175+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentOriginalOffsetBytes(BNTypeBuilder* type, uint64_t offset);
7176+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentOriginalWidthBytes(BNTypeBuilder* type, size_t size);
7177+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentStartBit(BNTypeBuilder* type, size_t startBit);
7178+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentWidthBits(BNTypeBuilder* type, size_t widthBits);
7179+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentTruncatedStartBits(BNTypeBuilder* type, size_t truncatedBits);
7180+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentWrapBit(BNTypeBuilder* type, size_t wrapBit);
7181+
BINARYNINJACOREAPI void BNSetTypeBuilderFragmentEndianness(BNTypeBuilder* type, BNEndianness endianness);
71507182
BINARYNINJACOREAPI void BNSetFunctionTypeBuilderCanReturn(BNTypeBuilder* type, BNBoolWithConfidence* canReturn);
71517183
BINARYNINJACOREAPI void BNSetTypeBuilderPure(BNTypeBuilder* type, BNBoolWithConfidence* pure);
71527184
BINARYNINJACOREAPI void BNSetFunctionTypeBuilderParameters(

plugins/dwarf/dwarf_export/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,10 @@ fn export_type(
401401
);
402402
Some(wide_char_die_uid)
403403
}
404+
TypeClass::FragmentTypeClass => {
405+
tracing::error!("Fragment types are not representable in DWARF");
406+
None
407+
}
404408
}
405409
}
406410

plugins/warp/src/convert/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ pub fn from_bn_type_internal(
244244
};
245245
TypeClass::Character(char_class)
246246
}
247+
BNTypeClass::FragmentTypeClass => {
248+
// XXX: possibly unrepresentable?
249+
TypeClass::Void
250+
}
247251
};
248252

249253
let name = raw_ty.registered_name().map(|n| n.name().to_string());

python/types.py

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
ReferenceType, VariableSourceType,
3232
TypeReferenceType, MemberAccess, MemberScope, TypeDefinitionLineType,
3333
TokenEscapingType,
34-
NameType, PointerSuffix, PointerBaseType
34+
NameType, PointerSuffix, PointerBaseType,
35+
Endianness
3536
)
3637
from . import callingconvention
3738
from . import function as _function
@@ -655,6 +656,7 @@ def immutable_copy(self):
655656
TypeClass.StructureTypeClass: StructureType,
656657
TypeClass.EnumerationTypeClass: EnumerationType,
657658
TypeClass.NamedTypeReferenceClass: NamedTypeReferenceType,
659+
TypeClass.FragmentTypeClass: FragmentType,
658660
}
659661
return Types[self.type_class](self._finalized, self.platform, self.confidence)
660662

@@ -1125,6 +1127,74 @@ def pointer_base_offset(self) -> int:
11251127
def pointer_base_offset(self, value: int):
11261128
self.set_pointer_base(self.pointer_base_type, value)
11271129

1130+
class FragmentBuilder(TypeBuilder):
1131+
@classmethod
1132+
def create(
1133+
cls, type: SomeType, width: int,
1134+
offset: int, endianness: Endianness = Endianness.LittleEndian,
1135+
confidence: int = core.max_confidence
1136+
) -> 'FragmentBuilder':
1137+
ic = type.immutable_copy()
1138+
handle = core.BNCreateFragmentTypeBuilder(width, ic._to_core_struct(), offset, endianness)
1139+
assert handle is not None, "BNCreateFragmentTypeBuilder returned None"
1140+
return cls(handle, None, confidence)
1141+
1142+
@property
1143+
def offset(self) -> int:
1144+
return core.BNGetTypeBuilderFragmentOriginalOffsetBytes(self._handle)
1145+
1146+
@offset.setter
1147+
def offset(self, value: int):
1148+
core.BNSetTypeBuilderFragmentOriginalOffsetBytes(self._handle, value)
1149+
1150+
@property
1151+
def fragment_original_width(self) -> int:
1152+
return core.BNGetTypeBuilderFragmentOriginalWidthBytes(self._handle)
1153+
1154+
@fragment_original_width.setter
1155+
def fragment_original_width(self, value: int):
1156+
core.BNSetTypeBuilderFragmentOriginalWidthBytes(self._handle, value)
1157+
1158+
@property
1159+
def fragment_start_bit(self) -> int:
1160+
return core.BNGetTypeBuilderFragmentStartBit(self._handle)
1161+
1162+
@fragment_start_bit.setter
1163+
def fragment_start_bit(self, value: int):
1164+
core.BNSetTypeBuilderFragmentStartBit(self._handle, value)
1165+
1166+
@property
1167+
def fragment_width_bits(self) -> int:
1168+
return core.BNGetTypeBuilderFragmentWidthBits(self._handle)
1169+
1170+
@fragment_width_bits.setter
1171+
def fragment_width_bits(self, value: int):
1172+
core.BNSetTypeBuilderFragmentWidthBits(self._handle, value)
1173+
1174+
@property
1175+
def fragment_truncated_start_bits(self) -> int:
1176+
return core.BNGetTypeBuilderFragmentTruncatedStartBits(self._handle)
1177+
1178+
@fragment_truncated_start_bits.setter
1179+
def fragment_truncated_start_bits(self, value: int):
1180+
core.BNSetTypeBuilderFragmentTruncatedStartBits(self._handle, value)
1181+
1182+
@property
1183+
def fragment_wrap_bit(self) -> int:
1184+
return core.BNGetTypeBuilderFragmentWrapBit(self._handle)
1185+
1186+
@fragment_wrap_bit.setter
1187+
def fragment_wrap_bit(self, value: int):
1188+
core.BNSetTypeBuilderFragmentWrapBit(self._handle, value)
1189+
1190+
@property
1191+
def endianness(self) -> Endianness:
1192+
return Endianness(core.BNGetTypeBuilderFragmentEndianness(self._handle))
1193+
1194+
@endianness.setter
1195+
def endianness(self, value: Endianness):
1196+
core.BNSetTypeBuilderFragmentEndianness(self._handle, value)
1197+
11281198

11291199
class ArrayBuilder(TypeBuilder):
11301200
@classmethod
@@ -2289,6 +2359,7 @@ def mutable_copy(self) -> 'TypeBuilder':
22892359
TypeClass.IntegerTypeClass: IntegerBuilder, TypeClass.FloatTypeClass: FloatBuilder,
22902360
TypeClass.PointerTypeClass: PointerBuilder, TypeClass.ArrayTypeClass: ArrayBuilder,
22912361
TypeClass.FunctionTypeClass: FunctionBuilder, TypeClass.WideCharTypeClass: WideCharBuilder,
2362+
TypeClass.FragmentTypeClass: FragmentBuilder,
22922363
# TypeClass.StructureTypeClass:Structure,
22932364
# TypeClass.EnumerationTypeClass:Enumeration,
22942365
# TypeClass.NamedTypeReferenceClass:NamedTypeReference,
@@ -3484,13 +3555,43 @@ def create(
34843555
assert core_type is not None, "core.BNCreateWideCharType returned None"
34853556
return cls(core_type, platform, confidence)
34863557

3558+
class FragmentType(Type):
3559+
@property
3560+
def offset(self) -> int:
3561+
return core.BNGetTypeFragmentOriginalOffsetBytes(self._handle)
3562+
3563+
@property
3564+
def fragment_original_width_bytes(self) -> int:
3565+
return core.BNGetTypeFragmentOriginalWidthBytes(self._handle)
3566+
3567+
@property
3568+
def fragment_start_bit(self) -> int:
3569+
return core.BNGetTypeFragmentStartBit(self._handle)
3570+
3571+
@property
3572+
def fragment_width_bits(self) -> int:
3573+
return core.BNGetTypeFragmentWidthBits(self._handle)
3574+
3575+
@property
3576+
def fragment_truncated_start_bits(self) -> int:
3577+
return core.BNGetTypeFragmentTruncatedStartBits(self._handle)
3578+
3579+
@property
3580+
def fragment_wrap_bit(self) -> int:
3581+
return core.BNGetTypeFragmentWrapBit(self._handle)
3582+
3583+
@property
3584+
def fragment_endianness(self) -> Endianness:
3585+
return Endianness(core.BNGetTypeFragmentEndianness(self._handle))
3586+
34873587

34883588
Types = {
34893589
TypeClass.VoidTypeClass: VoidType, TypeClass.BoolTypeClass: BoolType, TypeClass.IntegerTypeClass: IntegerType,
34903590
TypeClass.FloatTypeClass: FloatType, TypeClass.StructureTypeClass: StructureType,
34913591
TypeClass.EnumerationTypeClass: EnumerationType, TypeClass.PointerTypeClass: PointerType,
34923592
TypeClass.ArrayTypeClass: ArrayType, TypeClass.FunctionTypeClass: FunctionType,
34933593
TypeClass.NamedTypeReferenceClass: NamedTypeReferenceType, TypeClass.WideCharTypeClass: WideCharType,
3594+
TypeClass.FragmentTypeClass: FragmentType,
34943595
}
34953596

34963597

0 commit comments

Comments
 (0)