RTTI 中用于 throw 的 mdisp 字段是什么?

逆向工程 拆卸 视窗 x86 C++ 微信
2021-06-14 02:32:46

首先是我正在查找字段的文章

我正在尝试不同的组合,看看它们如何影响 C++ 抛出的 RTTI。似乎拥有一个虚拟基类会更改下面的两个字段,mdisp但我无法更改mdisp此处的实际字段,这是我尝试过的:

struct B {
    int a, b;
};

struct A : virtual B {
    int b, c;
};
int main() {

    struct A* tmp = 0;

    throw tmp;
}

上述将改变的catchabletypesstruct A *struct B *具有用于不同的值pdispvdisp因为虚拟基类。

我也尝试过指向成员的指针,但也没有改变字段的运气:

struct A::* tmp = &A::c;

我假设上述内容会导致类型的字段发生变化,因为 A 的字段相对于 B 有一个偏移量。在这种特殊情况下,我还尝试删除继承的虚拟说明符。

这是拆卸的样子:

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
1个回答

似乎继承做到了。如果我们做这样的事情:

#include <stdio.h>
struct B {
    int a, b;
};

struct B1 {
    B1() = default;
    B1(const B1& tmp) {
        a1 = tmp.a1;
        printf("B1::B1 copy constr\n");
    }
    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("%d\n", tmp.a1);
}

我们得到了struct A包含struct B1以下信息的条目的抛出的 RTTI

.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