Home > front end >  How to get the base class offset of an inherited struct without creating an instance
How to get the base class offset of an inherited struct without creating an instance

Time:11-26

Consider this code:

struct A {
    int64 member;
    int32 member2;
    virtual void f();
};

struct B {
    int16 member3;

    virtual void b();
};

struct C : A, B {
    virtual void b() override;
};

I'm interested in finding the offset of B in C. Previously with other structs with no virtual inheritance and only one base class offsetof of the first member seemed to work. I have decompiled some code (in IDA) and the base classes are nicely highlighted (hex) here:

screenshot

In a function those exact baseclass offsets are used to cast void*'s to derived classes by adding the offset to the void* (by casting to a char*). The structs A, B and C are similar to the one in the compiled code, which include classes with virtual functions and multiple base classes.

My question is how did they do that, and how can I do that? I've tried something like i32 offset = (i64)((B*)((C*)NULL)); but no luck.

CodePudding user response:

I tried the following, and it worked:

(char*)(B*)(C*)0x100 - (char*)(C*)0x100

It casts C* to B*; this is supposed to do the work. All the rest is support. I used an arbitrary number 0x100; it seems to work with all numbers except 0.

Why it doesn't work for 0: it sees a null-pointer of type C*; to convert it to a null-pointer of type B*, it should still be null. A special case.

Of course, this uses undefined behavior. It seems to work in Visual Studio in my short test program; no guarantee it will work anywhere else.

  • Related