超难问题:修改虚函数表??????

jeedispeed 2008-04-12 11:20:44
事出有因,关于回调函数的,想写一个万能的仿函数类.我的仿函数类有一个虚函数fun,我想修改这个fun这个函数的地址,地址为一个传入的函数指针,比如有仿函数类Visit.有一个void fun(char s)成员函数;重载().
使用这个类的方法
void (*fun)(char s);//函数指针,任意绑定一个函数,这样这个仿函数类就可以一劳永逸了.
Visit v; //比如定义 void fun1(char s){...操作...}
v.Set(fun); //fun=fun1
char s;
v(s);

#include <iostream>
class Base
{
private:
virtual void fun1(){std::cout<<"Bsed::fun1"<<std::endl;}
};
void fun1(){std::cout<<"fun1"<<std::endl;}
void main()
{
typedef void(*Fun)(void);
Base b;
Fun pFun;
std::cout<<"虚函数表开始地址:"<<(int*)(&b)<<std::endl;
std::cout<<"虚函数列表中第一个虚函数地址:"<<(int*)*(int*)(&b)<<std::endl;
std::cout<<"changed:"<<std::endl;
int *a=(int*)*(int*)(&b);
std::cout<<"a:"<<a<<std::endl;
Fun pFun2=&fun1;
*a=*(int*)(pFun2);
std::cout<<*a;
std::cout<<"虚函数列表中第一个虚函数地址:"<<(int*)*(int*)(&b)<<std::endl;
}
这是我的代码,提供个思路,但是没有成功,
...全文
325 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
YKaijin 2009-12-14
  • 打赏
  • 举报
回复
虚函数表不能修改
对象的虚函数表指针可以修改

这个问题可以通过给对象伪造一个虚函数表来实现

把SetFunc实现为:
求虚函数表大小
new 一块与虚函数表一样大的空间
将虚函数表copy到 new 出来的空间
在 new 空间中定位到要修改的虚函数项,并修改它使之指向给定的函数
将当前对像的虚函数表指针指向 new 出来的这块空间

但请注意回收 new 出来的空间
shminow 2009-06-10
  • 打赏
  • 举报
回复
LZ可以看看这篇文章:http://hi.baidu.com/wordsonwing/blog/item/c3b62a0aaeebc61894ca6b54.html
jeedispeed 2008-04-13
  • 打赏
  • 举报
回复
谢谢同志们了
baihacker 2008-04-12
  • 打赏
  • 举报
回复
那个地址不可写,即使用WriteProcessMemory
  • 打赏
  • 举报
回复
你试试boost::function 吧
Treazy 2008-04-12
  • 打赏
  • 举报
回复
没看内容,看了标题进来的

修改需函数表?这个还是看看vtabel和溢出方面的东西吧

jeedispeed 2008-04-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sheenl 的回复:]
引用 4 楼 jeedispeed 的回复:
加这个成员变量 其类型还是obj::fun的
我的IDE是VS2008


怎么可能?
[/Quote]

我的意思这个仿函数类的类如果设计一个void (*fun)(char s);
那么如果传入一个void (obj::*fun)(char s);就不可以用了
jeedispeed 2008-04-12
  • 打赏
  • 举报
回复
而且如果这样加上 如果接受一个void (*fun)(char s);
那么接受void (obj::*fun)(char s);的时候还是有问题
也就是说在类的内部调用的时候就不可以了
sheenl 2008-04-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jeedispeed 的回复:]
加这个成员变量 其类型还是obj::fun的
我的IDE是VS2008
[/Quote]

怎么可能?
  • 打赏
  • 举报
回复
噢,你的意思是依赖对象?
jeedispeed 2008-04-12
  • 打赏
  • 举报
回复
加这个成员变量 其类型还是obj::fun的
我的IDE是VS2008
oo 2008-04-12
  • 打赏
  • 举报
回复
加一个 void (*fun)(char s);这样的成员变量不行吗?
jeedispeed 2008-04-12
  • 打赏
  • 举报
回复
函数指针是不可以的
比如类的成员函数fun 其指针类型是obj::*fun 你传入的指针怎么搞成这个类型呢
  • 打赏
  • 举报
回复
这个用函数指针就可以了,用不着虚函数吧
taodm 2008-04-12
  • 打赏
  • 举报
回复
boost::function + boost::lambda,已经完成了你要的东西了。
我是风 2008-04-12
  • 打赏
  • 举报
回复
俺做了个例子,不知道对你有没有帮助。
#include <iostream>
using namespace std;

template<class T>
class TestBase
{
private:
bool isStandardCall;
T *refObject;
void(T::*callackMFPtr)(char);
void(*callbackSFPtr)(char);
public:
explicit TestBase(T *object, void(T::*aMFPtr)(char)) : isStandardCall(false), refObject(object), callackMFPtr(aMFPtr) {}
explicit TestBase(void(*aSFPtr)(char)) : isStandardCall(true), refObject(NULL), callbackSFPtr(aSFPtr) {}
void SetFunction(T *, void (T::*)(char));
void SetFunction(void (*)(char));
void operator()(char);
};

template<class T>
void TestBase<T>::SetFunction(T *object, void(T::*aMFPtr)(char))
{
this->isStandardCall = false;
this->refObject = object;
this->callackMFPtr = aMFPtr;
}

template<class T>
void TestBase<T>::SetFunction(void (*aSFPtr)(char))
{
this->isStandardCall = true;
this->callbackSFPtr = aSFPtr;
}

template<class T>
void TestBase<T>::operator()(char s)
{
if(this->isStandardCall)
(this->callbackSFPtr)(s);
else
(this->refObject->*this->callackMFPtr)(s);
}

void TestFun1(char cs)
{
cout << "standard function: TestFun1(" << cs << ")" << endl;
}

class TestClass {
public:
void TestFun2(char cs)
{
cout << "member function: TestFun2(" << cs << ")" << endl;
}
};

int main(void)
{
TestBase<string> testBase1(TestFun1);
testBase1('A');
TestClass testClass;
TestBase<TestClass> testBase2(&testClass, &TestClass::TestFun2);
testBase2('B');
testBase2.SetFunction(TestFun1);
testBase2('C');
testBase2.SetFunction(&testClass, &TestClass::TestFun2);
testBase2('D');
return 0;
}
Supper_Jerry 2008-04-12
  • 打赏
  • 举报
回复
依赖编译器,不可移植,
而且强烈怀疑,这个地址可以改写。
hastings 2008-04-12
  • 打赏
  • 举报
回复
完全同意LS几位的观点.
我啃 2008-04-12
  • 打赏
  • 举报
回复
1.万能的仿函数类不存在,个人觉得MCD里面那个泛化functor已经很不错了,还有BOOST等也不错
2.虚函数表只是动多态的编译器实现,标准从来没有保证它的存在,更不用说手动访问,修改等操作
3.编译器不同,修改虚函数表可能无法工作,而且不可能统一,没有移植性
4.建议重新审视你的构造目的
  • 打赏
  • 举报
回复
还有bind mem_fun呢,转化成一个不依赖对象的东西
加载更多回复(1)

64,680

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