// 使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用。
#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
分享到:
相关推荐
第3章 函数-------------------------------------------------------------102 3.1 简介------------------------------------------------------------102 3.2 C++程序组件----------------------------------...
*3.4.2 在输入流与输出流中使用控制符 3.4.3 用getchar和putchar函数进行字符的输入和输出 3.4.4 用scanf和printf函数进行输入和输出 3.5 编写顺序结构的程序 3.6 关系运算和逻辑运算 3.6.1 关系运算和关系表达式 ...
*3.4.2 在输入流与输出流中使用控制符 3.4.3 用getchar和putchar函数进行字符的输入和输出 3.4.4 用scanf和printf函数进行输入和输出 3.5 编写顺序结构的程序 3.6 关系运算和逻辑运算 3.6.1 关系运算和关系表达式 ...
7.11 有关对象的思考:在电梯模拟程序中使用复合和动态对象管理 小结 术语 自测练习 自测练习答案 练习 第8章 运算符重载 8.1 简介 8.2 运算符重载的基础 8.3 运算符重载的限制 8.4 用作类成员与友元函数的...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
7.11 有关对象的思考:在电梯模拟程序中使用复合和动态对象管理 小结 术语 自测练习 自测练习答案 练习 第8章 运算符重载 8.1 简介 8.2 运算符重载的基础 8.3 运算符重载的限制 8.4 用作类成员与友元函数的...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
14.8.2虚函数在构造函数中的行为 14.9析构函数和虚拟析构函数 14.10小结 14.11练习 第15章 模板和包容器类 15.1包容器和循环子 15.2模板综述 15.2.1C方法 15.2.2Smalltalk方法 15.2.3模板方法 15.3模板的语法 15.3.1...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 ...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...
12.9.1 虚函数和多态性 389 12.9.2 纯虚函数和抽象类 391 12.9.3 虚基类 391 12.9.4 抽象类和抽象数据类型 393 12.10 图的搜索算法 394 12.10.1 宽度优先搜索 394 12.10.2 类Network 395 12.10.3 BFS的实现 395 ...