Как определить подсистему приложения из исполняемого файла - PullRequest
5 голосов
/ 06 мая 2010

Я пытаюсь обнаружить консольное приложение из списка исполняемых файлов, установленных на моем компьютере.

Как это реализовать?

У каждого приложения есть «подсистема» (приложение Windows, консольное приложение или библиотека; я думаю, что для компоновщика это опция). Как обнаружить его, используя только исполняемый файл?

Существуют ли альтернативные методы определения характеристик приложения? Кроме того, есть ли способ определить, является ли файл действительно исполняемым файлом?

Есть ли проблемы с исполняемыми файлами JAR?

Ответы [ 3 ]

4 голосов
/ 06 мая 2010

Без программирования вы получаете эту информацию от

dumpbin.exe /headers filename

Некоторая информация дает вам функции GetBinaryType и SHGetFileInfo. Всю информацию, которая вам нужна, вы найдете в заголовке каждого исполняемого файла. См. Спецификацию формата исполняемого файла Microsoft Common и формата общего объекта в http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx.

Можно также использовать API библиотеки отладки из файла DbgHelp.dll (см. Структуры http://msdn.microsoft.com/en-us/library/ms679309(VS.85).aspx). IMAGE_DOS_HEADER, IMAGE_DOS_SIGNATURE и IMAGE_NT_HEADERS32 для получения полной информации.

ОБНОВЛЕНО (добавить код) : Или вы можете использовать только структуры, определенные в 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;
        }
1 голос
/ 06 мая 2010

Чтобы определить подсистему, вам нужно прочитать исполняемый файл и проанализировать PE-заголовок. Подробную статью о том, как это сделать , можно найти здесь .

JAR-файл - это просто ZIP-файл с некоторыми конкретными файлами и структурой папок, так что вы можете открыть его как обычный zip-файл и искать те файлы и папки, которые всегда есть.

1 голос
/ 06 мая 2010

Исполняемые файлы Windows PE имеют поле в заголовке, которое указывает подсистему (Console, GUI, Posix и т. Д.). У них также есть поля, которые можно использовать для идентификации исполняемых файлов в целом. Загрузите спецификацию PE с msdn.com, чтобы получить подробности.

...