Does Ghidra's type system directly support inheritance, polymorphism, and/or multiple inheritance? #2368
-
I'm conducting a comparative analysis of IDA vs. Ghidra for C++ reverse engineering. I want the comparison to be fair, and not marred by my own ignorance of Ghidra. Hence, I have a few questions to ensure I haven't overlooked anything. Roughly speaking, if I have a C++ class with a few data items and virtual functions, e.g.:
It's easy to create a structure for Now let's suppose I have a derived class, as follows:
One might imagine trying to "simulate" inheritance by creating a However, the problem with this is that the VTable type for IDA 7.2 added the ability to change the VTable type in derived classes, thus solving this issue. We could represent the situation above using these declarations:
As you can see, IDA 7.2+ offers true support for polymorphism in inheritance, using familiar syntax ( Does Ghidra support something akin to the above -- direct specification of inheritance relationships, with the ability to override VTable types in derived objects? IDA 7.2 also added support for multiple inheritance ( For overridden virtual functions in Does Ghidra have anything comparable for multiple inheritance? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 1 reply
-
Not yet. The type system doesn't directly support virtual multiple inheritance yet. There is an open pull request for shifted pointers. If given the ability to have the decompiler assume a struct member is a constant value, coupled with the shifted pointers, I could make all of this work with my plugin. |
Beta Was this translation helpful? Give feedback.
-
Virtual inheritance was the one form of inheritance I hadn't mentioned in my questions above. (To be clear we're using the same terminology: virtual inheritance is not the same thing as virtual functions; it refers to sharing the data from common base classes during multiple inheritance.) Although I did write a virtual inheritance plugin for Hex-Rays, I don't think it's very realistic for any reverse engineering tool's type system to support it directly, given the vastly different implementations across compilers. Or did you mean "inheritance of virtual functions" rather than "virtual inheritance"? |
Beta Was this translation helpful? Give feedback.
-
I did indeed mean virtual inheritance. For the vftable a pointer to a structure full of function definitions does a good job. Virtual inheritance could be handled. Both the visual studio and gcc/clang implementations strip each virtual base of their virtual bases and then append them to the end of the class in order. The dynamic virtual base lookup is different as visual studio utilizes a separate _vbptr whilegcc/clang use just one _vptr. I don't think it is too absurd to support. I have written a plugin which leverages rtti to rebuild the class structure. Most of it is hacky due to the lack of support in the type system but it does a fairly decent job. The only thing really holding it back is that the virtual base offset doesn't get resolved because there is no way to tell the decompiler the constant value being read from the vbtable even though it only needs to assume the value based on index. |
Beta Was this translation helpful? Give feedback.
-
Okay. Yes, your last paragraph describes roughly how my Hex-Rays plugin for virtual inheritance worked. I'll publish it eventually; for now, here's a screenshot. (There was a similar idea underlying another plugin I wrote for virtual function resolution). In any case, this is going adrift of my original intention, which was to get an authoritative answer from the Ghidra developers on the current status of direct type-system support for single inheritance, polymorphism, and multiple inheritance. Thank you for your comments. |
Beta Was this translation helpful? Give feedback.
-
@RolfRolles we currently don't support true inheritance as well as mixing structure definitions with class methods directly as a Class data type. They have been on the books to do for quite a while. There have been various attempts to add general support for a class mostly in the form of namespaces as Classes, and Class folders in the datatypes with various definitions for class components. These generally fall short because they are conventions and are not enforced nor do they affect things like the debugger in the correct way. In addition, conventions don't work well if you are trying to RE something where you are recovering the hierarchy where methods signatures will be edited, new class relation ships discovered. Cross references would also need to be addressed. There have been many folks using Ghidra to recover RTTI type information and apply them. There is a script we will be including soon that creates classes probably very similarly to what is described above. However it will suffer from really a static view of the classes. There is a fairly big refactor of the datatype model to support this sort of thing, among others, that has also been on the books for quite a while. The re-design was scheduled to start last April. That said, we are hoping to get some support in 9.3 and 9.4. One necessary change "shifted pointers" in a pull request for shifted pointers that we have looked. Support for pointers declared as pointing to an offset into a larger structure will be necessary. The idea is a good idea but we need to study how it would fit with the other changes we are designing. The biggest issue is a database refactor to support this type of change and others in a general fashion, which is really all I can say at this point on support for shifted pointers. Function signatures as first class type objects handled as structures are an issue. Meaning function signatures exist as a definition in the type system and as an entry in the data type manager and both reflect the same information. This isn't as satisfying an answer as I'd like to provide. We've had many of these ideas for quite a while, however some of the features we currently support with the data type archives, merging, version tracking, program diffing, and general database extensions require a careful design to support. Expect to see some type model changes towards this end in the near future. |
Beta Was this translation helpful? Give feedback.
-
would like to know more about your results with this |
Beta Was this translation helpful? Give feedback.
@RolfRolles we currently don't support true inheritance as well as mixing structure definitions with class methods directly as a Class data type. They have been on the books to do for quite a while. There have been various attempts to add general support for a class mostly in the form of namespaces as Classes, and Class folders in the datatypes with various definitions for class components. These generally fall short because they are conventions and are not enforced nor do they affect things like the debugger in the correct way. In addition, conventions don't work well if you are trying to RE something where you are recovering the hierarchy where methods signatures will be edited, new cla…