6

我在我的程序中使用了一个静态库,它只能将文件名作为输入,而不是实际的文件内容。对于库的源代码,我无能为力。所以我想:创建一个全新的文件,将要处理的数据存储到其中,将其刷新到磁盘上(?),将其名称传递给库,然后将其删除。

但我也希望这个过程相当安全:
1)必须重新创建文件,没有任何虚假数据(也许它并不重要,但无论如何);
2)除我的进程之外的任何人都不能读取或写入该文件(我希望库处理我的实际数据,而不是一些聪明人设法插入的虚假数据);
3)在我完成这个文件之后,它必须被删除(好吧,如果有人TerminateProcess()我,我想没有什么可以做的,但仍然)。

该库似乎使用非 Unicodefopen()来打开给定的文件,所以我不太确定如何处理所有这些,因为该程序旨在在 Windows 上运行。有什么建议么?

4

6 回答 6

4

您已经有很多建议,但我认为没有提到的另一个选项是使用命名管道。它将取决于所讨论的库是否有效,但它可能值得一试。您可以使用该函数在应用程序中创建命名管道,并将CreateNamedPipe管道名称传递给库以进行操作(您将传递的文件名是\\.\pipe\PipeName)。库是否接受这样的文件名是您必须尝试的,但如果它有效,则优势是您的文件永远不必实际写入磁盘。

于 2013-01-09T09:40:45.723 回答
2

这篇文章应该给你一些关于这个问题的很好的指导。

事情的要旨是这样的:

  • POSIX mkstemp()函数是可用的安全且首选的解决方案。不幸的是,它在 Windows 中不可用,因此您需要找到一个使用 Windows API 调用正确实现此功能的包装器。
  • 在 Windows 上,tmpfile_s()函数是唯一真正以原子方式打开临时文件的函数(而不是简单地生成文件名),从而保护您免受竞争条件的影响。不幸的是,此功能不允许您指定将在哪个目录中创建文件,这是一个潜在的安全问题。
于 2013-01-09T08:55:37.530 回答
2

这可以使用CreateFileandGetTempFileName函数来实现(如果您不知道是否可以写入当前工作目录,您可能还想使用 , GetTempPath)。

  1. 确定一个目录来存储你的临时文件;当前目录(“。”)或结果GetTempPath将是很好的候选者。
  2. 用于GetTempFileName创建临时文件名。
  3. 最后,调用CreateFile创建临时文件。

对于最后一步,有几点需要考虑:

  • dwFlagsAndAttributes参数CreateFile大概应该包括FILE_ATTRIBUTE_TEMPORARY.
  • dwFlagsAndAttributes参数可能还应该包括FILE_FLAG_DELETE_ON_CLOSE以确保无论如何都删除文件(如果您的进程崩溃,这可能也有效,在这种情况下,系统会为您关闭所有句柄)。
  • dwShareMode参数CreateFile可能应该是FILE_SHARE_READ这样其他尝试打开文件将成功,但仅用于读取. 这意味着您的库代码将能够读取该文件,但没有人能够写入它。
于 2013-01-09T08:44:51.203 回答
0

虽然给出的建议很好,例如使用 FILE_SHARE_READ、FILE_DELETE_ON_CLOSE 等,但我认为没有完全安全的方法可以做到这一点。

我使用 Process Explorer 关闭了旨在阻止第二个进程启动的文件 - 我这样做是因为第一个进程被卡住并且“不可杀死且未死,但没有响应”,所以我有正当理由这样做- 由于系统上正在运行其他进程,我不想在该特定点重新启动机器。

如果有人使用某种调试器[包括非商业的,专门为此目的编写的],附加到您正在运行的进程,设置断点并停止代码,然后关闭您打开的文件,它可以写入文件你刚刚创建。

您可以让它变得更难,但您无法阻止具有足够特权/技能/能力的人拦截您的程序并操纵数据。

请注意,文件/文件夹保护仅在您可靠地知道用户在计算机上没有特权帐户时才有效 - 典型的 Windows 用户要么立即成为管理员,要么拥有另一个用于管理目的的帐户 - 我有权访问 sudo/root我在工作中使用的几乎所有 Linux 机器——有些文件服务器我没有 [也不应该] 具有 root 访问权限。但是我自己使用的所有盒子或可以借用的测试目的,我都可以进入根环境。这不是很不寻常。

我能想到的一个解决方案是找到一个使用不同接口的不同库[或获取库的源并对其进行修改以使其]。并不是说这可以防止使用上述调试器方法的“停止、修改和继续”攻击。

于 2013-01-09T09:03:48.563 回答
0

首先,您可以在用户的​​临时文件夹(例如 C:\Users\\AppData\Local\Temp)中创建文件 - 这是存放此类文件的理想场所。其次,在创建文件时,您可以指定,您提供什么样的访问共享。

MSDN 上 CreateFile 帮助页面的片段:

dwShareMode

  • 0阻止其他进程在请求删除、读取或写入访问权限时打开文件或设备。
  • FILE_SHARE_DELETE启用对文件或设备的后续打开操作以请求删除访问权限。否则,如果其他进程请求删除访问权限,它们将无法打开文件或设备。如果未指定此标志,但已打开文件或设备以进行删除访问,则函数失败。注意:删除访问允许删除和重命名操作。
  • FILE_SHARE_READ启用对文件或设备的后续打开操作以请求读取访问权限。否则,如果其他进程请求读取访问权限,它们将无法打开文件或设备。如果未指定此标志,但已打开文件或设备以进行读取访问,则函数失败。
  • FILE_SHARE_WRITE启用对文件或设备的后续打开操作以请求写入访问权限。否则,如果其他进程请求写访问权限,它们将无法打开文件或设备。如果未指定此标志,但已打开文件或设备以进行写访问或具有具有写访问权限的文件映射,则该函数将失败。
于 2013-01-09T08:33:03.150 回答
-1

使用 CreateFile API 在可执行文件的文件夹中创建文件,您可以在每次创建文件时给文件名一些 UUID,这样其他进程就无法猜测文件名来打开它。并将其属性设置为隐藏。用完之后把文件删了就行了?

于 2013-01-09T08:23:21.030 回答