Основной вопрос – кто нибудь когда-нибудь видел работающий исполняемый файл размера больше 4 Гб?
У меня подозрение, что в винде существует тупое ограничение на размер EXE-файла, равное 4 Гб. Я создаю exe-файл размером 4400 Мб (ну это типа инсталлятор), но при запуске он выдает только "программа не является приложением Win32". Код, создающий экзешник, вроде как отлаженный, и создаваемые файлы меньшего размера рабочие (3 Гб exe-файл работает). В различной документации про ограничение на размер exe не нашел.
Чтобы было ясно – я не собираюсь запихнуть в адресное пространство четыре с половиной гига, собственно программа (image) занимает очень немного, то есть большая часть экзешника является оверлеем, который по идее не должен проецироваться в память загрузчиком.
Кроме ограничения, остается вариант, что для большого размера поля PE-заголовков надо заполнять как-то по особому. Может кто что-нибудь знает по этому поводу, в спецификации PE ничего хорошего не нашел.
Спасибо за внимание.
P.S. Пока писал, пришла мысль проверить с WinRar'ом, создал SFX-архив больше 4 Гб, тоже не работает, но WinRar даже не дает предупреждения, что работать не будет
1 сентября 2009 в 12:02
#28 вобщем-то это так в win2000 уже было 100%, про NT не уверен, в win98 резервировался последний гигабайт, как в 2000 со спец ключём.
31 августа 2009 в 14:05
2 Нгамдкхе Кверос:
Я рад, что вы меня поняли.
31 августа 2009 в 14:04
насколько я помню никакой специальной резервации нет (если у тебя статический бинарник).
но я могу и ошибаться или что-то за последних 5 лет изменилось…
ер не буду флудить (давно не писал под винду)
31 августа 2009 в 13:02
Василий Some, там всё хуже, винда в виртуальном адресном пространстве процесса резервирует 2-1 гиг под проецирование системных длл(по дефолту два но есть какой-то ключ который сокращает до одного), потому они и правы, тут дело не в проецировании файла, реально ты не спроецируешь даже больше трёх гигов, это особенность винды о которой я забыл, а в его случае (4г-1байт) ещё запускается. переполнение где-то ещё.
31 августа 2009 в 13:00
Александр Quyse Lert:
если у тебя 32 разрядная винда, то адресное пространство процесса – 4 гбайта, файл большего размера физически не может быть загружен (точнее спроецирован) в память.
чтобы работать с таким файлом ты должен сам (руками) писать код, который будет читать такой файл кусками.
можно написать свой загрузчик, а можно не выпендриваясь или вынести из инсталятора инсталлируемое или/и побить его на некоторое количество более мелких файлов.
31 августа 2009 в 12:01
Ровно 4гб – это на 1 больше чем влезет в unsigned int32
Если бы дело было в каких-то регионах под системные функции, то 4гб-1бтоже бы не запустилось.
31 августа 2009 в 12:00
долго не мог воткнуть в чём противоречие, ведь файл как-раз в 4г должен нормально проецироваться на 32-ух битное виртуальное адресное пространство пока не вспомнил что там есть регионы под системные функции
спасибо.
31 августа 2009 в 9:04
Винда конечно резервирует регион в адресном пространстве. Я имел в виду то, что размер этого региона не такой, чтобы в него поместился данный EXE-файл, как говорит Рихтер. Размер у него равен значению поля SizeOfImage, расположенному в одном из заголовков. Рихтер подразумевал, что SizeOfImage равно размеру файла, как это и бывает у большинства EXE-файлов. Но официальная спецификация PE/COFF этого не утверждает.
После резервирования загрузчик проецирует файл в этот регион, причем по частям, соответствующим секциям файла.
Смотрим в дамп заголовков файла (пост #12). SizeOfImage = BF000. Это значит, что этот регион будет размера менее 800 Кб. И загрузчика не волнует, что файл размером в несколько гигабайт. Просто оставшуюся часть он проецировать не будет, так как она не относится к никаким секциям. Читайте Криса Касперски или Мэтта Питрека.
Именно вот это похоже на то, что я наблюдаю. Потому что файл размером почти в 4 Гб запускается.
30 августа 2009 в 23:01
а если он (просто предположение в порядке бреда) говорил о том о чём он говорил, а именно что винда, видя необходимость создания процесса, создаёт структуру процесса, создавая процесс для экзешника, занимается такой процедурой, как резервирование региона в виртуальном адресном пространстве процесса на который проецирует экзе файл? во всяком случае это очень похоже на то что вы наблюдаете фактически.
30 августа 2009 в 23:00
Если вы об этом: "Резервирует регион адресного пространства — такой, чтобы в него поместился данный ЕХЕ-файл", то это высказывание неверно. Рихтер по-видимому говорил о "нормальных" файлах без оверлеев. Больше я ничего там не вижу. Если не это, то что конкретно я по-вашему не понял?
30 августа 2009 в 22:04
пост адекватный, просто в трёх словах вы не поняли а подробно гуглить о проецировании файлов предлагалось,
см и медитируй также на #6 .4.
30 августа 2009 в 22:00
Мда :-\
Мягко говоря, ваше высказывание несколько неадекватно.
Советую обратить внимание на пост #1, уже в котором я употребил слово проецируется, пост #8, где я сказал, что даже больше 2 гигов не спроецировать, не то что 4-х, и опять пост #1, где я сказал, что бОльшая часть файла проецироваться не будет, поэтому все вполне могло бы работать.
30 августа 2009 в 21:02
Александр Quyse Lert, тебе разве сказали что файл считывается в оперативную память? нет! он туда ПРОЕЦИРУЕТСЯ, а виртуальная память в обычной винде 32-х битная, так что извиняй, но больше 4 гиг никак не спроецировать,
механизм проекции гугли. по сути это как своп, только файл не считываясь в память оказывается как бы засвопен в свой собственный файл без какого-то чтения. (сам знаю что ахинея но я полному ламеру чисто на пальцах пытался объяснить.)
30 августа 2009 в 10:03
А у меня не выдает, версия наверно старая…
Ну значит совсем все понятно. Спасибо )
30 августа 2009 в 0:05
> Остается еще вопрос с Rar'ом )
Сегодня проверил. После окончания запаковки WinRar выдает ошибку "Исполняемый файл в Windows не может превышать 4 Гб"
29 августа 2009 в 12:03
Да, может и так.
Может как-нить посмотрю, щас я не по этой части )
29 августа 2009 в 12:00
думаю все гораздо проще… загрузчик оперирует с 32-м uint значением длины исполяемого файла, после переполнения остается младшый кусочек от длины, где то проверка на соотвествие образа на диске, который скорей всего считывается GetFileSize как положено со старшеной частью, и того что посчитал загрузчик – несоответсвие длин и вылет! Хотя если там оно действительно так – то глупо как то. А вообще взял бы IDA и посмотрел как реализован загрузчик.
29 августа 2009 в 10:04
Проверил с размерами. В общем, файл размером ровно 4 Гб не запускается.
Файл размером 4 гига минус 1 байт успешно запускается.
Думаю, вопрос решен… По сути, загрузчику не должно быть никакой разницы, 4 Гб или на байт меньше, так как если бы он что-нибудь делал с ними, то этот байт все равно бы прибавился из-за выравнивания. Если загрузчик боится, что файл может содержать секции дальше первых 4 гигабайт, то данное ограничение ничем ему помочь не может, так как при нем все равно можно сделать такие секции, и нужны дополнительные проверки.
В общем, ограничение выглядит довольно бессмыссленным.
Остается еще вопрос с Rar'ом )
29 августа 2009 в 10:01
Немного подсократил, некоторые поля в заголовках выкинул.
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
29 августа 2009 в 3:01
Результат dumpbin в студию.
28 августа 2009 в 23:02
Этого я не проверял… я 4 Гб как границу определил приближенно, только по тем цифрам, которые в первом посте ) Может завтра проверю.
А система – ну возможно тупит, это как бы и выясняю ) тогда все понятно. Единственно странно, что WinRar как бы не колеблясь создает неработающий файл, и ничего не предупреждает. Помнится, где-то читал, что в какой-то новой его версии убрано ограничение на размер SFX архивов 4 Гб. Что толку тогда с этого новшества.
Правда, может ограничение появилось только в висте (забыл сказать про нее), а раньше не было.
28 августа 2009 в 23:01
Может просто система тупит от таких размерах на этапах загрузки и не может понять, чего куда и сколько грузить. Если размер ровно 4гб или на байт меньше, то работает или нет?
28 августа 2009 в 23:00
> Ну, иногда удобнее чтобы все было в одном файле, к примеру, когда скачивают файл с инета, одной ссылкой
Все это сливать zip'om (без сжатия!) в один файл
А вот, что говорит по этому поводу Рихтер
==================
При вызове из потока функции CreateProcess система действует так:
1. Отыскивает ЕХЕ-файл, указанный при вызове CreateProcess. Если файл не найден, новый процесс не создастся, а функция возвращает FALSE.
2. Создает новый объект ядра «процесс»
3. Создает адресное пространство нового процесса
4. Резервирует регион адресного пространства — такой, чтобы в него поместил ся данный ЕХЕ-файл Желательное расположение этого региона указывается внут ри самого ЕХЕ-файла По умолчанию базовый адрес ЕХЕ-файла — 0×00400000 (в 64-разрядном приложении под управлением 64-разрядпой Windows 2000 этот адрес может быть другим). При создании исполняемого файла приложе ния базовый адрес может быть изменен через параметр компоновщика /BASE.
5. Отмечает, что физическая память, связанная с зарезервированным регионом, — ЕХЕ-файл на диске, а нс страничный файл.
Спроецировав ЕХЕ-файл на адресное пространство процесса, система обращает ся к разделу ЕХЕ-файла со списком DLL, содержащих необходимые программе функции. После этого система, вызывая LoadLibrary, поочередно загружает указанные (а при необходимости и дополнительные) DLL-модули. Всякий раз, когда для загрузки DLL вызывается LoadLibrary, система выполняет действия, аналогичные описанным выще в пп. 4 и 5:
==================
28 августа 2009 в 23:00
2 Евгений сферический в вакууме Тихонов:
Про удобство. Да я все понимаю ) Я не собираюсь выкладывать здоровый файл в инет, чтобы кто-то его качал. Есть достаточно конкретная задача, и я утверждаю, что в моих обстоятествах один exe огромного размера удобнее других вариантов.
Огромный exe может запускаться долго, если он с сертификатом. Тогда естественно перед запуском винда долго считает его хеш, чтобы проверить цифровую подпись. В моем случае подписей не будет )
В оперативку экзешник прямиком не уходит, если он правильно сделан. То есть в адресное пространство проецируются только те части файла, которые относятся к секциям, а остаток файла (оверлей) не загружается, его будет грузить сам экзешник из себя с помощью обычного ввода-вывода. Проблема в том, что до него управление не доходит совсем, система отказывается запускать файл.
28 августа 2009 в 23:00
2 Антон Щиров:
Я в курсе, что говорил Рихтер )
То что файл не грузится в память целиком, легко доказать тем, что 3 Гб экзешник запускается и работает, а пользовательская часть адресного пространства составляет, как известно 2 Гб. И работает все очень быстро.
И все же, видел кто-нибудь файл или нет?!
28 августа 2009 в 22:05
Ога, удобнее.. Я ***дь полтора часа ждал, пока е**ная контра сурс установится из такого вот огромного EXE, а если его антивирусник начнёт шерстить? Это ш пипец… К слово о контре – я со стима за 15 минут выкачиваю и она работает, а двухтонный экзешник полтора часа ставился, как я уже сказал.
Экзешник же прямиком в оперативку уходит, так? А если система 32х битная, то наверное поэтому больше 4х гигов и не получается, если пейджфайл отключен и прочее
28 августа 2009 в 22:05
Может на 64битной системе будет работать… особенно если памяти больше 4гб будет
Для скачивания все можно в архив помещать, zip винда давно поддерживать научилась.
28 августа 2009 в 22:04
Ну, иногда удобнее чтобы все было в одном файле, к примеру, когда скачивают файл с инета, одной ссылкой. Вопрос ведь не об этом. Понятно, что если не получится, сделаю как цивилизованные люди делают )
28 августа 2009 в 22:03
А чо за неведомая ***ная **ня на 4 гига? Не проще ли как все цивилизованные люди делают – инсталятор на 500 килобайт, а файлы распаковываемые на 4-5 гигов?