astrelsky / Ghidra-Cpp-Class-Analyzer

Ghidra C++ Class and Run Time Type Information Analyzer
MIT License
633 stars 46 forks source link

Vtable analysis doesn't seem to work on VC++ binaries #29

Closed jrmuizel closed 3 years ago

jrmuizel commented 3 years ago

Given the following program:

struct Bar {
        virtual int a(int x) = 0;
        virtual int b(double x, double y) = 0;
        virtual int get() = 0;
};

struct Foo : public Bar {
        int a(int ax) override {
                x = ax;
                return x;
        }
        int b(double ax, double ay) override {
                x = ax;
                y = ay;
                return y;
        }
        virtual int get() {
                return y;
        }
        int x;
        int y;
};

int main() {
        Bar* b = new Foo;
        b->a(4);
        b->b(6, 7);
        return b->get();
}

Foo and Bar don't seem to show up in the ClassTypeInfo Tree.

jrmuizel commented 3 years ago

Here's an x64 version compiled with VC++ 2019 Archive.zip

jrmuizel commented 3 years ago

And a x86 version compiled with VC++ 2008 Archive 2.zip

astrelsky commented 3 years ago

So 8cc330d should have solved the problem with Foo and Bar not showing up in the tree. I was accidentally excluding struct and union rtti.

I did notice that some vtables were missing functions. Most notable was std::exception missing the what function. I'm not sure if it is only the last function being trimmed off or if they are more. I suspect this is due to an issue with Ghidra's Windows rtti analyzer but I'd like to investigate further before I go pointing any fingers.

For the x64 program vtable analysis is intentionally not being run. This is due to the presence of control flow guard (CFG). When CFG is present some vtables will have pointers to the control flow functions instead of the actual virtual functions and I have no idea how to resolve the destination. Running the analyses when they are present causes much more harm than good so the analysis is automatically disabled.