Vector35 / Vector35/binaryninja-api

Derived class VFT definition uses multiple base VFT for multiple inheritence when debug symbols are present

Aperta
#4,967 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Component: DebugInfo DebugInfo: DWARF DebugInfo: PDB Effort: Medium Impact: Medium
Lingua principale
C++
Stelle
1.3k
Fork
298
Merge medio
5g 5h
PR unite (30g)
19

Descrizione

Version and Platform (required):

  • Binary Ninja Version: 3.6.4790-dev, 10b89271
  • OS: macos
  • OS Version: 14.3
  • CPU Architecture: arm64

Bug Description:
I have two base classes named Animal and Pet, and a Cat class derived from both of them. When I use a PDB and BN imports the types from it, BN generates vft types for these classes like this:

struct __data_var_refs Animal::VTable
{
    void* (* __vecDelDtor)(class Animal* this, uint32_t);
    void (* introduce)(class Animal const* this);
    void (* makeSound)(class Animal const* this);
    char const* (* getType)(class Animal const* this);
};

struct __data_var_refs Pet::VTable
{
    void* (* __vecDelDtor)(class Pet* this, uint32_t);
    void (* play)(class Pet const* this);
};

struct __base(Animal::VTable, 0) __base(Pet::VTable, 0) __data_var_refs Cat::VTable
{
    void* (* __vecDelDtor)(class Cat* this, uint32_t);
    __inherited void (* Pet::VTable::play)(class Pet const* this);
    __inherited void (* Animal::VTable::makeSound)(class Animal const* this);
    __inherited char const* (* Animal::VTable::getType)(class Animal const* this);
};

Notice that the VFT for Cat uses two base VFT for the same offset, resulting in the second function being overwritten with the Pet::play function from Pet's VFT definition, which is incorrect; instead, it should be introduce from Animal. When I remove the __base(Pet::VTable, 0) part from the type definition, the type transforms into this:

struct __base(Animal::VTable, 0) __data_var_refs Cat::VTable
{
    void* (* __vecDelDtor)(class Cat* this, uint32_t);
    __inherited void (* Animal::VTable::introduce)(class Animal const* this);
    __inherited void (* Animal::VTable::makeSound)(class Animal const* this);
    __inherited char const* (* Animal::VTable::getType)(class Animal const* this);
};

Which seems correct to me.

Steps To Reproduce:

  1. Download and build the attached source code using
    1. MSVC
    2. x64 architecture
    3. Release mode
    4. Debug symbols enabled
    5. Optimizations disabled
  2. Load the binary into the BN
  3. Check VFT definition for Cat class.

Additional Information:
class_test_source.zip

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Start with the attached class_test_source.zip and reproduce the issue by building it with MSVC, x64, release mode, debug symbols, and optimizations disabled, then load the binary in Binary Ninja. Inspect the generated Cat::VTable definition and the handling of its Animal and Pet base VFTs at the same offset. Done means the Cat definition preserves the expected Animal entries instead of overwriting one with Pet::play.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
cpp
Ambito
reverse-engineering
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.