CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

请教一个关于thunk技术的问题,请进!

楼主CrazyAzreal(顶..真系稳食艰难!)2006-11-03 03:09:08 在 C/C++ / C++ 语言 提问

关于thunk我的理解是,thunk技术就是在内存里开辟一片空间,存放我们在程序运行时写入的代码,然后让程序跳转到我们开辟的空间,去执行这些代码。而对于让类的成员函数作为回调函数这样的情况,其实就是把调用类的成员函数的语句“call   成员函数”这句代码放到刚才开辟的那片空间去,然后再以该空间的首地址,作为回调函数的首地址传入对应函数去,是这样吗?  
   
  在看了http://blog.csdn.net/superarhow/archive/2006/07/10/898261.aspx这篇文章后,我跟了好久。。都没搞清楚这篇文章里的STDACJMPProc里面的汇编代码是做是什么用的?CalcJmpOffset这个函数又是做什么用的??在我的机子上,执行完下面那四句话  
  p->_this   =   (long)m_pThis;  
  p->_func   =   *(long   *)&m_pFunc;  
  p->tag   =   0xE8;  
  p->offset   =   CalcJmpOffset((long)p,   (long)STDACJMPProc);  
  后,内存里是这样  
  01190000     E8   2B   21   27   FF   48   4C     .+!'.HL  
  01190007     36   00   B4   10   40   00   00     6...@..  
   
  即call   2B   21   27(这句我明白,不过2B   21   27这个地址我跟进去,好像是STDACJMPProc的地址,那为什么还需经过CalcJmpOffset计算才赋值给offset呢?)  
      FF   48   4C   36     00   B4   10   40   (那么这句对应的汇编代码是什么呢?)  
   
   
  有领悟了的大哥指教一吓啊`谢谢! 问题点数:40、回复次数:5Top

1 楼superarhow(苏泊尔耗)回复于 2006-11-03 08:43:19 得分 25

由此看来,这篇贴子的作者一定很帅~~~~  
   
  内存里生成的内容是这样:  
  CALL   STDACJMPProc  
  DD     offset   func  
  DD     offset   this_pointer  
   
  就这样跳到STDACJMPProc里面时,栈首的指针就指向DD   offset   func的地址。那段汇编代码就是把地址pop出来,然后取到func和this_pointer,把this_pointer放到ECX中再调用func,效果就和有this指针的一样了。  
   
  因为我们用的CALL(0xE8)是CALL   NEAR   PTR,所以CALL后面的地址是相对地址,所以要用那个CalcJmpOffset计算一下。Top

2 楼akirya(坏[其实偶不是什么所谓的坏人])回复于 2006-11-03 08:55:15 得分 0

这个vckbase上有篇文章讲。推荐用ollydbg调试Top

3 楼jixingzhong(瞌睡虫·星辰)回复于 2006-11-03 09:03:49 得分 5

http://dev.csdn.net/develop/article/15/15747.shtm  
   
  “我对C++中THUNK一种实现技术的分析”Top

4 楼mLee79()回复于 2006-11-03 09:13:46 得分 10

我一般都是   mov   eax   ,   procAddr   ;   call   eax   ,   这样做比较方便,   不用计算偏移   .....  
  这东西,   VC   调试照样方便   ...  
  以前写的   :  
   
  #include   <windows.h>  
  #include   <stdio.h>  
   
  class   mTimer  
  {  
  BYTE       m_cdTrk[16];  
  static   void   CALLBACK   tTimerProcStatic(   mTimer*   _pTHIS   ){_pTHIS->tTimerProc();   }  
  protected:  
  UINT       m_nIDEvent;  
  UINT       m_uElapse;  
  virtual   void   tTimerProc()   =   0;  
  public:  
  mTimer(   UINT   uElapse   )     :   m_uElapse(   uElapse   )   ,   m_nIDEvent(   0   ){  
  void*   pTHIS   =   this;   void*   procTimer   =   (void*)mTimer::tTimerProcStatic;  
  memcpy(   m_cdTrk   ,   "\x68\0\0\0\0\xB8\0\0\0\0\xFF\xD0\xC2\x10\x00"   ,   16   );  
  memcpy(   m_cdTrk   +   1   ,   &pTHIS   ,   4   );memcpy(   m_cdTrk   +   6   ,   &procTimer     ,   4   );}  
  virtual   ~mTimer()   {   StopTimer();   }  
  public:  
  void   StartTimer()   {   StopTimer();   m_nIDEvent   =   SetTimer(   NULL   ,   0   ,   m_uElapse   ,   (TIMERPROC)(void*)(m_cdTrk)   );   }  
  void   StopTimer()     {   if(   m_nIDEvent   )   {   KillTimer(   NULL   ,   m_nIDEvent   );   m_nIDEvent   =   0;   }   }  
  };  
  class   testTimer1   :   public   mTimer  
  {  
  virtual   void   tTimerProc(){  
  printf(   "testTimer1::tTimerProc   ID:   %d   ,   COUNT:   %d.\n"   ,   m_nIDEvent   ,   m_count++   );  
  if(   m_count   >   10   )   PostQuitMessage(0);}  
  public:  
  UINT   m_count;  
  testTimer1(   UINT   u   =   1000   )   :   mTimer(   u   )   ,   m_count(0)   {}  
  };  
  class   testTimer2   :   public   mTimer  
  {  
  virtual   void   tTimerProc(){printf(   "testTimer2::tTimerProc   ID:   %d   \n"   ,   m_nIDEvent   );}  
  public:  
  testTimer2(   UINT   u   =   1000   )   :   mTimer(   u   )   {}  
  };  
  int   main()  
  {  
  MSG   msg;  
  testTimer1   tmR;  
  testTimer2   tmR2(500);  
  tmR.StartTimer();  
  tmR2.StartTimer();  
  while(   GetMessage(   &msg   ,   NULL   ,   0   ,   0   )   )    
  DispatchMessage(   &msg   );  
   
  return   0;  
  }  
   
  Top

5 楼CrazyAzreal(顶..真系稳食艰难!)回复于 2006-11-03 10:36:21 得分 0

哈哈`明白了``我跟的时候,死活就是没往寄存器窗口看一眼。汗死``谢谢各位大虾了!Top

相关问题

关键词

得分解答快速导航

  • 帖主:CrazyAzreal
  • superarhow
  • jixingzhong
  • mLee79

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo