代码之家  ›  专栏  ›  技术社区  ›  Luca

如何从可执行文件确定应用子系统

  •  5
  • Luca  · 技术社区  · 15 年前

    我正在尝试从安装在我的计算机上的可执行文件列表中检测控制台应用程序。

    如何实施?

    每个应用程序都有一个“子系统”(Windows应用程序、控制台应用程序或库;我认为是作为选项指定给链接器)。如何只使用可执行文件检测它?

    是否有其他方法检测应用程序特性?此外,是否有任何方法可以检测文件是否是真正的可执行文件?

    JAR可执行文件有问题吗?

    3 回复  |  直到 15 年前
        1
  •  4
  •   Oleg    15 年前

    如果没有任何编程,您将从

    dumpbin.exe /headers filename
    

    一些信息提供了getBinaryType和shgetFileInfo函数。您需要的所有信息都可以在每个可执行文件的头文件中找到。请参阅中的Microsoft可移植可执行文件和通用对象文件格式规范。 http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx .

    还可以使用dbghelp.dll中的调试帮助库API(请参见 http://msdn.microsoft.com/en-us/library/ms679309(VS.85).aspx )图像头、图像签名和图像头32结构为您提供完整的信息。

    更新(添加一些代码) : 或者只能使用winnt.h中定义的结构。相应的代码可以如下开头

    // Open source file
    hSrcFile = CreateFile (pszSrcFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    if (hSrcFile == INVALID_HANDLE_VALUE)
        __leave;
    
    // Map the source file in memory
    hMapSrcFile = CreateFileMapping (hSrcFile, NULL, PAGE_READONLY, 0, 0, NULL);    // SEC_IMAGE
    if (!hMapSrcFile || hMapSrcFile == INVALID_HANDLE_VALUE)
        __leave;
    
    // Map the entire of the source file is memory
    pSrcFile = (PBYTE) MapViewOfFile (hMapSrcFile, FILE_MAP_READ, 0, 0, 0);
    if (!pSrcFile)
        __leave;
    
    pDosHeader = (IMAGE_DOS_HEADER *)pSrcFile;
    
    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
        printf ("it is not a EXE file.\n");
        return 1;
    }
    printf ("IMAGE_DOS_HEADER size %d (0x%X) bytes\n",  sizeof(IMAGE_DOS_HEADER), sizeof(IMAGE_DOS_HEADER));
    
    DumpDosHeader (pDosHeader);
    pDosExeStart = (PBYTE)pDosHeader + pDosHeader->e_cparhdr*16;
    
    if (g_bDump)
        HexDump (1, pDosExeStart, pDosHeader->e_lfanew - pDosHeader->e_cparhdr*16, (DWORD)pDosExeStart);
    
    if (pDosHeader->e_lfanew) {
        IMAGE_NT_HEADERS32 *pNtHeader = (IMAGE_NT_HEADERS32 *)((PBYTE)pDosHeader + pDosHeader->e_lfanew);
        //IMAGE_NT_HEADERS64 *pNtHeader64 = (IMAGE_NT_HEADERS64 *)((PBYTE)pDosHeader + pDosHeader->e_lfanew);
        IMAGE_SECTION_HEADER *pFirstSectionHeader = (IMAGE_SECTION_HEADER *)((PBYTE)&pNtHeader->OptionalHeader +
                                                                                pNtHeader->FileHeader.SizeOfOptionalHeader);
    
        if (pNtHeader->Signature == IMAGE_NT_SIGNATURE) {
            int i;
    
            printf ("\nPE signature\n");
            printf ("\nIMAGE_FILE_HEADER: size %d (0x%X) bytes, offset from the begin of the file: %d (0x%X)\n",
                    sizeof(IMAGE_FILE_HEADER), sizeof(IMAGE_FILE_HEADER),
                    ((PBYTE)&pNtHeader->FileHeader - (PBYTE)pDosHeader), ((PBYTE)&pNtHeader->FileHeader - (PBYTE)pDosHeader));
            DumpFileHeader (1, &pNtHeader->FileHeader);
            switch (pNtHeader->OptionalHeader.Magic) {
                case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
                    printf ("\nIMAGE_OPTIONAL_HEADER32: size %d (0x%X) bytes, offset from the begin of the file: %d (0x%X)\n",
                            sizeof(IMAGE_OPTIONAL_HEADER32), sizeof(IMAGE_OPTIONAL_HEADER32),
                            ((PBYTE)&pNtHeader->OptionalHeader - (PBYTE)pDosHeader), ((PBYTE)&pNtHeader->OptionalHeader - (PBYTE)pDosHeader));
                    DumpOptionalHeader32 (1, &pNtHeader->OptionalHeader);
                    break;
                case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
                    break;
                case IMAGE_ROM_OPTIONAL_HDR_MAGIC:
                    break;
            }
    
        2
  •  1
  •   500 - Internal Server Error    15 年前

    Windows PE可执行文件在头中有一个指定子系统(控制台、GUI、POSIX等)的字段。它们也有一些字段,通常可以用来标识可执行文件。从msdn.com下载PE规范以获取详细信息。

        3
  •  1
  •   shoosh    15 年前

    要确定子系统,需要读取可执行文件并解析PE头。关于如何做到这一点的详细文章 is found here .

    JAR文件只是一个具有特定文件和文件夹结构的zip文件,因此您可以像打开常规zip文件一样打开它,并查找始终存在的文件和文件夹。

    推荐文章