singlepost

Ограничение размера для исполняемых файлов << На главную или назад  

Основной вопрос – кто нибудь когда-нибудь видел работающий исполняемый файл размера больше 4 Гб?

У меня подозрение, что в винде существует тупое ограничение на размер EXE-файла, равное 4 Гб. Я создаю exe-файл размером 4400 Мб (ну это типа инсталлятор), но при запуске он выдает только "программа не является приложением Win32". Код, создающий экзешник, вроде как отлаженный, и создаваемые файлы меньшего размера рабочие (3 Гб exe-файл работает). В различной документации про ограничение на размер exe не нашел.
Чтобы было ясно – я не собираюсь запихнуть в адресное пространство четыре с половиной гига, собственно программа (image) занимает очень немного, то есть большая часть экзешника является оверлеем, который по идее не должен проецироваться в память загрузчиком.

Кроме ограничения, остается вариант, что для большого размера поля PE-заголовков надо заполнять как-то по особому. Может кто что-нибудь знает по этому поводу, в спецификации PE ничего хорошего не нашел.
Спасибо за внимание.

P.S. Пока писал, пришла мысль проверить с WinRar'ом, создал SFX-архив больше 4 Гб, тоже не работает, но WinRar даже не дает предупреждения, что работать не будет :)

53 ответов в теме “Ограничение размера для исполняемых файлов”

  1. 29
    Нгамдкхе Кверос ответил:

    #28 вобщем-то это так в win2000 уже было 100%, про NT не уверен, в win98 резервировался последний гигабайт, как в 2000 со спец ключём.

  2. 28
    Александр Lert ответил:

    2 Нгамдкхе Кверос:
    Я рад, что вы меня поняли.

  3. 27
    Василий Some ответил:

    насколько я помню никакой специальной резервации нет (если у тебя статический бинарник).
    но я могу и ошибаться или что-то за последних 5 лет изменилось…
    ер не буду флудить (давно не писал под винду)

  4. 26
    Нгамдкхе Кверос ответил:

    Василий Some, там всё хуже, винда в виртуальном адресном пространстве процесса резервирует 2-1 гиг под проецирование системных длл(по дефолту два но есть какой-то ключ который сокращает до одного), потому они и правы, тут дело не в проецировании файла, реально ты не спроецируешь даже больше трёх гигов, это особенность винды о которой я забыл, а в его случае (4г-1байт) ещё запускается. переполнение где-то ещё.

  5. 25
    Василий Some ответил:

    Александр Quyse Lert:
    если у тебя 32 разрядная винда, то адресное пространство процесса – 4 гбайта, файл большего размера физически не может быть загружен (точнее спроецирован) в память.
    чтобы работать с таким файлом ты должен сам (руками) писать код, который будет читать такой файл кусками.
    можно написать свой загрузчик, а можно не выпендриваясь или вынести из инсталятора инсталлируемое или/и побить его на некоторое количество более мелких файлов.

  6. 24
    Евгений Тюкавкин ответил:

    Ровно 4гб – это на 1 больше чем влезет в unsigned int32
    Если бы дело было в каких-то регионах под системные функции, то 4гб-1бтоже бы не запустилось.

  7. 23
    Нгамдкхе Кверос ответил:

    долго не мог воткнуть в чём противоречие, ведь файл как-раз в 4г должен нормально проецироваться на 32-ух битное виртуальное адресное пространство пока не вспомнил что там есть регионы под системные функции :-)
    спасибо.

  8. 22
    Александр Lert ответил:

    Винда конечно резервирует регион в адресном пространстве. Я имел в виду то, что размер этого региона не такой, чтобы в него поместился данный EXE-файл, как говорит Рихтер. Размер у него равен значению поля SizeOfImage, расположенному в одном из заголовков. Рихтер подразумевал, что SizeOfImage равно размеру файла, как это и бывает у большинства EXE-файлов. Но официальная спецификация PE/COFF этого не утверждает.
    После резервирования загрузчик проецирует файл в этот регион, причем по частям, соответствующим секциям файла.
    Смотрим в дамп заголовков файла (пост #12). SizeOfImage = BF000. Это значит, что этот регион будет размера менее 800 Кб. И загрузчика не волнует, что файл размером в несколько гигабайт. Просто оставшуюся часть он проецировать не будет, так как она не относится к никаким секциям. Читайте Криса Касперски или Мэтта Питрека.
    Именно вот это похоже на то, что я наблюдаю. Потому что файл размером почти в 4 Гб запускается.

  9. 21
    Нгамдкхе Кверос ответил:

    а если он (просто предположение в порядке бреда) говорил о том о чём он говорил, а именно что винда, видя необходимость создания процесса, создаёт структуру процесса, создавая процесс для экзешника, занимается такой процедурой, как резервирование региона в виртуальном адресном пространстве процесса на который проецирует экзе файл? во всяком случае это очень похоже на то что вы наблюдаете фактически.

  10. 20
    Александр Lert ответил:

    Если вы об этом: "Резервирует регион адресного пространства — такой, чтобы в него поместился данный ЕХЕ-файл", то это высказывание неверно. Рихтер по-видимому говорил о "нормальных" файлах без оверлеев. Больше я ничего там не вижу. Если не это, то что конкретно я по-вашему не понял?

  11. 19
    Нгамдкхе Кверос ответил:

    пост адекватный, просто в трёх словах вы не поняли а подробно гуглить о проецировании файлов предлагалось,

    см и медитируй также на #6 .4.

  12. 18
    Александр Lert ответил:

    Мда :-\
    Мягко говоря, ваше высказывание несколько неадекватно.
    Советую обратить внимание на пост #1, уже в котором я употребил слово проецируется, пост #8, где я сказал, что даже больше 2 гигов не спроецировать, не то что 4-х, и опять пост #1, где я сказал, что бОльшая часть файла проецироваться не будет, поэтому все вполне могло бы работать.

  13. 17
    Нгамдкхе Кверос ответил:

    Александр Quyse Lert, тебе разве сказали что файл считывается в оперативную память? нет! он туда ПРОЕЦИРУЕТСЯ, а виртуальная память в обычной винде 32-х битная, так что извиняй, но больше 4 гиг никак не спроецировать,

    механизм проекции гугли. по сути это как своп, только файл не считываясь в память оказывается как бы засвопен в свой собственный файл без какого-то чтения. (сам знаю что ахинея но я полному ламеру чисто на пальцах пытался объяснить.)

  14. 16
    Александр Lert ответил:

    А у меня не выдает, версия наверно старая…
    Ну значит совсем все понятно. Спасибо )

  15. 15
    Антон Щиров ответил:

    > Остается еще вопрос с Rar'ом )
    Сегодня проверил. После окончания запаковки WinRar выдает ошибку "Исполняемый файл в Windows не может превышать 4 Гб"

  16. 14
    Александр Lert ответил:

    Да, может и так.
    Может как-нить посмотрю, щас я не по этой части )

  17. 13
    Cyber Max ответил:

    думаю все гораздо проще… загрузчик оперирует с 32-м uint значением длины исполяемого файла, после переполнения остается младшый кусочек от длины, где то проверка на соотвествие образа на диске, который скорей всего считывается GetFileSize как положено со старшеной частью, и того что посчитал загрузчик – несоответсвие длин и вылет! Хотя если там оно действительно так – то глупо как то. А вообще взял бы IDA и посмотрел как реализован загрузчик.

  18. 12
    Александр Lert ответил:

    Проверил с размерами. В общем, файл размером ровно 4 Гб не запускается.
    Файл размером 4 гига минус 1 байт успешно запускается.
    Думаю, вопрос решен… По сути, загрузчику не должно быть никакой разницы, 4 Гб или на байт меньше, так как если бы он что-нибудь делал с ними, то этот байт все равно бы прибавился из-за выравнивания. Если загрузчик боится, что файл может содержать секции дальше первых 4 гигабайт, то данное ограничение ничем ему помочь не может, так как при нем все равно можно сделать такие секции, и нужны дополнительные проверки.
    В общем, ограничение выглядит довольно бессмыссленным.
    Остается еще вопрос с Rar'ом )

  19. 11
    Александр Lert ответил:

    Немного подсократил, некоторые поля в заголовках выкинул.

    Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
    Copyright (C) Microsoft Corporation.All rights reserved.
    Dump of file ***\Installer_big.exe
    PE signature found
    File Type: EXECUTABLE IMAGE

    FILE HEADER VALUES
    14C machine (x86)
    5 number of sections
    4A97E917 time date stamp Fri Aug 28 20:26:31 2009
    0 file pointer to symbol table
    0 number of symbols
    E0 size of optional header
    102 characteristics
    Executable
    32 bit word machine

    OPTIONAL HEADER VALUES
    3CC00 size of code
    3EC00 size of initialized data
    0 size of uninitialized data
    35CC0 entry point (00435CC0)
    1000 base of code
    3E000 base of data
    400000 image base (00400000 to 004BEFFF)
    1000 section alignment
    200 file alignment
    BF000 size of image
    400 size of headers
    83DFB checksum
    2 subsystem (Windows GUI)

    SECTION HEADER #1
    .text name
    3CA86 virtual size
    1000 virtual address (00401000 to 0043DA85)
    3CC00 size of raw data
    400 file pointer to raw data (00000400 to 0003CFFF)
    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

    SECTION HEADER #2
    .rdata name
    13BD2 virtual size
    3E000 virtual address (0043E000 to 00451BD1)
    13C00 size of raw data
    3D000 file pointer to raw data (0003D000 to 00050BFF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    40000040 flags
    Initialized Data
    Read Only

    Debug Directories
    Time Type SizeRVAPointer
    ——– —— ——– ——– ——–
    4A97E917 cv4E 00049BD8 48BD8 Format: RSDS, {6EF0058F-00FE-41B9-90F5-4B00366856BD}, 33, ***\Installer.pdb

    SECTION HEADER #3
    .data name
    415F0 virtual size
    52000 virtual address (00452000 to 004935EF)
    A00 size of raw data
    50C00 file pointer to raw data (00050C00 to 000515FF)
    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

    SECTION HEADER #4
    .rsrc name
    26B8C virtual size
    94000 virtual address (00494000 to 004BAB8B)
    26C00 size of raw data
    51600 file pointer to raw data (00051600 to 000781FF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    40000040 flags
    Initialized Data
    Read Only

    SECTION HEADER #5
    .reloc name
    395E virtual size
    BB000 virtual address (004BB000 to 004BE95D)
    3A00 size of raw data
    78200 file pointer to raw data (00078200 to 0007BBFF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    42000040 flags
    Initialized Data
    Discardable
    Read Only

    Summary
    42000 .data
    14000 .rdata
    4000 .reloc
    27000 .rsrc
    3D000 .text

  20. 10
    Константин Смотритель ответил:

    Результат dumpbin в студию.

  21. 9
    Александр Lert ответил:

    Этого я не проверял… я 4 Гб как границу определил приближенно, только по тем цифрам, которые в первом посте ) Может завтра проверю.
    А система – ну возможно тупит, это как бы и выясняю ) тогда все понятно. Единственно странно, что WinRar как бы не колеблясь создает неработающий файл, и ничего не предупреждает. Помнится, где-то читал, что в какой-то новой его версии убрано ограничение на размер SFX архивов 4 Гб. Что толку тогда с этого новшества.
    Правда, может ограничение появилось только в висте (забыл сказать про нее), а раньше не было.

  22. 8
    Евгений Тюкавкин ответил:

    Может просто система тупит от таких размерах на этапах загрузки и не может понять, чего куда и сколько грузить. Если размер ровно 4гб или на байт меньше, то работает или нет?

  23. 7
    Антон Щиров ответил:

    > Ну, иногда удобнее чтобы все было в одном файле, к примеру, когда скачивают файл с инета, одной ссылкой
    Все это сливать zip'om (без сжатия!) в один файл

    А вот, что говорит по этому поводу Рихтер
    ==================
    При вызове из потока функции CreateProcess система действует так:
    1. Отыскивает ЕХЕ-файл, указанный при вызове CreateProcess. Если файл не найден, новый процесс не создастся, а функция возвращает FALSE.
    2. Создает новый объект ядра «процесс»
    3. Создает адресное пространство нового процесса
    4. Резервирует регион адресного пространства — такой, чтобы в него поместил ся данный ЕХЕ-файл Желательное расположение этого региона указывается внут ри самого ЕХЕ-файла По умолчанию базовый адрес ЕХЕ-файла — 0×00400000 (в 64-разрядном приложении под управлением 64-разрядпой Windows 2000 этот адрес может быть другим). При создании исполняемого файла приложе ния базовый адрес может быть изменен через параметр компоновщика /BASE.
    5. Отмечает, что физическая память, связанная с зарезервированным регионом, — ЕХЕ-файл на диске, а нс страничный файл.

    Спроецировав ЕХЕ-файл на адресное пространство процесса, система обращает ся к разделу ЕХЕ-файла со списком DLL, содержащих необходимые программе функции. После этого система, вызывая LoadLibrary, поочередно загружает указанные (а при необходимости и дополнительные) DLL-модули. Всякий раз, когда для загрузки DLL вызывается LoadLibrary, система выполняет действия, аналогичные описанным выще в пп. 4 и 5:
    ==================

  24. 6
    Александр Lert ответил:

    2 Евгений сферический в вакууме Тихонов:
    Про удобство. Да я все понимаю ) Я не собираюсь выкладывать здоровый файл в инет, чтобы кто-то его качал. Есть достаточно конкретная задача, и я утверждаю, что в моих обстоятествах один exe огромного размера удобнее других вариантов.
    Огромный exe может запускаться долго, если он с сертификатом. Тогда естественно перед запуском винда долго считает его хеш, чтобы проверить цифровую подпись. В моем случае подписей не будет )

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

  25. 5
    Александр Lert ответил:

    2 Антон Щиров:
    Я в курсе, что говорил Рихтер )
    То что файл не грузится в память целиком, легко доказать тем, что 3 Гб экзешник запускается и работает, а пользовательская часть адресного пространства составляет, как известно 2 Гб. И работает все очень быстро.

    И все же, видел кто-нибудь файл или нет?! :)

  26. 4
    Евгений Тихонов ответил:

    Ога, удобнее.. Я ***дь полтора часа ждал, пока е**ная контра сурс установится из такого вот огромного EXE, а если его антивирусник начнёт шерстить? Это ш пипец… К слово о контре – я со стима за 15 минут выкачиваю и она работает, а двухтонный экзешник полтора часа ставился, как я уже сказал.

    Экзешник же прямиком в оперативку уходит, так? А если система 32х битная, то наверное поэтому больше 4х гигов и не получается, если пейджфайл отключен и прочее

  27. 3
    Евгений Тюкавкин ответил:

    Может на 64битной системе будет работать… особенно если памяти больше 4гб будет :)
    Для скачивания все можно в архив помещать, zip винда давно поддерживать научилась.

  28. 2
    Александр Lert ответил:

    Ну, иногда удобнее чтобы все было в одном файле, к примеру, когда скачивают файл с инета, одной ссылкой. Вопрос ведь не об этом. Понятно, что если не получится, сделаю как цивилизованные люди делают )

  29. 1
    Евгений Тихонов ответил:

    А чо за неведомая ***ная **ня на 4 гига? Не проще ли как все цивилизованные люди делают – инсталятор на 500 килобайт, а файлы распаковываемые на 4-5 гигов?

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.