binaryninja-api
binaryninja-api copied to clipboard
Generalized `__ptr_offset` support in the type system
Suppose I have a type hierarchy looking like this:
struct S1ControllerBase __packed
{
struct `S1ControllerBase::__vftable`* __vftable;
// ... snip ...
};
struct __data_var_refs `S1ControllerBase::__vftable` __packed
{
// ... snip ...
};
struct IS1AnimEventHandler __packed
{
struct `IS1AnimEventHandler::__vftable`* __vftable;
// ... snip ...
};
struct __data_var_refs `IS1AnimEventHandler::__vftable` __packed
{
// ... snip ...
};
struct __base(S1ControllerBase, 0) __base(IS1AnimEventHandler, 0x8) S1SocialController __packed
{
struct `S1SocialController::__vftable`* __vftable;
struct `S1SocialController::__vftable_IS1AnimEventHandler`* __vftable_IS1AnimEventHandler;
// ... snip ...
};
struct __base(`S1ControllerBase::__vftable`, 0) __data_var_refs `S1SocialController::__vftable` __packed
{
// ... snip ...
};
struct __base(`IS1AnimEventHandler::__vftable`, 0) __data_var_refs `S1SocialController::__vftable_IS1AnimEventHandler` __packed
{
// ... snip ...
};
Now, suppose I have a member function on S1SocialController's vtable for IS1AnimEventHandler. The this pointer in this member function is going to be offset (specifically, to 0x8). AFAIK, there are 3 ways I can handle this:
- Type it as
void* __offset(S1SocialController, 0x8) this. - Type it as
IS1AnimEventHandler* __offset(S1SocialController, 0x8) this(or similar). - Create a new type using
__ptr_offsetand type it as that.
These all have problems:
- (1) isn't as precise as it could be.
- (2) doesn't work as I hoped unless I use the exact type of the field that sits at the offset (i.e.
S1SocialController::__vftable_IS1AnimEventHandler**), making it unwieldy and prone to becoming outdated as the types evolve. - (3) works but now requires me to define yet another thunk type (in which I also need to abuse
__baseto keep things sane).
As it stands, I always just use (1) when dealing with multiple inheritance. It gets mostly good results for minimal effort. Using __ptr_offset is just too much work for too little gain, and it still feels 'hacky' because of abusing __base like this:
struct __base(S1SocialController, 0) __ptr_offset(0x8) `S1SocialController::__thunk_IS1AnimEventHandler` __packed
{
// ... snip ...
};
The intent behind __ptr_offset is great, but attaching it to type definitions seems to me like it misses the mark. I think BN should allow using it directly in type syntax, as in S1SocialController* __ptr_offset(0x8) this, similar to __offset. Then you get the benefits without defining an extra type and abusing __base.
Has the team had a chance to contemplate this one? :eyes: