Почему мой PE-файл недействителен?

Я уже задавал аналогичный вопрос, "Требования к заголовку PE", но я не очень доволен этим отвечать.

Я создаю ассемблер/компоновщик в Java SE 1.6. Я прочитал около 5 различных документов/спецификаций о заголовке PE/COFF и формате файла, но я застрял в проблеме:

Мой сгенерированный файл недействителен, говорит Windows: "X не является допустимым приложением Win32." Я понятия не имею, что может быть не так; Я перепроверил каждую запись в заголовке PE и дополнительном заголовке PE, и все вроде бы правильно.
У меня есть три раздела:

  • code (RVA 0x1000, файл 0x400)
  • data (РВА 0x2000, файл 0x600)
  • import (РВА 0x3000, файл 0x800)

Мое значение точки входа равно 0x1000 (начало code), а моя база изображений — 0x400000. Выравнивание раздела — 0x1000, а выравнивание файла — 0x200.

Просмотрите версии этого вопроса, чтобы увидеть весь файл.

Итак: я взял действительный PE-файл (простое приложение окна сообщений «Hello World») и начал изменять его с помощью шестнадцатеричного редактора (HxD). Я получил много разных сообщений об ошибках, не «X не является допустимым приложением Win32.»:

Я знаю, что мой контент code не является «действительным» кодом, но я проверил его: неверный код приводит к ошибке сбоя приложения.

Если содержимое раздела импорта недопустимо в PE-файле «Hello World», это выдает мне ошибку «Точка процедуры не может быть найдена в [...]» или «Не удалось запустить приложение, потому что [..] dll не найдено.», или сбой приложения. Все эти ошибки очень полезны; все они дают мне понять, что было не так.

Но мой PE-файл с ошибкой «X не является допустимым приложением Win32» сводит меня с ума: Что не так с моим PE-файлом?

Выход из мусорной корзины:

E:\Documenten\CP Language\compiler\Win32Builder>dumpbin /ALL test.exe
Microsoft (R) COFF/PE Dumper Version 10.00.21003.01
Copyright (C) Microsoft Corporation.  All rights reserved.
Dump of file test.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
         14C machine (x86)
           3 number of sections
    32EB4BF5 time date stamp Sun Jan 26 13:20:05 1997
           0 file pointer to symbol table
           0 number of symbols
          E0 size of optional header
         703 characteristics
               Relocations stripped
               Executable
               32 bit word machine
               Debug information stripped
               CD - run from swapfile

OPTIONAL HEADER VALUES
         10B magic # (PE32)
        8.00 linker version
        1000 size of code
        1000 size of initialized data
           0 size of uninitialized data
        1000 entry point (00401000)
        1000 base of code
        2000 base of data
      400000 image base (00400000 to 0040088F)
        1000 section alignment
         200 file alignment
        4.00 operating system version
       13.37 image version
        4.00 subsystem version
           0 Win32 version
         890 size of image
         400 size of headers
           0 checksum
           2 subsystem (Windows GUI)
           0 DLL characteristics
       40000 size of stack reserve
       11000 size of stack commit
      100000 size of heap reserve
        1000 size of heap commit
           0 loader flags
          10 number of directories
           0 [       0] RVA [size] of Export Directory
        3000 [    1000] RVA [size] of Import Directory
           0 [       0] RVA [size] of Resource Directory
           0 [       0] RVA [size] of Exception Directory
           0 [       0] RVA [size] of Certificates Directory
           0 [       0] RVA [size] of Base Relocation Directory
           0 [       0] RVA [size] of Debug Directory
           0 [       0] RVA [size] of Architecture Directory
           0 [       0] RVA [size] of Global Pointer Directory
           0 [       0] RVA [size] of Thread Storage Directory
           0 [       0] RVA [size] of Load Configuration Directory
           0 [       0] RVA [size] of Bound Import Directory
           0 [       0] RVA [size] of Import Address Table Directory
           0 [       0] RVA [size] of Delay Import Directory
           0 [       0] RVA [size] of COM Descriptor Directory
           0 [       0] RVA [size] of Reserved Directory

SECTION HEADER #1
   .code name
    1000 virtual size
    1000 virtual address (00401000 to 00401FFF)
      23 size of raw data
     400 file pointer to raw data (00000400 to 00000422)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         Execute Read    
RAW DATA #1
  00401000: 68 00 00 00 00 68 0D 20 40 00 68 00 20 40 00 68  h....h. @.h. @.h
  00401010: 00 00 00 00 E8 64 30 40 00 68 00 00 00 00 E8 6C  ....è[email protected]....èl
  00401020: 30 40 00                                         0@.

