win32平台关于“pure virtual function call”的解释

本博客(http://blog.csdn.net/livelylittlefish )贴出作者(三二一@小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!

 

Explanation about “pure virtual function call” on Win32 platform

 

Content

0. Introduction

1. an example

2. Disassemble code analysis

3. jump table of this program

4. _purecall function & its disassemble code

5. where is the message from?

5.1 _RT_PUREVIRT macro

5.2 _RT_PUREVIRT_TXT macro

5.3 rterrs array

6. which function does it prompt the message?

6.1 _NMSG_WRITE function

6.2 call stack

7. how does it be when the pure virtual function is implemented explicitly?

7.1 implement it inside of class

7.2 implement it outside of class

8. Summary

 

0. Introduction

 

In this article, we will not explain why does it prompt “pure virtual function call” and how to prompt “pure virtual function call”, but detailed explain the program itself when we call a pure virtual directly/indirectly in a constructor/destructor on win32 platform. This issue on Linux platform will be introduced in another article.

 

At the beginning, a classical example will be shown, in this example, it will prompt a message box with “pure virtual function call”.

 

1. An example

 

 

 

Running result: 

 

 

 

From the example, we can conclude that,

In constructor/destructor,

l   Direct call a pure virtual function, a compiling error will occur, such as

error LNK2001: unresolved external symbol "public: virtual double __thiscall Shape::area(void)const " (?area@Shape@@UBENXZ)

l   Indirect call a pure virtual function, it will prompt “pure virtual function call”

 

 

2. Disassemble code analysis

 

 

Debug this program, we can see the disassemble code of Shape::value() listed below, my comments embedded.

 

    double value() const

    {

004118F0  push        ebp 

004118F1  mov         ebp,esp

004118F3  sub         esp,0CCh

004118F9  push        ebx 

004118FA  push        esi 

004118FB  push        edi 

004118FC  push        ecx 

004118FD  lea         edi,[ebp-0CCh]

00411903  mov         ecx,33h

00411908  mov         eax,0CCCCCCCCh

0041190D  rep stos    dword ptr es:[edi]

0041190F  pop         ecx 

00411910  mov         dword ptr [ebp-8],ecx

    return ValuePerSquareUnit * area();

00411913  mov         eax,dword ptr [this]     //eax = 0x003b5fc0, move this pointer to eax

00411916  mov         edx,dword ptr [eax]      //edx = 0x00417800, move vfptr to edx

00411918  mov         esi,esp

0041191A  mov         ecx,dword ptr [this]    //ecx = 0x003b5fc0, move this pointer to ecx

0041191D  mov         eax,dword ptr [edx]     //eax = 0x004111f4, the address of __purecall, move the first virtual function address to eax

0041191F  call        eax                     //call this virtual function

00411921  cmp         esi,esp

00411923  call        @ILT+500(__RTC_CheckEsp) (4111F9h)

00411928  mov         ecx,dword ptr [this]

0041192B  fmul        qword ptr [ecx+8]

    }

0041192E  pop         edi 

0041192F  pop         esi 

00411930  pop         ebx 

00411931  add         esp,0CCh

00411937  cmp         ebp,esp

00411939  call        @ILT+500(__RTC_CheckEsp) (4111F9h)

0041193E  mov         esp,ebp

00411940  pop         ebp 

00411941  ret             

 

the disassemble codes and my comments can be verified from the following figure, which was captured from debuging. 

 

 

  

3. jump table of this program

 

To find the address of 0x004111f4, it is necessary to find the jump table of this program in the disassemble codes. Then, we find it listed below, which lists all jump items. 

 

00411005  jmp         _setdefaultprecision (413E80h)

0041100A  jmp         _setargv (413F20h)

0041100F  jmp         std::ios_base::good (41283Ah)

00411014  jmp         DebugBreak (414B78h)

00411019  jmp         _RTC_GetErrDesc (413BE0h)

0041101E  jmp         Rectangle::area (411BD0h)

00411023  jmp         __p__fmode (413F94h)

00411028  jmp         __security_check_cookie (412870h)

0041102D  jmp         IsDebuggerPresent (414B6Ch)

00411032  jmp         std::basic_ostream<char,std::char_traits<char> >::sentry::operator bool (412630h)

00411037  jmp         type_info::operator= (412BA0h)

0041103C  jmp         _RTC_Terminate (413F60h)

00411041  jmp         WideCharToMultiByte (414B7Eh)

<

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值