如何判断文件是EXE还是DLL?

如何判断文件是EXE还是DLL?,dll,executable,file-extension,portable-executable,Dll,Executable,File Extension,Portable Executable,如果你把文件扩展名搞砸了,你怎么能把可执行文件和DLL区分开呢 它们似乎都有入口点和所有东西…抓取OllyDbg并打开其中的EXE/DLL。点击顶部的大M按钮打开内存映射。向下滚动,直到找到与您的程序相对应的模块的PE标头。双击以在内存转储中打开它。向下滚动到您看到PE签名的位置(可能是图像库中的0xF8),如果它是一个DLL,则特征将在其上显示DLL标志。特征应该比PE签名低几个百分点。看看windows上可移植可执行文件的详细说明 然后看看关于PE标题的部分。另外,其中的代码在C中显示了使用

如果你把文件扩展名搞砸了,你怎么能把可执行文件和DLL区分开呢


它们似乎都有入口点和所有东西…

抓取OllyDbg并打开其中的EXE/DLL。点击顶部的大M按钮打开内存映射。向下滚动,直到找到与您的程序相对应的模块的PE标头。双击以在内存转储中打开它。向下滚动到您看到PE签名的位置(可能是图像库中的0xF8),如果它是一个DLL,则特征将在其上显示DLL标志。特征应该比PE签名低几个百分点。

看看windows上可移植可执行文件的详细说明

然后看看关于PE标题的部分。另外,其中的代码在C中显示了使用Win32打开和检查PE文件的方法。您要查找的此信息存储在中。特别是在
特征
字段中,如果是DLL,该字段将包括标志
图像文件_dll0x2000

这将为您提供足够的信息,以创建一个小型实用程序,确定一组文件,如果这是您正在寻找的

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

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);
}

对我有用。如果您没有安装grep,我不太清楚该使用什么,但我建议您这样做。

此信息位于PE标题中。要查看它,您可以使用PE资源管理器(如)打开它,并打开文件头的Characterics字段,从中可以找到它是DLL还是可执行文件


如果有人对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;

            }
        }
    }

@OmerPT,@CharlesB:我的意思是更像是通过它们的特性(例如它们的PE头、它们的反汇编等等)将其重命名为扩展名
exe
,并尝试在Windows环境中执行它。如果它做了什么,它就是一个exeP实际上我也很好奇…你可以检查PE标题。请看kichik的回答:@anirudh4444:如果您正在查看资源/版本信息,是的——这是欺骗,并不总是有效的P@Mehrdad公认的答案说的不多,但kichik的答案是正确的:“你可以在IMAGE\u NT\u头中查看IMAGE\u FILE\u头的特征成员。对于DLL,它打开了IMAGE\u FILE\u DLL(0x2000)标志。对于EXE,它是IMAGE\u FILE\u EXECUTABLE\u IMAGE(0x2)标志。”-我会把一些代码放在一起实现这一点。再仔细想想,我意识到上面的代码是行不通的(已经很长时间了)。它无法正确获取文件头。等我有空的时候,我会尽力改正的
 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;

            }
        }
    }