今日の雑記

生きることでいっぱいいっぱい

センセー!うちではこうなりましたー!(VC 編)

大元 http://d.hatena.ne.jp/shinichiro_h/20061213#1165948550
元記事 http://www.kt.rim.or.jp/~kbk/zakkicho/zakkicho18.html#D20061214-1


#include
struct C {
void f() {}
virtual void vf() {}
};
int main() {
printf("%p\n", &C::f);
printf("%p\n", &C::vf);
}

00401005
0040100F
Cygwin では shinh さんとこのような結果になったんですが、確かに VC(6) だとこのような結果に。
(VC の)混合モードで表示してみた。

6: int main() {
00401030 push ebp
00401031 mov ebp,esp
00401033 sub esp,40h
00401036 push ebx
00401037 push esi
00401038 push edi
00401039 lea edi,[ebp-40h]
0040103C mov ecx,10h
00401041 mov eax,0CCCCCCCCh
00401046 rep stos dword ptr [edi]
7: printf("%p\n", &C::f);
00401048 push offset @ILT+0(C::f) (00401005)
0040104D push offset string "%p\n" (0042001c)
00401052 call printf (004010d0)
00401057 add esp,8
8: printf("%p\n", &C::vf);
0040105A push offset @ILT+10(`vcall') (0040100f)
0040105F push offset string "%p\n" (0042001c)
00401064 call printf (004010d0)
00401069 add esp,8
9: }
ほう。
んで、注目の「push offset @ILT+10(`vcall') (0040100f)」の「0040100f」を見てみよう。

@ILT+10(??_9@$BA@AE):
0040100F jmp `vcall' (004010c0)
その先。

`vcall':
004010C0 mov eax,dword ptr [ecx]
004010C2 jmp dword ptr [eax]
元記事の内容と同じですね。
んじゃ、複数にしてみましょう。

00401005
0040100F
00401014

00401030 push ebp
00401031 mov ebp,esp
00401033 sub esp,40h
00401036 push ebx
00401037 push esi
00401038 push edi
00401039 lea edi,[ebp-40h]
0040103C mov ecx,10h
00401041 mov eax,0CCCCCCCCh
00401046 rep stos dword ptr [edi]
8: printf("%p\n", &C::f);
00401048 push offset @ILT+0(C::f) (00401005)
0040104D push offset string "%p\n" (0042001c)
00401052 call printf (004010d0)
00401057 add esp,8
9: printf("%p\n", &C::vf);
0040105A push offset @ILT+10(`vcall') (0040100f)
0040105F push offset string "%p\n" (0042001c)
00401064 call printf (004010d0)
00401069 add esp,8
10: printf("%p\n", &C::vf2);
0040106C push offset @ILT+15(`vcall') (00401014)
00401071 push offset string "%p\n" (0042001c)
00401076 call printf (004010d0)
0040107B add esp,8
11: }

@ILT+10(??_9@$BA@AE):
0040100F jmp `vcall' (004010c0)
00401014 jmp `vcall' (0040b7c0)

`vcall':
004010C0 mov eax,dword ptr [ecx]
004010C2 jmp dword ptr [eax]

`vcall':
0040B7C0 mov eax,dword ptr [ecx]
0040B7C2 jmp dword ptr [eax+4]

基本的には同じ。ちゃんとテーブル的には「次の」アドレスを指してるっぽい。
しかし「vf2」はこれはまた偉く遠い所に配置されてますなあ...。理由は解らんけど。
以上、報告でした!(それだけ?