rizinorg / rizin

UNIX-like reverse engineering framework and command-line toolset.
https://rizin.re
GNU Lesser General Public License v3.0
2.64k stars 352 forks source link

[FR] Identify class member variables in disassembly #3746

Open FalcoGer opened 2 years ago

FalcoGer commented 2 years ago

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 commented 2 years ago

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

ITAYC0HEN commented 2 years ago

CC @thestr4ng3r

XVilka commented 1 year ago

@FalcoGer could you please attach a binary?

FalcoGer commented 1 year ago

@FalcoGer could you please attach a binary?

@XVilka here you go

cutter_person_test.zip