cutter icon indicating copy to clipboard operation
cutter copied to clipboard

[FR] Identify class member variables in disassembly

Open FalcoGer opened this issue 2 years ago • 2 comments

Is your feature request related to a problem? Please describe.

Using debug information or dynamic analysis, one might figure out the layout of a class. For example code like this is fairly straight forward:

class Person
{
    private:
        int _age;
        int _height;
    public:
        Person() = delete;
        Person(const int age, const int height) : _age{age}, _height{height} {}
        inline int getAge() const { return _age; }
        inline void setAge(const int age) { _age = age; }
        inline int getHeight() const { return _height; }
        inline void setHeight(const int height) { _height = height; }
};

You know that this + 0x00 is _age and this + 0x04 is _height

I have recently seen a feature of the binary ninja decompiler here. If given the structure of an object it can resolve member access with useful names. You could get such information for example with ptype Person when running such a program in GDB.

It would be great if such a feature could be implemented for rizin/cutter as well.

Describe the solution you'd like

A way to edit the member variables of of class/struct, then any references to them being replaced with the clear text. Something like this for example:

image

Describe alternatives you've considered

Additional context

Full test case, compile with g++ -O0 -g main.cpp -o main:

// main.cpp
#include <iostream>

class Person
{
    private:
        int _age;
        int _height;
    public:
        Person() = delete;
        Person(const int age, const int height) : _age{age}, _height{height} {}
        inline int getAge() const { return _age; }
        inline void setAge(const int age) { _age = age; }
        inline int getHeight() const { return _height; }
        inline void setHeight(const int height) { _height = height; }
        inline void print() const
        {
            std::cout << getAge() << ", " << getHeight() << std::endl;
        }
};

int main(int argc, char** argv, char** envr)
{
    auto p = Person(20, 180);
    p.print();
    p.setAge(30);
    p.setHeight(190);
    p.print();
    return 0;
}

gdb output:

gdb main
GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
GEF for linux ready, type `gef' to start, `gef config' to configure
96 commands loaded for GDB 12.0.90 using Python engine 3.10
Reading symbols from main...
gef➤  ptype Person
type = class Person {
  private:
    int _age;
    int _height;

  public:
    Person(void);
    Person(int, int);
    int getAge(void) const;
    void setAge(int);
    int getHeight(void) const;
    void setHeight(int);
    void print(void) const;
}
gef➤

FalcoGer avatar Jul 25 '22 01:07 FalcoGer

Perhaps the disassembly should be replaced by dword [ rax + 4 ] ; {int64_t Person::_height} instead. putting this there doesn't really add a lot.

FalcoGer avatar Jul 25 '22 02:07 FalcoGer

CC @thestr4ng3r

ITAYC0HEN avatar Jul 25 '22 04:07 ITAYC0HEN