【问题标题】:How to tell if a file is an EXE or a DLL?如何判断文件是EXE还是DLL?
【发布时间】:2011-09-12 15:27:01
【问题描述】:

如果你把文件扩展名弄乱了,你怎么能把可执行文件和 DLL 区分开来?

他们似乎都有切入点和一切......

【问题讨论】:

  • @OmerPT, @CharlesB:我的意思更像是通过它们的功能(例如它们的 PE 标头、它们的反汇编等)
  • 用扩展名exe重命名它并尝试在Windows环境中执行它。如果它做某事,它就是一个exe。 :P 其实我也很好奇...
  • 您可以检查 PE 标头。在此处查看 kichik 的答案:stackoverflow.com/questions/1210873/…
  • @anirudh4444:如果您正在查看资源/版本信息,是的——这是作弊,它并不总是有效。 :P
  • @Mehrdad 接受的答案并没有说太多,但 kichik 的答案是正确的:“可以在 IMAGE_NT_HEADERS 中查看 IMAGE_FILE_HEADER 的特性成员。对于 DLL,它具有 IMAGE_FILE_DLL ( 0x2000) 标志打开。对于 EXE,它是 IMAGE_FILE_EXECUTABLE_IMAGE (0x2) 标志“-我将把一些代码放在一起。

标签: dll executable file-extension portable-executable


【解决方案1】:

抓取 OllyDbg 并打开其中的 EXE/DLL。单击顶部的大 M 按钮调出内存映射。向下滚动,直到找到与您的程序相对应的模块的 PE 标头。双击以在内存转储中打开它。向下滚动到您看到 PE 签名的位置(可能是图像库中的 0xF8),如果它是一个 DLL,那么特性上就会有 DLL 标志。特征应该比 PE 签名少几个整数。

【讨论】:

    【解决方案2】:

    查看this article 以获得对 Windows 上可移植可执行文件的良好解释。

    然后看一下关于PE头的部分。此外,其中的代码以 C 语言显示了使用 Win32 打开和检查 PE 文件的方式。您要查找的信息存储在IMAGE_FILE_HEADER 中。特别是在 Characteristics 字段中,如果它是 dll,则该字段将包含标志 IMAGE_FILE_DLL 0x2000。

    这应该为您提供了足够的信息来创建一个小型实用程序,该实用程序可以确定一堆文件(如果这是您要查找的文件)。

    用于参考目的的最相关代码位,从上面的文章中复制并编辑以删除无关的细节/错误处理。

    void DumpFile(LPWSTR filename)
    {
        HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
        HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    
        LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);    
    
        PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
    
        PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew);
    
        if ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_DLL))
             printf("dll"); 
        if ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
             printf("exe"); 
        else 
             printf("????");
    
        UnmapViewOfFile(lpFileBase);
        CloseHandle(hFileMapping);
        CloseHandle(hFile);
    }
    

    【讨论】:

    • 再想一想,我意识到上面的代码行不通(已经很久了)。它不会正确获取文件头。当我有时间时,我会尝试纠正它
    【解决方案3】:
    dumpbin *.* | grep "File Type"
    

    为我工作。如果您没有安装 grep,我不完全记得要使用什么,但我建议您这样做。

    【讨论】:

      【解决方案4】:

      此信息位于 PE 标头中。要查看它,您可以使用NTCore CFF Explorer 等PE 资源管理器打开它,然后打开文件头的Characterics 字段,您可以在其中找到它是DLL 还是可执行文件。

      【讨论】:

        【解决方案5】:

        如果有人对这里感兴趣的是 C# 中的代码,经过 32 位 PE 文件测试。

         public static class PECheck
            {
        
                public static bool IsDll(Stream stream)
                {
        
                    using (BinaryReader reader = new BinaryReader(stream))
                    {
        
                        byte[] header = reader.ReadBytes(2); //Read MZ
                        if (header[0] != (byte)'M' && header[1] != (byte)'Z')
                            throw new Exception("Invalid PE file");
        
                        stream.Seek(64 - 4, SeekOrigin.Begin);//read elf_new this is the offset where the IMAGE_NT_HEADER begins
                        int offset = reader.ReadInt32();
                        stream.Seek(offset, SeekOrigin.Begin);
                        header = reader.ReadBytes(2);
                        if (header[0] != (byte)'P' && header[1] != (byte)'E')
                            throw new Exception("Invalid PE file");
        
                        stream.Seek(20, SeekOrigin.Current); //point to last word of IMAGE_FILE_HEADER
                        short readInt16 = reader.ReadInt16();
                        return (readInt16 & 0x2000) == 0x2000;
        
                    }
                }
            }
        

        【讨论】:

          猜你喜欢
          • 2010-11-01
          • 2013-01-11
          • 2011-10-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多