Reverse Engineering Asked on June 23, 2021
First of here is the article from which I’m looking up the fields.
I was trying out different combinations to see how they affect the RTTI for a C++ throw. It seems that having a virtual base class changes the two fields below mdisp
but I wasn’t able to change the actual mdisp
field here is what I’ve tried:
struct B {
int a, b;
};
struct A : virtual B {
int b, c;
};
int main() {
struct A* tmp = 0;
throw tmp;
}
The above will change the catchabletypes of struct A *
and struct B *
to have different values for pdisp
and vdisp
because of the virtual base class.
I’ve also tried pointer to members but with the no luck of changing the field as well:
struct A::* tmp = &A::c;
I assumed that the above will cause the field for the type to change because there is an offset for the fields of A relative to B. I also tried removing the virtual specifier for the inheritance in this particular case.
Here is what the dissasembly looks like:
push offset __TI3PAUA@@ ; throw info for 'struct A *'
lea ecx, [ebp+var_8]
push ecx
call sub_401BB4
.rdata:004130C0 __TI3PAUA@@ dd 0 ; DATA XREF: _main+13↑o
.rdata:004130C0 ; attributes
.rdata:004130C4 dd 0 ; destructor of exception object
.rdata:004130C8 dd 0 ; forward compatibility frame handler
.rdata:004130CC dd offset __CTA3PAUA@@ ; address of catchable types array
.rdata:004130D0 __CTA3PAUA@@ dd 3 ; DATA XREF: .rdata:004130CC↑o
.rdata:004130D0 ; count of catchable type addresses following
.rdata:004130D4 dd offset __CT??_R0PAUA@@@8 ; catchable type 'struct A *'
.rdata:004130D8 dd offset __CT??_R0PAUB@@@8 ; catchable type 'struct B *'
.rdata:004130DC dd offset __CT??_R0PAX@8 ; catchable type 'void *'
.rdata:004130E0 __CT??_R0PAUA@@@8 dd CT_IsSimpleType or CT_HasVirtualBase
.rdata:004130E0 ; DATA XREF: .rdata:004130D4↑o
.rdata:004130E0 ; attributes
.rdata:004130E4 dd offset ??_R0PAUA@@@8 ; A * `RTTI Type Descriptor'
.rdata:004130E8 dd 0 ; mdisp
.rdata:004130EC dd -1 ; pdisp
.rdata:004130F0 dd 0 ; vdisp
.rdata:004130F4 dd 4 ; size of thrown object
.rdata:004130F8 dd 0 ; reference to optional copy constructor
.rdata:004130FC __CT??_R0PAUB@@@8 dd CT_IsSimpleType ; DATA XREF: .rdata:004130D8↑o
.rdata:004130FC ; attributes
.rdata:00413100 dd offset ??_R0PAUB@@@8 ; B * `RTTI Type Descriptor'
.rdata:00413104 dd 0 ; mdisp
.rdata:00413108 dd 0 ; pdisp
.rdata:0041310C dd 4 ; vdisp
.rdata:00413110 dd 4 ; size of thrown object
.rdata:00413114 dd 0 ; reference to optional copy constructor
.rdata:00413118 __CT??_R0PAX@8 dd CT_IsSimpleType ; DATA XREF: .rdata:004130DC↑o
.rdata:00413118 ; attributes
.rdata:0041311C dd offset ??_R0PAX@8 ; void * `RTTI Type Descriptor'
.rdata:00413120 dd 0 ; mdisp
.rdata:00413124 dd -1 ; pdisp
.rdata:00413128 dd 0 ; vdisp
.rdata:0041312C dd 4 ; size of thrown object
.rdata:00413130 dd 0 ; reference to optional copy constructor
It seems that inheritance does it. If we do something like:
#include <stdio.h>
struct B {
int a, b;
};
struct B1 {
B1() = default;
B1(const B1& tmp) {
a1 = tmp.a1;
printf("B1::B1 copy constrn");
}
int a1, b1;
};
struct A : B, B1 {
int b, c;
};
int main() try {
struct A tmp;
tmp.a1 = 9;
throw tmp;
}
catch (B1 tmp) {
printf("%dn", tmp.a1);
}
We got RTTI for the throw of struct A
containing an entry of struct B1
with the following info:
.rdata:00419D8C __CT??_R0?AUB1@@@8_401150 dd 0 ; DATA XREF: .rdata:00419D50↑o
.rdata:00419D8C ; attributes
.rdata:00419D90 dd offset ??_R0?AUB1@@@8 ; B1 `RTTI Type Descriptor'
.rdata:00419D94 dd 8 ; mdisp
.rdata:00419D98 dd -1 ; pdisp
.rdata:00419D9C dd 0 ; vdisp
.rdata:00419DA0 dd 8 ; size of thrown object
.rdata:00419DA4 dd offset sub_401150 ; reference to optional copy constructo
Answered by rec on June 23, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP