如何将对非托管 dll 的访问限制为仅特定的第 3 方(拒绝所有其他方的访问)?
我创建了一个非托管 C++ DLL,我想将其提供给第三方。该 DLL 将公开分发,但我不希望其他任何人能够调用 DLL 中的方法。限制访问的好方法是什么?
FWIW - 该 DLL 将在 Mac 和 Windows 上使用。
I created an unmanaged C++ DLL that I'd like to provide to a 3rd-party. The DLL will be distributed publically but I don't want anyone else to be able to call methods in the DLL. What's a good way to restrict access?
FWIW - the DLL will be used on both Mac and Windows.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最终,您无法阻止决心已定的人,但您可以做一些事情来让未经授权的用户感到困难。
显而易见的是加密 DLL 中的(至少大部分)代码。有一个入口点,用户必须调用该入口点来获取(例如)指向实际函数的指针表。当调用入口点时,必须提供密钥并用于解密其余内容,然后返回指针。如果用户提供了错误的密钥,他们会得到指针,但数据不会被正确解密,因此当他们尝试调用它时,它不起作用。
无论如何,这都不是万无一失的。举一个明显的例子,如果有人在调试器下运行授权程序,他们可以看到传递了什么密钥,然后简单地重新使用它。如果你想让攻击者的生活变得更棘手,你可以做一些事情,比如让 DLL 对可执行文件进行校验和,并将其用作密钥(用户必须嵌入一些数据才能获得校验和)出右)。这仍然可以弄清楚,但至少需要一些工作。
编辑:确切的加密并不重要。我可能会使用 AES,只是因为它很容易找到实现并且运行速度相当快,所以没有太多理由使用其他东西。
至于调用代码如何工作,它会是这样的:
在调用代码中,您将进行如下初始化:
然后调用函数将是这样的:
本质上,您正在重新创建一个小的面向对象编程的一部分,让你的入口点返回某种“对象”,DLL 的实际函数作为该“对象”的“成员函数”。
至于获取校验和,我还没有详细考虑过。基本上只需要存储可执行文件的地址。您可以使用 VirtualQuery 遍历模块,也可以使用 GetModuleHandle(NULL)。
Ultimately, you can't stop somebody who's determined, but you can do a few things to make life difficult for unauthorized users.
The obvious would be to encrypt (at least most of) the code in the DLL. Have a single entry point that the user has to call to get (for example) a table of pointers to the real functions. When the entry point is called, a key has to be supplied and that is used to decrypt the rest of the content, and then the pointers are returned. If the user supplies the wrong key, they get pointers, but the data won't be decrypted correctly, so when they try to call it, it doesn't work.
That's not foolproof by any means. Just for an obvious example, if somebody runs the authorized program under a debugger they can see what key is passed, and simply re-use it. If you want to make life a bit trickier for an attacker, you can do something like having the DLL do a checksum on the executable, and use that as the key (and the user will have to embed some data to get the checksum to come out right). That can still be figured out, but it will at least take some work.
Edit: The exact encryption doesn't matter a lot. I'd probably use AES, simply because it's easy to find an implementation and it runs pretty fast, so there's not much reason to use something else.
As far as how the calling code would work, it would be something like this:
In the calling code you'd have initialization something like:
and then calling a function would be something like:
In essence, you're re-creating a small piece of object oriented programming, and having your entry point return an "object" of sorts, with the DLL's real functions as "member functions" of that "object".
As far as getting the checksum goes, I haven't thought through it in a lot of detail. Basically just just want the address where the executable is stored. You can walk through modules with VirtualQuery, or you can use GetModuleHandle(NULL).
任何有权访问该 dll 的人都可以检查它、加载它并获取指向 dll 中函数的指针。我不确定你严格指的是 dll,但正如你所说:
Dll 不是 Mac 的东西——它们是运行时加载/链接库的 Windows 特定实现。所以我假设你真正的问题一定只是限制某些第三方对图书馆的访问。为了实现您的目标,其他一些选项可能更合适:
将所有内容编译为单个整体 exe,而不是 dll。将该 exe 作为服务或盒子上的第二个进程运行。让第三方通过套接字/命名管道/任何其他形式的进程间通信连接到它。对服务的用户进行身份验证,以便只有具有正确凭据的第三方软件才能访问该服务。其他人都被拒绝访问。
为第 3 方应用程序创建帐户。第 3 方应用程序只能在该帐户登录时运行。将 dll(或 Mac 上的 dylib)放置在只能由该帐户访问的文件夹中。其他人无法访问该位置,因此除了以管理员身份运行的应用程序之外,其他应用程序都无法运行该位置。
Anyone with access to the dll will be able to inspect it, load it, and get pointers to functions in the dll. I'm not sure you strictly mean dll though as you say:
Dlls aren't a Mac thing--they are a Windows specific implementation of a runtime loaded/linked library. So you're real question, I'm assuming, must simply be about limiting access to a library for only certain 3rd parties. To achieve your goal, some other options may be more appropriate:
Instead of a dll, compile everything into a single monolothic exe. Run that exe as a service or a second process on the box. Have the 3rd party connect to it through sockets/named pipes/whatever other forms of interprocess communication. Authenticate the users of the service so that only the 3rd party software with the right credentials can access the service. Everyone else gets denied access.
Create an account for the 3rd party application. The 3rd party application can only run when that account is logged in. Place the dll (or dylib in the case of Mac) in a folder only accessible to that account. Noone else has access to that location, so no other applications can run it barring those run as administrator.