PDA

查看完整版本 : 【求助】怎样才能知道DLL中导出函数的调用参数及返回值类型


wxfykx
2006-03-17, 14:55:21
想调用一个动态库中的导出函数,但不知道其调用参数是什么,也不知返回值类型是什么,请问各位大侠,有没有办法能够得到这种函数的调用参数和返回值的类型啊,急用!

小虾
2006-03-17, 15:26:06
1、向官方索取
2、看函数名(有些函数看函数名已经大概可以猜出)。
3、反汇编
4、调试跟踪。
5、。。。。。。:D:

林海雪原
2006-03-17, 17:03:52
小虾是大虾:D:

wxfykx
2006-03-17, 17:55:52
在OllyDBG中跟踪到函数处,但还是找不出它的参数啊

wxfykx
2006-03-17, 18:04:10
比如:下面就是调用的Dll中的一个函数,怎样能够看出它的调用参数和返回值的类型啊。


00D910B0 Te>/$ 81EC 00010000 sub esp, 100
00D910B6 |. 56 push esi ; MFC42.#4234_CDialog::messageMap
00D910B7 |. 8BB424 08010000 mov esi, [esp+108]
00D910BE |. 85F6 test esi, esi
00D910C0 |. 75 0C jnz short 00D910CE
00D910C2 |. 33C0 xor eax, eax
00D910C4 |. 5E pop esi
00D910C5 |. 81C4 00010000 add esp, 100
00D910CB |. C2 0800 retn 8
00D910CE |> 57 push edi
00D910CF |. B9 40000000 mov ecx, 40
00D910D4 |. 33C0 xor eax, eax
00D910D6 |. 8D7C24 08 lea edi, [esp+8]
00D910DA |. F3:AB rep stos dword ptr es:[edi]
00D910DC |. 8B8C24 10010000 mov ecx, [esp+110]
00D910E3 |. 8D7C24 08 lea edi, [esp+8]
00D910E7 |. 8BC1 mov eax, ecx
00D910E9 |. 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00D910EB |. C1E9 02 shr ecx, 2 ; |
00D910EE |. F3:A5 rep movs dword ptr es:[edi], dword ptr [e>; |
00D910F0 |. 8BC8 mov ecx, eax ; |
00D910F2 |. 68 2030D900 push 00D93020 ; |Title = "ShowMsg",B2,"馐?
00D910F7 |. 83E1 03 and ecx, 3 ; |
00D910FA |. F3:A4 rep movs byte ptr es:[edi], byte ptr [esi>; |
00D910FC |. 8D4C24 10 lea ecx, [esp+10] ; |
00D91100 |. 51 push ecx ; |Text
00D91101 |. 6A 00 push 0 ; |hOwner = NULL
00D91103 |. FF15 2021D900 call [<&USER32.MessageBoxA>] ; \MessageBoxA
00D91109 |. 5F pop edi
00D9110A |. B8 01000000 mov eax, 1
00D9110F |. 5E pop esi
00D91110 |. 81C4 00010000 add esp, 100
00D91116 \. C2 0800 retn 8

小虾
2006-03-17, 18:17:56
00D910B6 |. 56 push esi ; MFC42.#4234_CDialog::messageMap
上面这一句已经告诉你了,这个函数是MFC42.#4234_CDialog::messageMap成员函数,只有一个参数,并返回一个int的值。
int messageMap(char szStr[]);

小虾
2006-03-17, 21:22:19
最初由 林海雪原 发布
小虾是大虾:D:
永远都是小虾,呵呵。:D:

wxfykx
2006-03-17, 21:59:39
不对啊,这是我调用的一个我写的测试动态库中的函数,函数原型是:
BOOL ShowMsg(char *pMsg,int iLen);

本来有一个DLL中的一些函数需要调用,但不知道调用参数和返回值类型,所以写了一个测试动态库来试试,看用什么方法能够确定调用参数和返回值类型,好去找那几个函数的调用参数和返回值类型,但是我搞了好长时间也不能从汇编代码中找出这个函数的参数和返回值类型来。

北极星2003
2006-03-17, 23:01:02
最初由 wxfykx 发布
不对啊,这是我调用的一个我写的测试动态库中的函数,函数原型是:
BOOL ShowMsg(char *pMsg,int iLen);

本来有一个DLL中的一些函数需要调用,但不知道调用参数和返回值类型,所以写了一个测试动态库来试试,看用什么方法能够确定调用参数和返回值类型,好去找那几个函数的调用参数和返回值类型,但是我搞了好长时间也不能从汇编代码中找出这个函数的参数和返回值类型来。

你的这个函数原型应该是对的
不过测试时,字符串长度不要超过100(实际有效字符最多为40)
你的问题所在是堆栈不平衡
应该是"retn 8"的问题

retn取32位偏移量作段内返回,可以跟一个立即数作为操作数,该数实际上是从堆栈上传给子程序的参数的个数(以字计)返回后自动把堆栈指针esp加上指定的数*2,从而丢弃堆栈中的参数。

当你调用该程序结束后,esp会与理论上相差16字节,所以最后只需要更改ESP即可

没有经过实际检验,纯属分析!
楼主可以具体调试观察下。

wxfykx
2006-03-18, 20:47:47
还是找不出来,汇编水平不行啊

wxfykx
2006-03-18, 21:10:20
不知道有没有其它的方法可行呢?

lajidong
2006-03-19, 19:57:40
00D910C2 xor eax, eax
00D9110A mov eax, 1
以上两句中的eax就是返回值,要么返回0,要么返回1;

从 retn 8,依据堆栈平衡的原理可知参数共8 bytes,函数的一个参数一般是4bytes,所以可推测函数有两个参数;

00D910B7 mov esi, [esp+108]
这句的[esp+108]就是后入栈的参数,即pMsg;

00D910DC mov ecx, [esp+110]
这句的[esp+110]就是先入栈的参数,即iLen;

光从汇编代码是很难推出函数的原型 BOOL ShowMsg(char *pMsg,int iLen)的, 但你把它当成DWORD func(void *param1,unsigned int param2)来调用结果也是一样的,只要进行必要的强制类型转换!

关键还是了解函数的功能,各参数的意义及存储空间的大小,具体类型并不是很重要。

建议阅读《加密与解密(第二版)》 “2.3.1 函数”这一节(第33页至第36页)!

wxfykx
2006-03-20, 10:43:28
非常感谢各位的回答
但是我主要还是想找出函数的调用参数类型和返回值的类型
知道了这些就可以在程序中动态调用这些导出函数了