实现插件框架的最佳方式 - DLL是唯一的方法(C / C ++项目)吗?

时间:2010-05-10 12:12:40

标签: c architecture dll plugins design-decisions

简介

我目前正在开发一个C / C ++文档分类器软件,我将使用Naive-Bayesian模型进行分类。但是我希望用户使用他们想要的任何算法(或者我将来想要的),因此我将体系结构中的算法部分分离为一个插件,该插件将附加到主app @ app启动。因此,任何用户都可以将自己的算法编写为插件,并将其与我的应用程序一起使用。

问题陈述:

我打算开发这种方法的方法是将用户想要使用的每个算法制作成DLL文件并放入特定目录。一开始,我的应用程序将搜索该目录中的所有DLL并加载它们。

我的问题:

(1)如果将恶意代码作为DLL(并且具有插件框架规定的相同功能)并将其放入我的插件目录中该怎么办?在这种情况下,我的应用程序会认为它是一个插件并选择它并调用其功能,因此恶意代码可以轻松地降低我的整个应用程序(在最坏的情况下可能使我的应用程序作为恶意代码启动器!!!)

(2)使用DLL是实现插件设计模式的唯一方法吗? (不仅是因为害怕恶意插件,而是出于好奇心的一般性问题:))

(3)我认为很多软件都是用插件模型编写的,用于扩展性,如果是这样,他们如何防御这种攻击?

(4)一般来说,您如何看待我决定使用插件模型进行扩展(您认为我应该考虑其他任何替代方案吗?)

谢谢

-MicroKernel:)

7 个答案:

答案 0 :(得分:6)

  1. 不要担心恶意插件。如果有人设法将恶意DLL潜入该文件夹,他们可能也有权直接执行这些东西。

  2. 作为DLL的替代方案,您可以连接像Python或Lua这样的脚本语言,并允许脚本化插件。但也许在这种情况下你需要编译代码的速度?

    要嵌入Python,请参阅here。这个过程并不是很困难。您可以静态链接到解释器,因此用户无需在其系统上安装Python。但是,任何非内置模块都需要随应用程序一起提供。

    但是,如果语言对您来说无关紧要,嵌入Lua可能更容易,因为它是专门为该任务设计的。请参阅其手册的this section

  3. 参见1.他们没有。

  4. 使用插件模型听起来像是一个很好的解决方案,前提是此时 是一个问题,但缺乏可扩展性。如果事实证明实际需要它,那么对当前模型进行硬编码可能会更容易,并在以后添加插件界面。它很容易添加,但一旦人们开始使用它就很难删除。

答案 1 :(得分:4)

恶意代码不是DLL的唯一问题。即使是一个善意的DLL也可能包含一个可能导致整个应用程序崩溃或逐渐泄漏内存的错误。

使用高级语言加载模块可以降低风险。如果您想学习嵌入Python,例如documentation is here

另一种方法是在单独的进程中启动插件。它确实需要您付出更多努力才能实现,但它更安全。 Google的Chrome网络浏览器使用单独的流程方法,他们有a document describing the architecture

基本思想是为插件编写者提供一个库,其中包含与主应用程序通信的所有逻辑。这样,插件作者就可以使用他们使用的API,就像他们正在编写DLL一样。维基百科有一个很好的list of ways for inter-process communication (IPC)

答案 2 :(得分:3)

1)如果插件文件夹中存在恶意dll,则可能已经入侵。

2)不,你可以从文件动态加载汇编代码,但这只是重新发明轮子,只需使用DLL。

3)Firefox扩展程序没有,甚至没有它的javascript插件。我所知道的其他所有内容都使用动态库中的本机代码,因此无法保证安全性。然后Chrome再次使用NaCL对二进制代码进行了广泛的分析并拒绝它,如果它不能100%确定它不违反界限,那么不会,尽管我确信随着时间的推移它们会有越来越多的漏洞

4)插件很好,只是将它们限制在可信赖的人身上。或者,您可以使用LUA,Python,Java等安全语言,并将文件加载到该语言中,但仅将其限制为不会损害您的程序或环境的API子集。

答案 3 :(得分:3)

(1)您是否可以使用操作系统安全设施来防止未经授权访问搜索或加载DLL的文件夹?那应该是你的第一个方法。

否则:进行威胁分析 - 风险是什么,已知的攻击媒介等等。

(2)不一定。如果你想要编译插件,它是最直接的 - 这主要是性能问题,操作系统功能的访问等。如上所述,考虑编写脚本语言。

(3)通常通过写“防止恶意代码执行,限制对插件文件夹的访问”。

(4)还有一些额外的成本 - 即使使用你还不熟悉的插件框架。它增加了成本:

  • 核心应用程序(插件功能)
  • 插件(更高的隔离度)
  • 安装
  • 调试+诊断(仅在某些插件组合时出现的错误)
  • 管理(用户必须知道并管理插件)

仅在

时支付
  • 安装/更新主软件比更新插件要复杂得多
  • 需要单独更新各个组件(例如,用户可以组合不同版本的插件)
  • 其他人为您的主要应用程序开发插件

(将代码移入DLL中还有其他好处,但它们与插件无关)

答案 4 :(得分:1)

  

如果将恶意代码设为DLL

,该怎么办?

通常,如果您不信任dll,则无法以这种或那种方式加载它。

这对几乎任何其他语言都是正确的,即使它被解释了。

Java和一些语言非常难以限制用户可以执行的操作,这仅仅因为它们在虚拟机中运行而起作用。

所以没有。 Dll加载的插件只能来自可靠来源。

  

使用DLL是实现插件设计模式的唯一方法吗?

您也可以在代码中嵌入一些解​​释器,例如GIMP允许编写插件 在python中。

但要注意这个事实会慢很多,因为如果是任何解释语言的性质。

答案 5 :(得分:1)

我们的产品非常相似,因为它使用模块来扩展功能。

我们做两件事:

  1. 我们使用封面下的DLL作为BPL文件。这是来自C ++ Builder中Borland / Codegear / Embarcadero的特定技术。我们利用一些RTTI类型的特性来发布一个类似于main(argv [])的简单API,这样就可以将任意数量的参数压入堆栈并由DLL弹出。

  2. 我们还将PERL嵌入到我们的应用程序中,以寻找更具业务逻辑性的内容。

  3. 我们的软件是会计/ ERP套件。

答案 6 :(得分:0)

查看现有的插件架构,看看是否有任何可以重用的内容。 http://git.dronelabs.com/ethos/about/是我在搜索glib +插件时遇到的一个链接。 glib本身可能更容易开发插件架构。 Gstreamer使用glib并且有一个非常好的插件架构,可能会给你一些想法。