【问题标题】:How to distinguish between normal exe file and self-extracting file in C#?C#中如何区分普通exe文件和自解压文件?
【发布时间】:2017-01-17 04:36:36
【问题描述】:

我想检测使用 zip 工具创建的exe 文件?比如7zWinRAR 或...,我的意思是SFX(自解压可执行文件)文件

所以我必须找到一种方法来区分 C# 中的普通 exe 文件和 SFX 文件?
有什么方法可以在 C# 中检测到它们吗?

【问题讨论】:

  • WinRAR 有marker block sequence,但它只适用于 WinRAR。那里的评论建议使用元解决方案,只需使用 7z 或 unRAR 尝试提取文件(这可能是也可能不是您想要的,具体取决于大小和实际要求)

标签: c# winrar sfx


【解决方案1】:

我不知道其他实用程序,但 Nico Mak Computing 的“经典”自解压器创建包含 _winzip_ 部分的可执行文件。这些可以通过读取可执行文件的节表来检测,该节表是IMAGE_SECTION_HEADER 结构的数组。

要在不使用专门库的情况下访问它,您需要:

  • 在文件上打开一个流
  • 读取64字节IMAGE_DOS_HEADER结构
  • 取其最后一个成员(四个字节)作为下一个头的偏移量
  • 寻找这个偏移量
  • 阅读 4 字节 PE 魔法
  • 读取 20 字节的 IMAGE_FILE_HEADER 结构
  • 接受其成员SizeOfOptionalHeader(倒数第二个字)
  • 跳过那么多字节
  • 流现在指向节表

然后就是读取section表(IMAGE_FILE_HEADER结构有一个成员NumberOfSections),看看有没有一个叫_winzip_

【讨论】:

    【解决方案2】:

    如果您想检测自提取器,则采取的方法会有所不同,具体取决于您是想以 100% 的可靠性检测一组已知格式中的自提取器,还是想以较低的可靠性检测不熟悉的自提取器.

    (这两种方法都有其用途。例如,后者很适合召集人征求第二意见。)

    选项 A 将使用与归档工具相同的方法。

    自解压存档只是一个常规存档,连接到一个 EXE 文件中,并固定了偏移量。 (对于 Zip 文件,您可以使用 Info-ZIP 中的 zip -A 手动执行此操作),因此打开文件并扫描,寻找有效的 RAR/Zip/等。标题/拖车。 (要有效地做到这一点,请使用类似Aho-Corasick 的算法一次性搜索所有候选字符串。)

    为了获得更高的可靠性,请解析 MZ 和 NE 或 PE 标头以确定跳过多少字节以跳过 EXE 本身中的任何潜在匹配字符串。

    选项 B 将按照 Medinoc 的描述解析 MZ 标头,但随后不是在 PE 标头中查找特定部分,而是计算 NE 或 PE 二进制文件的总长度(Win16 自解压器确实存在,如由 WinZIP 6.3 SR-1 及更低版本等工具创建)并全部跳过。

    然后,做一些启发式检查,例如将跳过的 EXE 部分的大小与整个文件的大小进行比较,并确定 EXE 部分的小和连接到它的东西的大是否看起来像一个自己的特征-提取器。

    (请记住,如果您不对非 NE/非 PE 文件进行额外检查以排除它们,这也可能会捕获基于 DPMI 的 DOS 应用程序,因为它们也使用“存根加上连接在"结构。)

    最可靠的解决方案是结合这两种方法:

    1. 使用选项 A 并检查所有现代或历史上常见的基于 EXE 的自提取器格式(7zRARACEZipARJARCLha/LZHZooInnoSetup 安装程序、NSIS 安装程序、InstallShield.msi 时代的单文件安装程序,或包含.cab 或@987654335 的EXE @捆绑。)

    2. 如果您没有找到匹配项,请使用选项 A 排除 .NET EXE 文件、常见 DPMI 扩展程序和其他可能作为穷人资源包连接到 EXE 上的常见批量内容。 (例如图像、音频、视频等)

      要为 DPMI EXE 创建测试文件,只需编译“Hello, World!”使用djgpp (Linux) 和 Open Watcom C/C++ (1.9, 2.0) 到 DPMI 目标。 djgpp 将为您提供 CWSDPMI,而 OpenWatcom C/C++ 包括 DOS/4GW、PMODE/W、DOS/32A 和 CauseWay DPMI 扩展器、Win386 windows 扩展器,并且与other free/freed extenders 兼容。 (PharLap 的扩展程序,微软许可包含在 Microsoft C/C++ 中,是我所知道的唯一没有被释放的值得注意的扩展程序,但我相信 Open Watcom 至少可以生成他们应该的二进制文件被添加到前面。)

      您可能还需要排除可执行打包程序,因为它们使用基于存根的系统。 UPX 几乎是今天唯一使用的一个,但从历史上看,有一个 lot of them

    3. 作为后备,解析 MZLENEPE 标头以正确计算嵌入资源(例如图标)作为 EXE 部分的一部分,然后,如果文件超过一定百分比的“额外数据”,它很可能是自解压器。

    【讨论】:

      【解决方案3】:

      您只需将.exe 格式转换为.rar 格式并双击打开(不解压缩)即可查看内容,如果您的WinRAR7z 设法为您打开它。但是,如果您在尝试查看 .rar 文件中的内容时遇到错误,那么很可能是正常的 .exe 文件。

      我相信还有其他方法,但这是我常用的一种,因为它非常简单。

      话虽如此,你需要让 C# 做的是:

      1. 将文件格式更改为.rar
      2. 使用 WinRAR 或 7z 打开文件
      3. 使用try-catch块,如果打开失败则给出错误消息,否则如果打开成功则给出肯定消息。

      如果您在更改文件格式方面需要帮助,可以查看以下内容:Change File Extension Using C#

      如果您在打开文件方面需要帮助:How do I launch files in C#

      【讨论】:

        【解决方案4】:

        如果它是来自任何压缩的 SFX,它肯定是一个标准的可执行文件..

        所以你可以采取方法来验证可执行文件与否

        How to find if a file is an exe?

        查看 Chris Schmich 的答案

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-23
          • 2011-02-22
          • 2011-11-15
          • 1970-01-01
          • 2023-03-06
          • 1970-01-01
          • 2011-12-02
          • 1970-01-01
          相关资源
          最近更新 更多