如何在不使用-T / -B的情况下从二进制数据中识别源代码?

时间:2012-10-10 16:02:58

标签: perl

我想在Perl中的二进制文件上使用binmode。那么我怎么知道手边的文件是二进制还是文本?

这意味着首先我要读完整个文件,知道它是二进制文本还是文本,然后使用binmode设置回放FP,如果它是二进制文件。

由于Perl -B / -T仅检查文本的起始块,因此它通常将pdf分类为文本文件(源代码可能隐藏在任何扩展名中,如.gif,.pdf等)。因此,我需要读取完整的文件数据,以确定它是二进制文件还是文本文件。

我听说任何源代码文件(.pl,.c,.php等)都不会包含0x0-0x1f和0xff之类的不可见字符。

我是否可以检查此范围内的每个字节以声明它是否是源代码文件?

3 个答案:

答案 0 :(得分:2)

如果您对安全性感到偏执,只需确保从数据中分离可执行文件即可。 binmode对此没有帮助:它可用于克服DOS和后代上的行结束恐怖,并可用于指定透明编码。

对于您的顾虑,所有用户上传的文件 都是恶意的。没有“安全”格式,因此从“文本”文件中分离“二进制”是没用的。不要相信简单的启发式方法。 (例如Perl允许control characters in variable names!)

处理用户数据时,Perl的一些关键部分应确保没有未经检查的输入:

  1. 可以通过(?{}) and (??{})执行正则表达式任意代码。
  2. systemexecqx(),反对自我解释
  3. eval - 插入变量时要小心。
  4. 其他有趣的观点是openglob和C-ish字符串函数的参数。
  5. binmode不属于这些。

    如果您必须提供用户指定的数据,请尝试将其传递给未处理的数据。例如。在用户定义的样式表的情况下,属于php不解释的目录。如果是图像,您可以尝试在收到文件后进行转换并保存等效但可能安全的变体。

答案 1 :(得分:2)

如果是文本文件,你真的需要在文本模式下读取文件吗?您可以无条件地使用binmode

如果您有一段处理文本文件的代码,它可以过滤掉任何无关的回车(0D)。如果你没有这样的代码,那么回车是否留下来肯定无关紧要。

答案 2 :(得分:1)

问题是在现代POSIX系统上,二进制文件和文本文件之间没有区别;一个字节是一个字节是一个字节。

我宁愿尝试另一种方法。如果您使用Linux / Unix,则可以直接利用file实用程序使用“magic”来查看文件的第一个字节(或者在某些情况下),并确定其类型;在Windows中,您必须先安装它。该实用程序使得捕获可执行文件,zip文件等变得相对简单。

在Perl中,您可以通过模块File::Type使用它。