首页
社区
课程
招聘
[推荐]关于Exe导出函数的一点疑问
发表于: 2013-5-26 16:12 5186

[推荐]关于Exe导出函数的一点疑问

2013-5-26 16:12
5186
出处在这里:
http://bbs.pediy.com/showthread.php?t=56840

经测试发现,参数为数字的时候,调用确实正常; 但是一旦参数为字符串的时候,程序就崩溃了.不清楚为什么?

有没有高手遇到过, 指点一下.

extern "C"
{
/*
__declspec(dllexport) int Add(int a, int b);
__declspec(dllexport) int Sub(int a, int b);
__declspec(dllexport) int Mul(int a, int b);
__declspec(dllexport) int Div(int a, int b);
*/

        int Add(int a, int b)
        {
                return (a + b);
        }

        int Sub(int a, int b)
        {
                return (a - b);
        }

        int Mul(int a, int b)
        {
                return (a * b);
        }

        int Div(int a, int b)
        {
                if (b == 0)
                        return 0;
                else
                        return (a / b);
        }

        int Str(wchar_t *pstr)
        {
                MessageBox(0,pstr,0,0);
                return 99;
        }


}

EXPORTS
        Add       @1  
        Sub       @2  
        Mul       @3  
        Div       @4         
        Str      @5

调用方式:


typedef int (__cdecl *PADD )(int i,int j);
typedef int (__cdecl *PStr )(wchar_t *str);


	HMODULE h = LoadLibrary("Callee.exe");
	if (h == NULL)
	{
		printf("load error\n");
	}

	PADD dwAdd = (PADD)GetProcAddress(h,"Add");
	int k = dwAdd(100,1000);
	printf("%d",k);

	PStr dwAddstr = (PStr)GetProcAddress(h,"Str");

	k = dwAddstr(L"sssssssssssss");   //这里就崩溃了,就是在MessageBox的时候会崩溃,反正遇到字符串处理就必定崩溃.

	printf("%d",k);
	FreeLibrary(h);


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

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 2120
活跃值: (73)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
用OD看了一下 你在Str这个函数里调用的函数的地址都是不对的 即他的导入表错了 如果改用静态链接的方式 那么他的导入表是正确的 可以正常调用其他函数
2013-5-26 23:34
0
雪    币: 2120
活跃值: (73)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
后来发现Callee.exe所需要的导入模块他没有加载
2013-5-26 23:47
0
雪    币: 398
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
我也做了下测试,发现用EXE文件调用另一下EXE文件里的导出函数时有时候会出错,特地用OD调试了一下,发现反汇编后的代码有点问题。。如下所示:
00C41000 >  55              push ebp
00C41001    8BEC            mov ebp,esp
00C41003    8B45 0C         mov eax,dword ptr ss:[ebp+0xC]
00C41006    8B4D 08         mov ecx,dword ptr ss:[ebp+0x8]
00C41009    6A 00           push 0x0
00C4100B    50              push eax
00C4100C    51              push ecx
00C4100D    6A 00           push 0x0
00C4100F    FF15 A8204000   call dword ptr ds:[<&MSVCR100.printf>]   ; MSVCR100.printf (这里按理来说应该是MessageBoxA的)
00C41015    B8 63000000     mov eax,0x63
00C4101A    5D              pop ebp
00C4101B    C3              retn
00C4101C    CC              int3

上面这个就是反汇编出来的STR函数。。我们编程程序的时候明明是调用MessageBoxA的,这里怎么会变成printf呢,晚上有点匆忙,下次再详细研究。。。

分析原因:因为被调用的程序中DLL是隐式调用的,应该是在EXE文件加载之前系统做了相关的初始化(包括加载需要用到的DLL中的函数),而在我们用另外一个EXE文件直接导入这个程序的函数时候,系统并没有对这个程序做相关初始化工作,所以才导致导入表错误;以上程序如果想正常使用,需要在被调用函数中使用显式调用。
2013-5-27 00:10
0
雪    币: 652
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不是printf 的问题,应该是messbox所在的这个函数传参

出了问题
2013-5-27 13:07
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢大家的回复! 感谢各位.
这个函数自己调用是没有问题的,别的模块调用它就有问题了. 看来这种只适合使用lib库, 不适合动态加载.
2013-5-27 19:48
0
雪    币: 2120
活跃值: (73)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
可以看一下LoadLibraryEx的描述 http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx

If the specified module is an executable module, static imports are not loaded; instead, the module is loaded as if DONT_RESOLVE_DLL_REFERENCES was specified. See the dwFlags parameter for more information.

说明exe静态链接的库是没有导入到内存里的 所以调用MessageBox的时候出现访问异常 因为那个地址根本不对
2013-5-27 21:21
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢, 但是为什么其他几个函数的调用都可以成功呢, 表示很奇怪!
2013-5-27 23:46
0
雪    币: 2120
活跃值: (73)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
因为你没有调用其它模块的函数啊
2013-5-27 23:59
0
游客
登录 | 注册 方可回帖
返回
//