Vector35 / Vector35/binaryninja-api

Generalized `__ptr_offset` support in the type system

Open
#5,196 1 comment 4 reactions 1 assignee View on GitHub

@rssor is already working on this.

Since Apr 4, 2024.

State: Awaiting Triage
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:

  1. Type it as void* __offset(S1SocialController, 0x8) this.
  2. Type it as IS1AnimEventHandler* __offset(S1SocialController, 0x8) this (or similar).
  3. Create a new type using __ptr_offset and 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 __base to 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.