15

我想从 dll 中调用一个方法,但我既没有源文件也没有头文件。我尝试使用 dumpbin /exports 查看方法的名称,但我可以找到方法签名?

有没有办法调用这个方法?

谢谢,

4

6 回答 6

10

如果该函数是 C++ 函数,则您可以从损坏的名称中派生函数签名。Dependency Walker是一种可以为您执行此操作的工具。但是,如果 DLL 是使用 C 链接创建的(Dependency Walker 会告诉您这一点),那么您就不走运了。

于 2009-02-16T21:18:02.170 回答
7

C++ 语言对 dll 一无所知。

这是在 Windows 上吗?一种方法是:

  • 打开depends.exe随附的 dll (Visual Studio)
  • 验证您要调用的函数的签名
  • 用于LoadLibrary()加载此 dll(注意路径)
  • 用于GetProcAddress()获取指向要调用的函数的指针
  • 使用这个指向函数的指针来使用有效参数进行调用
  • 用于FreeLibrary()释放手柄

顺便说一句:此方法通常也称为运行时动态链接,而不是编译时动态链接,您可以使用关联lib文件编译源代码。

*nixes with 存在一些类似的机制dlopen,但在那之后我的记忆开始失败。调用objdumpnm应该让你开始检查函数的东西。

于 2009-02-16T21:18:57.050 回答
5

如您所见,DLL 中的导出列表仅存储名称,而不存储签名。如果您的 DLL 导出 C 函数,您可能必须对函数进行反汇编和反向工程以确定方法签名。但是,C++ 在导出名称中对方法签名进行编码。这种结合方法名称和签名的过程称为“名称修饰”这个 Stackoverflow 问题有一个参考,用于根据损坏的导出名称确定方法签名。

试试免费的“Dependency Walker”(又名“depends”)实用程序。“Undecorate C++ Functions”选项应该确定 C++ 方法的签名。

于 2009-02-16T21:25:16.363 回答
4

可以通过分析其反汇编的开始来找出 C 函数签名。函数参数将在堆栈上,并且该函数将执行一些“弹出”以以相反的顺序读取它们。您不会找到参数名称,但您应该能够找到它们的编号和类型。返回值可能会变得更加困难 - 它可能是通过“eax”寄存器或通过作为最后一个伪参数(在堆栈顶部)传递给函数的特殊指针。

于 2009-03-08T07:10:06.457 回答
1

如果您确实知道或强烈怀疑该函数存在,您可以使用 loadLibrary 动态加载 DLL 并使用 getProcAddress 获取指向该函数的指针。见MSDN

请注意,这是一种手动的动态加载库的方式;您仍然必须知道正确的函数签名才能映射到函数指针才能使用它。AFAIK 无法在加载时功能中使用 dll 并使用没有头文件的函数。

于 2009-02-16T21:20:23.117 回答
1

每当更新第 3 方 DLL 时,调用非外部函数是让程序中断的好方法。

也就是说,undname实用程序也可能会有所帮助。

于 2009-02-16T21:25:38.877 回答