如何隐藏 DLL 中的导出函数

Posted

技术标签:

【中文标题】如何隐藏 DLL 中的导出函数【英文标题】:How to hide the exporting functions in DLL 【发布时间】:2010-10-25 06:59:02 【问题描述】:

我不希望用户在我的 DLL 中通过 Dependence 看到所有导出函数,有没有办法做到这一点?我用 C++ 和 MS Visual Studio 编译我的 DLL。

【问题讨论】:

我很想知道这样做的真正目的。导出函数的主要目的是让其他人知道我的函数签名。如果不需要,则无需导出它。 我的DLL有很多版本,我不希望购买基础版的用户看到高级导出功能。 制作 2 个 DLL,不要将高级的提供给基本版本的所有者。 其他原因可能是减小 dll 的大小。 【参考方案1】:

另一种选择可能是创建一个导出函数,该函数将返回您想要隐藏的函数的地址数组 - 一旦有了这些地址,您就可以直接调用它们

static void** Funcs = &foo, &foo1, &foo2, 0;

__declspec (dllexport) void* GetFuncs (void)

   return &Funcs;

在您的可执行文件中,您可以执行以下操作

void** Funcs = GetFuncs();

(*Funcs[0]) (1, 2, 3);

【讨论】:

【参考方案2】:

使用 *.def 文件并使用 NONAME 属性来防止名称被导出:参见 Exporting Functions from a DLL by Ordinal Rather Than by Name ... 有一个 an example here。

【讨论】:

【参考方案3】:

这真的很尴尬,但如果你不想让其他人看到序数,你可以用 COM 包装你的函数。 COM DLL 只公开常见的 COM 函数,因此您的将被隐藏。然后,有一些技术可以在不先注册的情况下使用 DLL,因此在系统中找不到有关您将使用的 COM 类的信息。使用 COM 绝对是一个奇怪的理由,但这种请求也很罕见......

【讨论】:

您可以在不使用 COM 的情况下做一些非常相似的事情:将您的 API 定义为抽象(即纯虚拟)C++ 接口,并导出一个返回指向(实现的对象)该接口的指针的函数. 确实......这将是一个更简单的解决方案。【参考方案4】:

使用 NONAME 的 IMO 对此毫无用处 - 它不会隐藏依赖项。仍然会显示依赖关系(通过使用序数)。您的基本用户仍然可以通过 GetProcAddress 访问他们。

我认为您将不得不使用更复杂的方法 - 例如eran 提出的解决方案。

【讨论】:

【参考方案5】:

请不要试图将您的访问隐藏在 COM 对象中,以为它会被隐藏。请参阅这篇文章Enumerate COM object (IDispatch) methods using ATL?,了解有人如何探测 COM DLL 中的函数名称。

此外,最好隐藏导出函数的名称。当您的 DLL 通过其他代码模块供您自己使用时,这是可取的,并且它执行的操作只有您希望调用代码才能访问。此类别可能包括算法商业机密。

另一个技巧是导出崩溃或设置内部状态的诱饵函数,以让代码知道它已被破坏。在受损状态下,代码可能会故意生成错误结果或随机崩溃。它还可以将包含窥探者信息的邮件发送回一个帐户。

【讨论】:

【参考方案6】:

一种非常简单的方法是将其包装在像 UPX 这样的包装器中。 你看到的导出的只是 UPX 用来将文件解压到内存中的东西

【讨论】:

还有一个非常简单的方法是取消 UPX 文件。 :-) 只要你真正调用了一个函数,你就可以规避任何隐藏它的企图。取消UPXing PE 比使用depends 更简单。【参考方案7】:

不,导出的全部意义在于它们是可见的。

这是简短的答案。长答案涉及 .def 文件。您可以使用 [定义文件](http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx).

告诉链接器将 C 函数转换为索引

【讨论】:

以上是关于如何隐藏 DLL 中的导出函数的主要内容,如果未能解决你的问题,请参考以下文章

c++调用dll导出函数

如何获取PE到导出表中的函数地址

dll从静态链接库导出函数符号

如何在程序中用显式加载的方式使用DLL中的导出类

怎么提取DLL文件中的导出函数呢?

如何调用 DLL 的非导出函数?