因为从事dll 编写的相关工作。没写完一个dll 之后都要对函数进行测试,对每个dll都要写一个测试demo的话就非常费劲。能不能一个公共的测试软件来各种dll里的函数测试呢?
尝试开始,从外界的.h文件中读取函数名很简单,但是我们不能在程序已经编译的过程中再进行添加定义该 函数的指针。
比如我dll中有一个
int add(int a,int b);
从.h中也读到了add,然而 没法再在运行中对其进行如下的定义了,必须开始就定义好。
typedef int (CALLBACK* Fun_add)(int a,int b);
于是,我们只能从另一种路线入手,通过内存地址去查找这个函数,然后利用汇编向 压栈参数,然后得到结果。
例如 我们建立一个ADDdll.dll的动态库,其中有以下函数。
int __stdcall addabc(int a ,int b,int c)
{
int sum = a + b + c;
return sum;
}
在调用该函数的exe 中,我们进行如下操作。
HINSTANCE hInstLibrary = LoadLibrary(_T("ADDdll.dll"));
if( hInstLibrary == NULL)
{
MessageBox(NULL,_T("动态库加载失败"),NULL,MB_OK);
}
else
{
MessageBox(NULL,_T("动态库加载成功"),NULL,MB_OK);
int a = 2,b = 3,c = 4;
int addstr =(int) GetProcAddress(hInstLibrary,"addabc");//获得函数的地址
if(addstr == 0)
{
MessageBox(NULL,_T("函数加载失败"),NULL,MB_OK);
goto RE;
}
else
{
//为了查看函数地址具体值得无聊操作,请无视编码转化这种坑
char bb[50] = {0};
sprintf_s(bb,"%x",addstr);
WCHAR wszClassName[256];
memset(wszClassName,0,sizeof(wszClassName));
MultiByteToWideChar(CP_ACP,0,bb,strlen(bb)+1,wszClassName,
sizeof(wszClassName)/sizeof(wszClassName[0]));
MessageBox(NULL,wszClassName,NULL,MB_OK);
//---------------------------------------------------------
int result = 0 ;//用来取结果
_asm
{
push c
push b
push a //对三个参数压栈
call addstr//召唤这个等食的函数
mov dword ptr [result],eax //取回结果,一般函数结果都在eax中。
}
//★★★add esp,12 前期push的3个int 是12个字节,C++ 编译器自己进行了ret 8 真是吊
//对取得的结果进行格式化输出。
memset(bb,0,sizeof(bb));
sprintf_s(bb,"%d",result);
memset(wszClassName,0,sizeof(wszClassName));
MultiByteToWideChar(CP_ACP,0,bb,strlen(bb)+1,wszClassName,
sizeof(wszClassName)/sizeof(wszClassName[0]));
MessageBox(NULL,wszClassName,NULL,MB_OK);
}
}
return TRUE;
RE:
return FALSE;
请注意代码注释中的★★★处,当我跟踪汇编的调用动态库的函数过程中,pull出栈时,指针要加上三个参数之前所占用的空间。然而这个操作,C++编译器自己已经进行了操作,开始加那句add时错的一塌糊涂。。。希望这个小建议能帮大家不绕远路。
至于测试工具,就是文字处理归类的工作了,是上边那段代码的扩展了。