SECTION HEADER #2
   .data name
    1000 virtual size
    2000 virtual address (00402000 to 00402FFF)
      23 size of raw data
     600 file pointer to raw data (00000600 to 00000622)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0000040 flags
         Initialized Data
         Read Write
RAW DATA #2
  00402000: 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 48 65 6C  Hello World!.Hel
  00402010: 6C 6F 20 53 74 61 63 6B 20 4F 76 65 72 66 6C 6F  lo Stack Overflo
  00402020: 77 21 00                                         w!.

SECTION HEADER #3
 .import name
    1000 virtual size
    3000 virtual address (00403000 to 00403FFF)
      90 size of raw data
     800 file pointer to raw data (00000800 to 0000088F)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
50000040 flags
         Initialized Data
         Shared
         Read Only
RAW DATA #3
  00403000: 54 30 00 00 00 00 00 00 00 00 00 00 3C 30 00 00  T0..........<0..
  00403010: 64 30 00 00 5C 30 00 00 00 00 00 00 00 00 00 00  d0..\0..........
  00403020: 47 30 00 00 6C 30 00 00 00 00 00 00 00 00 00 00  G0..l0..........
  00403030: 00 00 00 00 00 00 00 00 00 00 00 00 75 73 65 72  ............user
  00403040: 33 32 2E 64 6C 6C 00 6B 65 72 6E 65 6C 33 32 2E  32.dll.kernel32.
  00403050: 64 6C 6C 00 74 30 00 00 00 00 00 00 82 30 00 00  dll.t0.......0..
  00403060: 00 00 00 00 74 30 00 00 00 00 00 00 82 30 00 00  ....t0.......0..
  00403070: 00 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78  ......MessageBox
  00403080: 41 00 00 00 45 78 69 74 50 72 6F 63 65 73 73 00  A...ExitProcess.

  Section contains the following imports:

user32.dll
            403064 Import Address Table
            403054 Import Name Table
                 0 time date stamp
                 0 Index of first forwarder reference

                0 MessageBoxA

kernel32.dll
            40306C Import Address Table
            40305C Import Name Table
                 0 time date stamp
                 0 Index of first forwarder reference

                0 ExitProcess

Summary
    1000 .code
    1000 .data
    1000 .import

person Pindatjuh    schedule 20.03.2010    source источник


Ответы (3)


Вы определенно решаете эту проблему не с того конца. Взлом шестнадцатеричного кода никогда не даст вам того, что вы хотите, файловая структура PE слишком сложна. Вам понадобятся две вещи.

  • Для понимания структуры необходимо прочитать основную статью Мэтта Питрека. Не приступайте к работе с кодом, пока не поймете его хотя бы на 75%.
  • Вам понадобится Windows SDK. Файл include/winnt.h содержит объявления структур, используемых в формате PE. Он начинается с _IMAGE_DOS_HEADER, первого фрагмента файла.

Напишите код для создания структур из их объявлений, это единственный способ получить действительный исполняемый файл.

PS: ваши шестнадцатеричные дампы вешают браузеры всех, кто пытается посмотреть на ваш вопрос.

person Hans Passant    schedule 20.03.2010
comment
Спасибо. Я много читал о заголовке PE, многое в нем понимаю. Я не могу использовать Windows SDK: потому что я программирую на Java, который не может использовать файлы C-заголовков. Я взламываю с помощью HEX-редактора, потому что не знаю, почему мои структуры, которые я использую в Java, неверны. По поводу зависания браузера; как кто-нибудь может помочь мне с моей проблемой, если у них нет моего PE-файла? - person Pindatjuh; 20.03.2010
comment
Вы можете скопировать объявления структур и сделать их совместимыми с любым удобным для вас языком. Они не такие большие. Убедитесь, что вы все сделали правильно, сначала написав код, который читает EXE. Если вы погуглите имена участников, скорее всего, вы найдете код кого-то, кто уже сделал это. - person Hans Passant; 20.03.2010

Быстрый гугл показал:

http://rcecafe.net/?p=26. Никто здесь не собирается копаться в ваших байтах за вас, лучшее, что вы можете ожидать, это указатели на инструменты.

person bmargulies    schedule 20.03.2010

Размер изображения, согласно дампбину 890, в то время как это должен быть размер изображения в памяти, то есть RVA последнего раздела + округленный размер этого раздела (например, 0x5000 в этом случае).

Оно работает. Спасибо за ответы, особенно за подсказку dumpbin!

person Pindatjuh    schedule 20.03.2010