Unable to change structure member type using API.
Version and Platform (required):
- Binary Ninja Version: Tested on Enterprise
4.1.5747and4.0.5336. - OS: Mac OS X
- OS Version: 14
- CPU Architecture: AARCH64
Bug Description:
Unable to change type of inlined StructureTypes present within already defined StructureType.
This was discovered when attempting to fix up a load of inline types which are present from DWARF debug info. (Likely related to: https://github.com/Vector35/binaryninja-api/issues/5328).
Steps To Reproduce: Can recreate issue by creating the following two types within a new BinaryView:
struct test_struct_a __packed
{
int32_t lol;
int32_t lol_b;
struct
{
int32_t a;
int32_t b;
} inlined_test_struct_b;
};
struct test_struct_b __packed
{
int32_t a;
int32_t b;
};
To demonstrate issue with API:
original = bv.types['test_struct_a']
mutable = original.mutable_copy()
mutable.replace(mutable.index_by_offset(0x8), bv.types['test_struct_b'], 'replaced_test_struct_b')
bv.define_user_type('test_struct_a', mutable)
The following code will rename the "inlined_test_struct_b" member to "replaced_test_struct_b", but the type remains inlined and does not change. The same behaviour is exhibited when also replacing inlined EnumerationTypes.
I have also completed further testing, including trying mutable.remove followed by mutable.insert/mutable.add_member_at_offset, which results in the same unexpected behaviour.
Expected Behavior:
The type of "replaced_test_struct_b" should be test_struct_b. However it remains the inlined type.
The resulting final struct should resemble:
struct test_struct_a __packed
{
int32_t lol;
int32_t lol_b;
struct test_struct_b replaced_test_struct_b;
};
Binary:
Not applicable, can be replicated on empty BinaryView.
So with further testing, I was able to achieve the expected behaviour by using the Type.registered_name field.
>>> original = bv.types['test_struct_a']
... mutable = original.mutable_copy()
... mutable.replace(mutable.index_by_offset(0x8), bv.types['test_struct_b'].registered_name, 'replaced_test_struct_b')
... bv.define_user_type('test_struct_a', mutable)
...
Not sure if this issue is just due to my API misusage?