C++ 如何防止C+中的I/O访问+;或本机编译代码

C++ 如何防止C+中的I/O访问+;或本机编译代码,c++,networking,io,operating-system,storage,C++,Networking,Io,Operating System,Storage,我知道这可能是不可能的,但我真的希望有办法做到这一点。如果有什么办法,请告诉我 我想在C++中编写沙箱应用程序,并允许其他开发人员编写可以立即加载到应用程序中的本地插件。我可能希望通过Windows上的DLL实现这一点,但我也希望支持Linux,希望支持Mac 我的问题是,我希望能够阻止插件自己进行I/O访问。我想要求他们使用我的包装例程,这样我就可以确保没有任何插件编写恶意代码,开始损害用户在磁盘上的文件或在网络上做不希望的事情 我对如何实现这一点的最佳猜测是在应用程序中包含一个编译器,并要求

我知道这可能是不可能的,但我真的希望有办法做到这一点。如果有什么办法,请告诉我

我想在C++中编写沙箱应用程序,并允许其他开发人员编写可以立即加载到应用程序中的本地插件。我可能希望通过Windows上的DLL实现这一点,但我也希望支持Linux,希望支持Mac

我的问题是,我希望能够阻止插件自己进行I/O访问。我想要求他们使用我的包装例程,这样我就可以确保没有任何插件编写恶意代码,开始损害用户在磁盘上的文件或在网络上做不希望的事情

我对如何实现这一点的最佳猜测是在应用程序中包含一个编译器,并要求在最终用户平台上分发和编译插件的源代码。然后,我需要一个代码扫描器,可以搜索插件未编译代码中的签名,这些签名将显示在硬盘、网络或其他存储介质的I/O操作中

我的理解是,STD库喜欢fstream包装特定于平台的函数,因此我认为只要扫描所有将编译为特定于平台的函数的代码,就可以完成任务。因为最终,任何C本机代码都不能执行任何I/O,除非它使用操作系统提供的方法之一与操作系统对话,对吗

如果我的思路是正确的,那么有没有人推荐我在哪里可以找到Windows、Linux和Mac上这些东西的细节

如果我的思路不正确,并且我不可能真正阻止本机代码(已编译或未编译)单独执行I/O操作,请告诉我,这样我就不会创建一个我认为安全但实际上不安全的应用程序


在一个绝对理想的世界中,我不想要求插件分发未编译的代码。我希望允许开发人员自己编译和保存代码。也许我可以扫描二进制文件,寻找与I/O访问有关的签名???

沙箱化执行代码的程序肯定比仅仅扫描代码以获得特定访问更难!例如,程序可以通过系统调用合成汇编语句


unix上最初的方法是
chroot()
程序,但我认为这种方法也有问题。另一种方法是像selinux这样的安全环境,可以与
chroot()
结合使用。用于这样做的现代方法似乎是在虚拟机中运行程序:在程序启动时启动一个合适的虚拟机快照。终止后,只需倒带到snaphot即可。这仅仅要求允许的访问以某种方式在某个地方进行传输。

即使是虚拟机也不会阻止I/O。但它可以非常容易地阻止网络流量

如果你想确保插件不进行I/O操作,你可以扫描它的DLL中的所有导入函数,然后根据I/O函数的黑名单运行函数列表。 Windows有
dumpbin
util,Linux有
nm
。两者都可以通过
system()
函数调用运行,并且工具的输出可以定向到文件

当然,您可以编写自己的分析器,但这要困难得多


用户代码无法自行执行I/O。只有内核。如果您担心插件获得ring0/内核权限,则需要扫描DLL的ASM以获取I/O指令。

我唯一想到的是将插件隔离在单独的进程中,并对其进行沙箱处理,以便通过IPC进行通信。沙箱应用程序的细节可能会有所不同,但我认为不可能通过DLL来实现。另一种方法是嵌入禁止I/O的解释器,比如LUA。VM不会阻止I/O吗?我的印象是VM绝对是沙箱应用程序的最佳方式。当然,应用程序可以写入虚拟机中的虚拟磁盘,但我从来没有听说过应用程序能够脱离虚拟机。这取决于你所说的“虚拟机”是什么意思。在虚拟机监控程序下运行的虚拟机是最终的沙箱。但是用于提供运行时环境的虚拟机(例如,Java的JVM)没有多大帮助。@Jim-是的,VM(例如,VirtualBox)是沙盒的一种极好方法-它不会损坏主机操作系统。但是虚拟机内部的进程有I/O。这个I/O可能只影响虚拟设备,但这直到I/O。从你的问题中我了解到你想测试插件是否做I/O。我明白了。我说限制I/O的原因是为了保证数据的安全。例如,只要我能保证磁盘上的备份是安全的,我就不担心流氓插件会破坏内存中的数据。这样,在内存数据损坏且损坏的数据被应用程序保存到磁盘的情况下,您至少可以返回到以前的备份以恢复良好的数据。我只需要一个提供某种故障安全数据保护的生态系统。在此基础上,虚拟机箱提供了一个故障安全生态系统,因为您可以备份虚拟磁盘快照。如果快照受损,您始终可以返回到以前的快照。插件没有办法篡改快照备份。你能澄清一下,通过合成汇编语句进行系统调用是什么意思吗?Unix上的系统调用只是汇编语句,也就是说,你可以调用
write()
,而不显示此函数的符号。汇编代码可以很容易地嵌入到C源代码中,但即使没有它,您也可以使用有意的越界内存写入操作堆栈,并使函数调用它们不打算调用的东西。虽然通常不可能在数据段中调用代码,但是puttin