防止通过接口拦截呼叫

时间:2012-06-12 19:10:41

标签: c# .net interface interception

我有一个接口,可以在我的应用程序中通过MEF实现类导出。实现类是在单独的程序集中,在编译时不知道(想想插件)。

接口基本上由一个调用组成,该调用表示“这里有一堆键值对,现在初始化你的许可状态”。即。

public LicensingInfo InitialiseLicense(IEnumerable<KeyValuePair<string, string>> keys)

我想知道的是 - 是否有任何方法可以保护该界面免受“中间人”的影响?即一个接收来自我的应用程序的调用,然后使用不同的键值对调用插件程序集中的相同方法,基本上说'是 - 在这里你去 - 拥有一切'。

我确实尝试过以不同的方式思考它,因为应用程序会调用插件程序集并传入一个可以查询的对象。该方法可能如下所示:

public LicensingInfo InitialiseLicense(ILicenseQueryProvider provider)

然而,再次使用这种方法,我认为拦截对象可以简单地为库提供不同的提供者。

那么,有没有办法阻止这样的接口拦截,或者我应该重构它以使插件程序集完全负责其自己的代码中的许可证加载等?还是有另一种方式,或许,我可以重构它,我没有考虑过?

2 个答案:

答案 0 :(得分:2)

我相信你可以让它更难打破,但不能使用界面。

这是你做的:

你需要2 + n个项目:一个用于exe(我们称之为program.exe),一个用于契约(contracts.dll),一个用于你的n个插件(plugin.dll)。

program.exe对contracts.dll有一个硬引用,就像plugin.dll一样。

使用强名称密钥对所有这些密钥进行签名。见http://msdn.microsoft.com/en-us/library/xc31ft41.aspx

在contracts.dll中创建一个密封类LicenceQueryProvider,而不是ILicenceQueryProvider接口。确保它没有公共构造函数,只有一个内部构造函数,没有修改对象的方法(在构造时初始化,不可变和只读字段)。

使用InternalsVisibleToAttribute标记contracts.dll,授予program.exe对内部构造函数的访问权限。见http://msdn.microsoft.com/en-us/library/System.Runtime.CompilerServices.InternalsVisibleToAttribute.aspx

这样,program.exe可以调用此对象上的构造函数,plugin.dll可以从中读取。

plugin.dll“知道”由于强名称签名,对象类尚未被修改。因为它是密封的,中间的人不能替代另一种实现。

现在记得我说你可以让它更难打破,但这并非永远不可能,尤其是如果你使用的是托管代码。

例如,中间的人可以使用反射来使用内部构造函数实例化对象。

更糟糕的是,在您的插件中有代码从此对象读取,并根据许可证信息做出决定。黑客可以将您的plugin.dll反编译为IL,并使用始终授予所有权限的代码替换该代码。

混淆只会有所帮助,但不会对抗反射攻击。本机代码会使它更难一些,但本机代码也可以修补。

最终,代码在黑客的机器上,黑客可以做他想做的事。他甚至可以在调试器下运行它,并修改内存中的数据。这是所有复制保护和许可机制面临的问题。在我看来,许可证使您的客户更难以使用您的软件,并且不会阻止坚定的黑客。您(或您的公司)是否想让您的客户难以使用您的软件?

现在这并不意味着没有解决方案。实际上有:黑客无法修改不在他的机器上的代码。让代码在您控制的服务器上运行。客户端应用程序通过Web服务访问它。 Web服务对用户进行身份验证(不是调用代码,这是不可能的)。了解用户后,该服务可以验证用户的许可证。这是唯一的解决方案。

<强>更新

需要明确的是:这样的服务需要运行对用户有价值的实际代码,而不仅仅是许可证检查。在后一种情况下,黑客可以修改客户端以简单地不进行呼叫,甚至可以替换伪造的许可证服务器。但是,假设许可证比重新创建服务中的实际逻辑更便宜。在这种情况下,即使是黑客也会更愿意购买重新创建代码。

答案 1 :(得分:1)

没有防弹方法来保护您的软件。

我们曾经使用过(广告方面)Safenet Inc的Sentinel硬件密钥,dotfuscator pro和智能组件来保护我们的一些应用程序。

硬件密钥可用于存储许可证(即每个功能/插件都有自己的许可证,可以在硬件密钥上启用并由应用程序查询)。可选地,他们的产品可用于加密您的应用程序 - 应用程序被加密,然后只能在内存中解密并在正确的硬件密钥连接到系统时启动。有一些反调试机制可以让某些人更难使用调试器,等待应用程序在内存中解密然后复制它。

Dotfuscator和智能程序集可用于“混淆”应用程序代码,以便使用像Reflector这样的工具进行反编译。

这些工具都不是防弹的。但“实现/偷取真的很痛苦”?我会这么说,但这是有代价的......你肯定可以在这些工具上投入大量资金。

相关问题