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:
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.
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.