Skip to content

Conversation

jmillikin
Copy link
Contributor

This adds a new ptroff metatype to the decompiler, which represents a typed pointer offset.

Given the following type definition:

<type metatype="ptroff" name="child-vtable-to-parent-a" id="0x1234500001" size="8">
  <typeref name="Child" id="0x100000000000015"/>
  <typeref name="Parent_A" id="0x100000000000013"/>
</type>

A PTRADD(0: Child*, 1: child-vtable-to-parent-a) op will have an output type of Parent_A*.

The new type allows the decompiler to better handle runtime field lookups, as seen in (for example) C++ virtual inheritance. More details and motivation in issue #5855.

Output of current master/HEAD:

int __thiscall Child::Caller(Child *this)

{
  int iVar1;
  int iVar2;

  iVar1 = *(int *)(&this->field_0x8 + ADJ(this->vtable)->as_Parent_B);
  iVar2 = Parent_A::Callee_A((Parent_A *)((long)&this->vtable + ADJ(this->vtable)->as_Parent_A));
  return iVar2 + iVar1;
}

Output with typed pointer offsets -- note how the parent_b_data field is now correctly resolved relative to the offset target type:

int __thiscall Child::Caller(Child *this)

{
  int iVar1;
  int iVar2;

  iVar1 = OFF(this,ADJ(this->vtable)->as_Parent_B)->parent_b_data[0];
  iVar2 = Parent_A::Callee_A(OFF(this,ADJ(this->vtable)->as_Parent_A));
  return iVar2 + iVar1;
}

@jmillikin
Copy link
Contributor Author

Note to reviewers: I tried my best to match the style and idioms of the existing code, but the Ghidra decompiler is very different from the C++ I'm used to so there may be stylistic and/or logical errors.

Sample decompiler input XML: ghidra-vtables-decompile.xml.gz

I plan to add UI support for defining pointer offsets separately, probably as a pointer typedef (similar to ptrrel).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature: Decompiler Status: Triage Information is being gathered

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants