Подтвердить что ты не робот

Каков минимально возможный исполняемый файл Windows (PE)?

Как предшественник написания компилятора, я пытаюсь понять формат Windows (32-разрядный) Portable Executable. В частности, я хотел бы увидеть пример исполняемого файла bare-bones, который ничего не делает, кроме как правильно загружать, запускать и выходить.

Я пробовал писать и компилировать простую основную функцию C, которая ничего не делает, но результирующий файл .exe составляет ~ 22 КБ и содержит много импорта из KERNEL32.DLL(предположительно, используемое LIBC для настройки среды, кучи и т.д.). Даже заголовок DOS, вероятно, может быть меньше (в настоящее время он печатает по умолчанию "Эта программа не может быть запущена в режиме DOS" ).

Какова структура минимально возможного 32-битного исполняемого файла Windows?

4b9b3361

Ответ 1

Как указано из источника (создание наименьшего возможного PE-исполняемого файла): 1

  • Наименьший возможный PE файл: 97 байт
  • Самый маленький возможный PE файл в Windows 2000: 133 байт
  • Самый маленький PE файл, который загружает файл через WebDAV и выполняет его: 133 байта

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

Этот результат был достигнут с помощью некоторых умных трюков NASM, таких как удаление шага, который ссылается на C stdlib и удаление нескольких полей заголовков и каталогов данных.

Полный исходный код приведен ниже. Это фактически то же самое, что и статья с этими изменениями:

  • Удаление пустых строк
  • sectalign label переименован в sect_align. С момента написания этого ассемблерного кода sectalign стал ключевым словом NASM. Переименуйте его, чтобы избежать предупреждений и ошибок.

Код выглядит следующим образом:

; tiny97.asm, copyright Alexander Sotirov

BITS 32
;
; MZ header
; The only two fields that matter are e_magic and e_lfanew

mzhdr:
    dw "MZ"       ; e_magic
    dw 0          ; e_cblp UNUSED

; PE signature
pesig:
    dd "PE"       ; e_cp, e_crlc UNUSED       ; PE signature

; PE header
pehdr:
    dw 0x014C     ; e_cparhdr UNUSED          ; Machine (Intel 386)
    dw 1          ; e_minalloc UNUSED         ; NumberOfSections

;   dd 0xC3582A6A ; e_maxalloc, e_ss UNUSED   ; TimeDateStamp UNUSED

; Entry point
start:
    push byte 42
    pop eax
    ret

codesize equ $ - start

    dd 0          ; e_sp, e_csum UNUSED       ; PointerToSymbolTable UNUSED
    dd 0          ; e_ip, e_cs UNUSED         ; NumberOfSymbols UNUSED
    dw sections-opthdr ; e_lsarlc UNUSED      ; SizeOfOptionalHeader
    dw 0x103      ; e_ovno UNUSED             ; Characteristics

; PE optional header
; The debug directory size at offset 0x94 from here must be 0

filealign equ 4
sect_align equ 4  ; must be 4 because of e_lfanew

%define round(n, r) (((n+(r-1))/r)*r)

opthdr:
    dw 0x10B      ; e_res UNUSED              ; Magic (PE32)
    db 8                                      ; MajorLinkerVersion UNUSED
    db 0                                      ; MinorLinkerVersion UNUSED

; PE code section
sections:
    dd round(codesize, filealign)  ; SizeOfCode UNUSED  ; Name UNUSED
    dd 0  ; e_oemid, e_oeminfo UNUSED ; SizeOfInitializedData UNUSED
    dd codesize  ; e_res2 UNUSED  ; SizeOfUninitializedData UNUSED  ; VirtualSize
    dd start  ; AddressOfEntryPoint  ; VirtualAddress
    dd codesize  ; BaseOfCode UNUSED  ; SizeOfRawData
    dd start  ; BaseOfData UNUSED  ; PointerToRawData
    dd 0x400000  ; ImageBase  ; PointerToRelocations UNUSED
    dd sect_align ; e_lfanew  ; SectionAlignment  ; PointerToLinenumbers UNUSED
    dd filealign  ; FileAlignment  ; NumberOfRelocations, NumberOfLinenumbers UNUSED
    dw 4  ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED
    dw 0  ; MinorOperatingSystemVersion UNUSED
    dw 0  ; MajorImageVersion UNUSED
    dw 0  ; MinorImageVersion UNUSED
    dw 4  ; MajorSubsystemVersion
    dw 0  ; MinorSubsystemVersion UNUSED
    dd 0  ; Win32VersionValue UNUSED
    dd round(hdrsize, sect_align)+round(codesize,sect_align) ; SizeOfImage
    dd round(hdrsize, filealign)  ; SizeOfHeaders
    dd 0  ; CheckSum UNUSED
    db 2  ; Subsystem (Win32 GUI)

hdrsize equ $ - $$
filesize equ $ - $$

Чтобы использовать исполняемый файл:

nasm -f bin tiny97.asm -o tiny97.exe

Для исполняемых файлов GNU/Linux ELF, см. Статью "Учебное пособие по вихревому созданию готовых исполняемых файлов ELF для Linux". TL; DR: 1340 байт, используя NASM

Примечание. Этот ответ является расширением J... комментария 3 декабря 16 в 17:31, чтобы сохранить информацию, найденную в ссылке (в случае, если она тоже мертва).


  1. Крошечный PE; Александр Сотиров; просмотрен 15/11/2017 @17:50 SAST