`
iwebcode
  • 浏览: 2071900 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

对类成员进行特殊操作(2) ---转贴

 
阅读更多
对类成员进行特殊操作(2)


发布者: 北斗龙 (进入北斗龙个人专栏)

评价等级:
代码下载
2位用户为此文章评分,平均分为4.0

大家在看了文章1后以经对取得虚函数地址有所了解,但用它作回调函数还是有一点问题,因为要使成员函数正确运行,我们必须每次在调用这前传一个this给ecx(对应的成员函数中没有操作类成员除外,原因见(文章1)),作为回调函数,它可不给你这个机会,那怎么实现呢?

下面就是一种实现方法:

我们可以在数据段中开一个数组,在这个数组里存放一些特殊的数据,然后将这个数组的地址作为回调函数的地址,然后这个数组将被作为代码运行。那么这个数组对应的代码又做些什么呢?很简单的:将对象的地址传入ecx, 然后jmp到真正的回调函数。

下面是个例子:

主要部分也就是ThunkInit(ThunkData t, void *This, int VirFucID);

传入一个数组指针,一个对象的指针,一个对应第几个虚函数。然后这个函数将生成对应的可执行代码:将对象的地址传入ecx, 最后jmp到真正的回调函数。

其次,就是用数组的地址作为函数地址,调用对应的函数时,先执行数组里的代码,这样就保证了函数内部的this指针的正确性。

例3

class CCC
{
public:
 CCC() {m_data1=50;}
 ~CCC() {};
 virtual void print1() { ::printf("m_data1=%dn", m_data1); }
 virtual void print2() { ::printf("m_data1+10=%dn", m_data1+10); }
 virtual void print3(int num) { ::printf("m_data1+%d=%dn", num, m_data1+num); }
private:
 int m_data1;
};

typedef unsigned char ThunkData[14];
void inline ThunkInit(ThunkData t, void *This, int VirFucID)
{ // begin ThunkInit
 t[0] = 0xB9; // mov ecx,
 *((long *)(t+1)) = (long) This; // this
*((short int *)(t+5)) = 0x018B; // mov eax, [ecx]
t[7] = 0x5; // add eax,
*((long *)(t+8)) = VirFucID*4; // VirFucID*4
*((short int *)(t+12)) = 0x20FF; // jmp [eax]
} // end ThunkInit
void print5Times1(long fucAddr)
{
int i=5;
 while(i--)
((void (__stdcall *)(void))fucAddr)();
}
void print5Times2(long fucAddr, int num)
{
int i=5;
 while(i--)
 ((void (__stdcall *)(int))fucAddr)(num);
}
void main()
{
 CCC cc;
 ThunkData fucAddr;
 //不做回调函数
 ThunkInit(fucAddr, &cc, 0);
 ((void (__stdcall *)(void))(long)fucAddr)();
 ThunkInit(fucAddr, &cc, 1);
 ((void (__stdcall *)(void))(long)fucAddr)();
 ThunkInit(fucAddr, &cc, 2);
 ((void (__stdcall *)(int))(long)fucAddr)(100);
 //做回调函数
 ThunkInit(fucAddr, &cc, 0);
 print5Times1((long)fucAddr);
 ThunkInit(fucAddr, &cc, 1);
 print5Times1((long)fucAddr);
 ThunkInit(fucAddr, &cc, 2);
 print5Times2((long)fucAddr, 100);
}

注意:

1. ((void (__stdcall *)(void))(long)fucAddr)();是将fucAddr的地址转换为long型,然后再将它转化为(void (__stdcall *)(void))类型函数(如有不明白,请找有关资料),最后调用此函数。
2. ThunkInit函数可能较难理解,下面是进一步的讲解:
t[0] = 0xB9; //这个操作码为 mov ecx, 它将把接下来的long立即数,送入ecx
*((long *)(t+1)) = (long) This; // this, 对应的对象的地址,在运行是将作立即数,送入ecx
*((short int *)(t+5)) = 0x018B; // mov eax, [ecx] 取得虚函数表的起始位置
t[7] = 0x5; // add eax,
*((long *)(t+8)) = VirFucID*4; //VirFucID*4 计算出存放对应虚函数地址的地址
*((short int *)(t+12)) = 0x20FF; // jmp [eax] 调转到以应的虚函数

最后我想加几句题外话,这些例子都只是简单的用应,文章1中两个例子没有实际意义,旨在为例3做铺垫。至于有没有用,我也不知,只是我在一些程序中应用了而己,刚开始只是从其它原码中拿过来用,也不解其中的原理。但一次在图书管中看了<编程深入引导>>(中国水利水电出版社)后,由于它详细说明了类的实现,并附了对应的汇编源码,让我豁然开朗,经过几翻测试,终于弄懂了它的原理,觉得做法挺不错,也就写了上面这些,文笔较差,还不知能否让大家看懂。

不过这种做法有点费涩难懂,在附件中的工程DD,演示了“静态成员函数+对象的静态指针”做回调函数,不过在这里得注意一点,后面这种做法,整个类只能定义一个对象(因为对象的静态指针)。

分享到:
评论

相关推荐

    行业分类-设备装置-FPC吸附胶纸转贴组件.zip

    这个组件在FPC的制造和组装过程中起到关键作用,确保FPC能够稳定地固定在设备上,并进行精确的连接。 FPC吸附胶纸,顾名思义,是专门用于吸附和固定FPC的一种特殊胶纸。它通常由基材、粘合剂和保护层三部分组成。...

    电脑故障维修判断指导大全---转贴

    这一原则要求我们在面对电脑故障时,首先要进行细致的观察,这包括对电脑所在环境的检查,例如电脑的放置位置、电源插座的稳定性、各类连线的连接状况等。同时,还应观察电脑的运行表现,比如是否能够正常开机、显示...

    电子政务-导电泡棉转贴装置.zip

    在“导电泡棉转贴装置”这个特定的场景下,我们可能是在讨论一种用于电子政务设备或系统中的特殊组件。 导电泡棉是一种具有导电性能的泡沫材料,通常用于电子设备的屏蔽、接地或防静电保护。在电子政务设备中,这种...

    电子功用-导电胶配对模切对半转贴加工方法

    对半转贴加工方法则是模切工艺的一种特殊应用,主要针对需要对称或匹配的导电胶部件。这种方法涉及将导电胶片裁切成两半,然后将这两半精确地对齐并贴合在一起,形成完整的导电路径。这种技术特别适用于那些需要紧密...

    flex和java进行CRUD操作(转贴)

    在IT行业中,Flex和Java是两种常用于构建富互联网应用...通过CRUD操作,我们可以实现对后台数据的有效管理,从而满足各种业务需求。而"flexdemo"提供的实例代码正是这一过程的具体体现,有助于开发者进一步提升技能。

    动易系统的论坛转贴工具 -ASP源码.zip

    开发者或者有兴趣学习ASP的人可以研究这个源码,理解如何在ASP环境中处理用户交互、数据库操作、论坛数据结构以及实现转贴功能的具体步骤。 压缩包内的“内容来自存起来软件站www.cqlsoft.com.txt”可能是一个文本...

    行业资料-电子功用-全自动导电布成型转贴穿管设备及工艺的介绍分析.rar

    3. **定位模块**:为了确保贴合和穿管的精确度,设备会使用精密的定位系统,确保导电布在正确的位置上进行后续操作。 4. **贴合模块**:将成型后的导电布贴合到目标物体上,可能涉及到热压、胶粘或其他方式。 5. *...

    论坛转贴 v1.0 JS版-源码.zip

    【标题】"论坛转贴 v1.0 JS版-源码.zip" 提供的是一个基于JavaScript的论坛转贴功能的源代码实现。JS版通常指的是使用JavaScript编程语言编写的版本,这表明该软件可能主要用于网页端,利用浏览器的JavaScript引擎...

    易语言动网转贴.rar

    4. **数据交互**:易语言可以处理各种数据类型,并且具备数据库操作能力,方便与数据库进行交互,这在论坛转贴功能中非常重要,因为帖子数据通常存储在数据库中。 关于"动网转贴"的具体实现,可能涉及到以下知识点...

    行业文档-设计装置-木器、玻璃用贴花纸生产及转贴方法.zip

    《木器、玻璃用贴花纸生产及转贴方法》是一个深入探讨装饰材料工艺的行业文档,主要聚焦于贴花纸在木器和玻璃制品上的应用。这份文档可能包含了从贴花纸的设计、生产到实际转贴过程中的各种技术细节和实践经验。 1....

    使用Struts2开发Java Web应用程序(转贴)

    此外,Struts2与Spring框架的集成非常紧密,能够利用Spring的依赖注入功能,简化Action类的管理,同时方便与其他框架如Hibernate、iBatis等进行集成。它支持多种结果类型,除了JSP外,还包括JasperReports报表、...

    动网转贴-易语言

    标题中的“动网转贴-易语言”表明这是一个基于易语言开发的系统工具,主要用于在论坛或网络上转发或分享内容。易语言是中国自主研发的一种高级编程语言,它以中文编程为特色,旨在降低编程难度,让更多人能参与到...

    易语言源码动网转贴.rar

    8. **安全防护**:防止恶意用户滥发帖子,可能需要设置转发频率限制,或者对转发内容进行审核,这些都需要在源码中实现。 9. **API接口调用**:如果动网是一个开放平台,那么转贴功能可能通过调用其他网站的公开API...

    动网转贴.e.rar

    如果是进行数据分析,可能需要对文件进行读取、清洗和转换,以便于使用数据分析工具(如Python的pandas库或Excel)进行处理。无论哪种情况,了解动网论坛的数据结构和文件格式都是至关重要的,这可能需要查阅相关的...

    Struts-menu源码分析(转贴).rar

    2. **MVC模式**: MVC模式是软件工程中的一个设计模式,将业务逻辑(Model)、用户界面(View)和数据控制(Controller)分离,使得开发更易于维护和扩展。在Struts-menu中,Model通常处理业务逻辑,View负责渲染...

    discuz X2转帖工具、采集工具

    2. 信息聚合:对于新闻资讯类论坛,可以通过采集功能快速收集并分享最新信息,提升论坛的新闻价值。 3. 数据分析:通过批量发布和转帖,可以进行用户行为分析,了解哪种类型的内容更受论坛用户欢迎。 综上所述,...

    jquery的转贴功能实现

    总的来说,实现jQuery的转贴功能需要对DOM操作、事件处理、Ajax请求以及不同社交网络的API有深入理解。通过合理地组织代码和利用jQuery的功能,可以创建一个高效且易于维护的分享系统,提升网站的互动性和用户参与度...

    [转贴]Symbian编程VC开发环境设置 (方便个人学习用,转载自 rocklys的专栏,转贴请搜索原作者) - waferham的专栏 - CSDNBlog.mht

    [转贴]Symbian编程VC开发环境设置 (方便个人学习用,转载自 rocklys的专栏,转贴请搜索原作者) - waferham的专栏

Global site tag (gtag.js) - Google Analytics