objdump ユーティリティと逆アセンブルされたコードを使用して、 VTABLE (対応する vptr)のアドレスを知るにはどうすればよいでしょうか。vptr は通常、オブジェクトの最初のバイトに格納されます (これを修正/編集してください)。仮想関数を使用したこの単純なコードがあります。
class base
{
public:
int x;
virtual void func()
{
//test function
}
};
class der : public base
{
void func()
{
//test function
}
};
/*
*
*/
int main() {
int s = 9;
base b;
der d ;
std::cout<<"the address of Vptr is = "<<(&b+0)<<std::endl;
std::cout<<"the value at Vptr is = "<<(int*)*(int*)((&b+0))<<std::endl;
return 0;
}
以下はコードの出力です:
the address of Vptr is = 0x7fff86a78fe0
the value at Vptr is = **0x400c30**
以下は main 関数の一部です - コードの逆アセンブル:
base b;
4009b4: 48 8d 45 d0 lea -0x30(%rbp),%rax
4009b8: 48 89 c7 mov %rax,%rdi
4009bb: e8 f4 00 00 00 callq 400ab4 <_ZN4baseC1Ev>
der d ;
4009c0: 48 8d 45 c0 lea -0x40(%rbp),%rax
4009c4: 48 89 c7 mov %rax,%rdi
4009c7: e8 fe 00 00 00 callq 400aca <_ZN3derC1Ev>
ここでは、_ZN4baseC1Ev がベース オブジェクトのアドレスであり、_ZN3derC1Ev が派生オブジェクトのアドレスであることを示しています。
_ZN4baseC1Ev で
0000000000400ab4 <_ZN4baseC1Ev>:
400ab4: 55 push %rbp
400ab5: 48 89 e5 mov %rsp,%rbp
400ab8: 48 89 7d f8 mov %rdi,-0x8(%rbp)
400abc: 48 8b 45 f8 mov -0x8(%rbp),%rax
400ac0: 48 c7 00 30 0c 40 00 movq $0x400c30,(%rax)
400ac7: c9 leaveq
400ac8: c3 retq
400ac9: 90 nop
0000000000400aca <_ZN3derC1Ev>:
}
#include<iostream>
class base
{
public:
int x;
virtual void func()
400a8a: 55 push %rbp
400a8b: 48 89 e5 mov %rsp,%rbp
400a8e: 48 89 7d f8 mov %rdi,-0x8(%rbp)
{
//test function
}
400a92: c9 leaveq
400a93: c3 retq
0000000000400a94 <_ZN3der4funcEv>:
};
class der : public base
{
void func()
400a94: 55 push %rbp
400a95: 48 89 e5 mov %rsp,%rbp
400a98: 48 89 7d f8 mov %rdi,-0x8(%rbp)
{
//test function
}
400a9c: c9 leaveq
400a9d: c3 retq
0000000000400a9e <_ZN4baseC2Ev>:
*/
#include <stdlib.h>
#include<iostream>
class base
{
400a9e: 55 push %rbp
400a9f: 48 89 e5 mov %rsp,%rbp
400aa2: 48 89 7d f8 mov %rdi,-0x8(%rbp)
400aa6: 48 8b 45 f8 mov -0x8(%rbp),%rax
400aaa: 48 c7 00 50 0c 40 00 movq $0x400c50,(%rax)
400ab1: c9 leaveq
400ab2: c3 retq
400ab3: 90 nop
0000000000400ab4 <_ZN4baseC1Ev>:
400ab4: 55 push %rbp
400ab5: 48 89 e5 mov %rsp,%rbp
400ab8: 48 89 7d f8 mov %rdi,-0x8(%rbp)
400abc: 48 8b 45 f8 mov -0x8(%rbp),%rax
400ac0: 48 c7 00 50 0c 40 00 movq $0x400c50,(%rax)
400ac7: c9 leaveq
400ac8: c3 retq
400ac9: 90 nop
0000000000400aca <_ZN3derC1Ev>:
}
};
objdump -S exeファイルの出力へのリンクは次のとおりです
また、objdump -t virtualfunctionsize | grep vtable はこれを与えます:
0000000000400c40 w O .rodata 0000000000000018 vtable for base
0000000000601e00 g O .dtors 0000000000000000 .hidden __DTOR_END__
0000000000400b00 g F .text 0000000000000089 __libc_csu_init
0000000000400c20 w O .rodata 0000000000000018 vtable for der
私が知りたかったのは、VTABLEアドレスとそれに対応する仮想関数がそれによって示されていることです。
Vptr のアドレスは = 0x7fff86a78fe0 です。これは何を表していますか - VTABLE の場所?
Vptr の値 = 0x400c30 - これは何を表していますか? 基本クラスの最初の仮想関数?
派生クラスの仮想関数の後続のアドレスを見つけるにはどうすればよいですか?
Rgds、ソフト