`
febird
  • 浏览: 254233 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用

    博客分类:
  • C++
阅读更多

// 使用" 参数化基类" " 成员函数指针" 模拟实现虚函数--在实际中的应用。

#include <stdio.h>

#include <string.h>

/*

    病毒或许可以使用这种技术有效地实现,不过这是我在写 Windows PE 文件

    加壳程序的时候总结出来的技术。当然可以被用在恶意程序上,任何事情总有两面性!

 

    ***注意***

    VC 中测试时,必须去掉“启用增量连接”,即(/INCREMENTAL:NO)

    如果在 ShellCode 或者 Virus 中使用该技术,字符串文字量(string literal

    也必须进行地址转化,即:convert_address("string literal").

 

    使用 "参数化基类 " "成员函数指针 "模拟实现虚函数。

    可能大家都以为只有疯子才会这么干,好好的虚函数干吗不用,而偏要拐弯抹角地

    搞得这么复杂,但有时候这可能是最好地选择。举个例子吧,我写 Windows PE 文件

    加壳程序的时候,遇到一个问题:

    1. 我开发了一个框架,可以只用 C++ 来写 "壳程序 ",大家很难想到吧!

    2. 但不能使用一些 C++ 功能:虚函数,异常处理,还有 switch-case 语句

    3. C++ 异常处理可以不用,但是不能使用虚函数可能太过苛刻。

 

    当我看了 "generative programming"以后,觉得 "参数化继承 "

    或许可以满足这个需求,模拟实现虚函数。

    以下是使用 "参数化继承 "实现虚函数的框架,以及要注意的事项。

 

    BaseClass 显然,实际上是 "抽象基类 ",因为如果实例化

    "InstantialClass<ConcreteClass>" 时,ConcreteClass

    必须定义响应的 "虚函数 ",否则编译就报错。如果相应的

    BaseClass InstantialClass 定义正确无误(从代码可以

    看到,这很简单,但比较麻烦,必须注意一些细节)。因此

    ConcreteClass 编译期错误不会被推迟到运行时才发现,

    而使用其它方式模拟,就很难有这个保证。

 

    其实,如果了解 C++ 的底层对象模型,这些需要注意的细节

    很容易理解!

 

    //-------

    另外有一种 C 语言模拟 C++ 虚函数的方法,可以在我以前

    (2002 )一篇文章中看到。

*/

 

struct Context

{

    int (*printf)(const char *, ...);

 

    // other external fuctions...

};

 

// construct these codes...

int entry(const Context* context)

{

    int imp_entry(const Context* context);

    return imp_entry(context);

}

 

template< typename AddressType >

AddressType convert_address(AddressType address)

{

    // if used in shell code, this must return another valid address.

#define SUPPORT_RECLOCATION

#ifdef SUPPORT_RECLOCATION

    __asm {

        call LL

LL:     pop eax

        sub eax, offset LL

        add eax, address

        mov address, eax

    }

#endif

    return address;

}

 

class BaseClass

{

#define DEFINE_VIRTUAL(ret , name, param_list, call_list ) \

protected :  \

    typedef ret (BaseClass ::*T## name) param_list ;   \

    T## name p ##name;     \

public :                 \

    ret name param_list \

    { return ( this->*this ->p## name)call_list ; }

 

//////////////////////////////////////////////////////////////////////////

// expansion of :

/*  DEFINE_VIRTUAL(int, Func1,

        (int x1, int x2),

        (   x1,    x2)

        );

*/

protected :

    typedef int (BaseClass ::*TFunc1)( int x1 , int x2);

    TFunc1 pFunc1;

public :

    int Func1(int x1, int x2 )

    {

        return ( this->*this ->pFunc1)( x1, x2 );

    //  return (this->*pFunc1)(x1, x2); // can be simplified as this line.

    }

// end expansion

//////////////////////////////////////////////////////////////////////////

 

    DEFINE_VIRTUAL( int, Func2 ,

        (int x1, int x2, int x3 ),

        (   x1 ,    x2 ,    x3 )

        );

 

public :

    template< typename BaseFuncType , typename ConcreteFuncType>

    void assign(BaseFuncType & x, ConcreteFuncType y )

    {

    // if use C Style cast like "(BaseFunType)(y)", it is danger!!

    // any member function can be assigned to x!!

    //  x = convert_address((BaseFuncType)(y)); // danger!!

        x = convert_address(static_cast <BaseFuncType>(y));

    }

    BaseClass()

    {

        pFunc1 = 0;

        pFunc2 = 0;

    }

};

 

class ConcreteClass1

{

private :

    const Context* context;

    int x1, x2 , x3;

public :

    ConcreteClass1(const Context* context)

    {

        this->context = context;

    }

    int Func1(int x1, int x2)

    {

        this-> x1 = x1 ;

FONT-SIZE: 9pt; FONT-FAMILY: "Courier New"; mso-font-k

分享到:
评论

相关推荐

    C++大学教程

    第3章 函数-------------------------------------------------------------102 3.1 简介------------------------------------------------------------102 3.2 C++程序组件----------------------------------...

    MoreEffectiveC++

    - 虚函数表和虚基类指针增加了对象的大小; - RTTI(运行时类型信息)需要额外的空间和时间; - 多重继承可能会导致“菱形问题”。 ### 技术部分 #### Item25: 虚拟化构造函数和非成员函数 - **定义**:虚拟化...

    C++模拟题5.docx

    6. **虚函数和动态联编**:虚函数是实现多态的关键,通过对象指针或引用调用虚函数可以实现动态绑定,即运行时确定函数调用。 7. **派生类和基类关系**:派生类可以继承基类的成员,包括公有、保护和私有成员。基类...

    C++ 模拟实现signal/slot

    要模拟实现信号/槽,我们可以使用多态、虚函数和回调函数等C++特性。下面是一个简单的实现思路: 1. **定义信号接口**:创建一个基类`SignalBase`,其中包含一个用于连接槽的成员函数,如`connect`。这个函数通常会...

    C模拟题答案.docx

    虚函数可以在基类中声明,并可以在派生类中重写,以便实现特定的行为。虚函数可以在类的内部或外部定义,只要在类声明中声明为虚函数即可。因此,A、B选项错误,D选项正确。C选项虽然在技术上是可行的,但在实践中...

    C++模拟题1答案.docx

    - 私有成员在基类中只能被基类的成员函数访问,不能在派生类中直接访问。公有和保护成员的访问权限则根据继承方式有所不同。 6. **派生类与基类的关系**: - 派生类是基类的特化或具体化,它可以扩展基类的功能。...

    计算机二级C++模拟题及答案.docx

    【计算机二级C++知识点】 ...这些知识点涵盖了C++中的类与对象、继承、运算符重载、构造函数、条件判断、循环结构以及指针和数组的使用。对于准备计算机二级C++考试的人来说,理解并掌握这些内容至关重要。

    C++模拟题5.pdf

    18. **虚函数调用**:动态多态性通常通过基类对象指针调用虚函数来实现,这样可以调用到实际对象所属类的对应函数。 19. **指针变量**:`*p`表示指针变量的值,即它指向的变量的地址;`p`本身是变量,存储了地址,...

    面向对象程序设计 动态联编 C++

    在MFC(Microsoft Foundation Classes)库中,虚函数的使用尤为关键,因为它涉及到消息响应和成员函数的重载。通过重写虚函数,开发者可以定制系统的行为,满足特定需求。 对于vtable的分析,我们可以理解到,每个...

    C++面向对象程序设计模拟试题五.pdf

    在本模拟试题中,涉及了C++的一些核心概念和特性,以下是相关知识点的详细说明: 1. 构造函数和析构函数: - 构造函数用于在创建对象时初始化对象的状态,它可以重载,即一个类可以有多个构造函数,每个函数有不同...

    浙江大学《C++》九套期末模式复习题(含答案).pdf

    在派生类中调用基类成员函数时,应使用基类名和作用域解析运算符(::)来调用基类的成员函数(C)。在C++中,派生类对象可以调用基类的public成员函数,但是必须明确指出是基类的作用域。 9. 虚析构函数和多态 当...

    面向对象实验

    - 成员函数实现周长和面积的计算。 #### 三、实验2:运算符重载 1. **成员函数重载运算符** - 示例: 重载`++`和`--`运算符,用于`Point`类实例的自增自减操作。 2. **友元函数重载运算符** - 示例: 重载`==`...

    高质量c编程.pdf

    覆盖是指派生类重新实现基类中的虚函数;而隐藏是指派生类中存在与基类同名的成员函数,但并不构成覆盖。 **8.3 参数的缺省值** - **知识点**: 缺省参数的使用。 - **详细解释**: 函数参数可以设置缺省值,这样在...

    C++类继承,访问权限,有源码参考

    - **虚函数**(virtual function)允许动态绑定,即在运行时确定调用哪个函数,这在多态性中至关重要。 - **纯虚函数**(pure virtual function)定义为`virtual void func() = 0;`,使得基类成为一个抽象类,无法...

    C+模拟题答案.pdf

    静态多态性在编译时通过函数重载实现,而动态多态性在运行时通过虚函数和基类指针或引用实现。 4. 默认参数:在构造函数中可以设置默认参数,如`A(int i=4, int j=0)`。如果没有提供参数,将使用默认值。在`A x(1);...

Global site tag (gtag.js) - Google Analytics