Vector35 / Vector35/binaryninja-api
Generalized `__ptr_offset` support in the type system
@rssor is already working on this.
Since Apr 4, 2024.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 298
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 19
Description
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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.