首页
社区
课程
招聘
[已解决]如何取得类成员函数的地址?
发表于: 2007-7-11 13:27 15909

[已解决]如何取得类成员函数的地址?

2007-7-11 13:27
15909

【求助】如何取得类成员函数的地址?

看了http://blog.csdn.net/orbit/archive/2007/01/29/1497457.aspx这篇文章,
对 三、对整个函数体使用SMC方式加密 感兴趣,可是只能针对void function(void)函数
,不能针对void CDialog::function(void)等类成员函数,不知道如何处理?


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
  • 1.PNG (1.78kb,240次下载)
收藏
免费 7
支持
分享
最新回复 (11)
雪    币: 290
活跃值: (635)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
void test(void)
{
	MessageBox(NULL,_T("1111"),_T("test"),MB_OK);
}

void CtestJMDlg::OnBnClickedButton1()
{
	CString tStr;
	
#if 0
	char *p = (char *)OnBnClickedButton1;
#else
	char *p = (char *)test;
#endif

	DWORD tRVA = m_Encrypt.GetFunctionRVA(p);

	tStr.Format(_T("RVA=%08lx %ld"),tRVA,tRVA);
	
	::MessageBox(NULL,tStr,_T("test"),MB_OK);
}

DWORD CEncrypt::GetFunctionRVA(void* FuncName)
{
	void *_tempFuncName = FuncName;
	char *ptempFuncName = (char *)(_tempFuncName);

	DWORD _jmpdwRVA, dwRVA;

	CopyMemory(&_jmpdwRVA, ptempFuncName+1, 4);

	dwRVA = (DWORD)ptempFuncName + _jmpdwRVA + 5;

	return (dwRVA);
}


上面是主要代码,当将#if 0改成#if 1时,即取void CtestJMDlg::OnBnClickedButton1()的地址时出现类型转换的错误。

Thanks!
2007-7-11 14:12
0
雪    币: 236
活跃值: (155)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
1.在h文件加入
#pragma warning(disable : 4248)

2.在CPP文件加入
#define  BEGIN_MEMFUNC_ENTRY_MAP() \
typedef void (CObject::*PFuntionName)(void); \
PFuntionName pFunAddress = NULL; \

#define MEMFUNC_ENTRY(memFunc,entry) \
pFunAddress = (PFuntionName)memFunc; \
entry =  *((DWORD*)&pFunAddress);  \

3.在使用的地方
    DWORD dwAddress = 0;
    BEGIN_MEMFUNC_ENTRY_MAP()  // 这行必须要
    MEMFUNC_ENTRY(CString::Delete,dwAddress) // 这里就可以得到CString::Delete的函数地址了
  
 */
2007-7-11 16:11
0
雪    币: 290
活跃值: (635)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢,OK了

似乎不需要#pragma warning(disable : 4248),注释掉没有编译没有问题!

其实主要是类型转换的问题,有个小疑问,自己定义的类CEncrypt并没有基类,更没有基于CObject,为何可以使用pFunAddress = (PFuntionName)CEncrypt::Test;来转换?
2007-7-11 17:21
0
雪    币: 236
活跃值: (155)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
类不需要从CObject派生,这里纯粹是骗过编译器而已,放心吧
2007-7-11 17:29
0
雪    币: 290
活跃值: (635)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
thanks!
2007-7-11 17:33
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
#include <stdio.h>
#include <stdlib.h>
class C
{public:
	void f() {}
};
void main()
{
	char buf[12];
	sprintf(buf,"%u",C::f);
	int d=atoi(buf);
	printf("%p\n",d);
}

#include <stdio.h>
#include <stdarg.h>
class C
{public:
	void f() {}
};
int func(int unused,...)
{
	va_list args;
	va_start(args,unused);
	return va_arg(args,int);
}
void main()
{
	printf("%p\n",func(0,C::f));
}
2007-7-11 19:09
0
雪    币: 290
活跃值: (635)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=dwing;333494]#include <stdio.h>
#include <stdlib.h>
class C
{public:
        void f() {}
};
void main()
{
        char buf[12];
        sprintf(buf,"%u",...[/QUOTE]

这也行!

有个C4313的warning, 程序执行没有问题。
2007-7-11 20:04
0
雪    币: 290
活跃值: (635)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
再问一下,如何由地址转换到类成员函数,即dwAddress转换到CString::Delete?

解决:
和entry =  *((DWORD*)&pFunAddress); 的道理是一样的。
2007-7-11 20:10
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
10
[QUOTE=dwing;333494]#include <stdio.h>
#include <stdlib.h>
class C
{public:
        void f() {}
};
void main()
{
        char buf[12];
        sprintf(buf,"%u",...[/QUOTE]

太强了,又学到一招
我以后有困难找dwing
2007-7-11 20:30
0
雪    币: 8209
活跃值: (4518)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
11
我要拜师学艺
2007-7-11 22:06
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
2007-9-11 22:48
0
游客
登录 | 注册 方可回帖
返回
//