Комментарии 18
Разместите вторую gif-ку покадрово, пожалуйста.
+6
Эх. Помню я как-то я журнале ZX-формат соревновались у кого меньше байт будет для плавной гасилки экрана. Вот были времена, когда программу в 21 байт укладывали.
+1
А где текст самой программы? Наверняка, общими усилиями сможем сделать меньше
0
Ещё не всё прочитал, но навскидку:
Существующие примеры программ размером 268 байт не содержат ни одной секции, и фактически, целиком помещаются внутри заголовка PE, для загрузки которого Windows выделяет одну страницу памяти (4КБ).Для загрузки заголовка выделяется
ALIGN_UP(SizeOfHeaders, max(SectionAlignment, PAGE_SIZE))
. Так что можно поставить SizeOfHeaders больше страницы и без секций обойтись.На WinXP моя программа, к сожалению, не работает: та отказывается загружать программы, у которых в каталоге менее 0xD записей.Там просто часть кода поддержки совместимости смотрит на Directories[DEBUG].Size, не проверяя, что DEBUG действительно есть. Если выставить соответствующий dword в нуль, всё будет работать.
+1
Минуточку. На XP SP3 оно вполне работает. (DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size у вас хоть и не 0, но 3, но пока оно меньше 0x1C, это нормально.) При отсутствии IMAGE_DIRECTORY_ENTRY_IAT = 0xC в XP есть засада, что таблица импорта должна быть в какой-нибудь секции, не в заголовке, но это проблема, только если делать программу целиком в заголовке без секций.
0
Как-то странно оно работает. Один и тот же файл запускаю — то запускается нормально, то выскакивает «Application Error: The application failed to initialize properly (0xc000007b). Click on OK to terminate the application.»
Поди, опять что-нибудь связанное с файловым кэшем.
(Всё равно спасибо за подсказку! Исправил пост, чтобы указать, что на WinXP программа иногда работает.)
Поди, опять что-нибудь связанное с файловым кэшем.
(Всё равно спасибо за подсказку! Исправил пост, чтобы указать, что на WinXP программа иногда работает.)
0
У меня на виртуалке запускается совершенно стабильно. Ошибка явно от юзермодного загрузчика, ему на файловый кэш должно быть ну совсем пофиг.
WinDbg на машине есть?
WinDbg на машине есть?
0
WinDbg есть, но не помогает — ошибка вываливается ещё до
Не исключено, что это шалит стоящий на машине антивирус (Symantec), но с ним я сделать ничего не могу — машина не моя, я только запустил программу.
DbgBreakPoint
внутри LdrpInitializeProcess
:Не исключено, что это шалит стоящий на машине антивирус (Symantec), но с ним я сделать ничего не могу — машина не моя, я только запустил программу.
0
У WinDbg в настройках можно включить Debug -> Event filters -> Create process -> enabled, перезагрузить процесс, сделать bu ntdll!LdrInitializeThunk, g, и отлаживать совсем с начала.
Но у меня появилась мысль, что может быть не так.
Но у меня появилась мысль, что может быть не так.
часть таблицы импорта (последние 0x16 её байт нулевые, и в файле не хранятся)Если честно добить файл нулями, проблема будет воспроизводиться?
0
Окей, исключение прилетает отсюда:
Выше по стеку вызовов — только
Да.
ntdll!_LdrpInitialize+0x178: 7c84a446 57 push edi 7c84a447 e85e530100 call ntdll!LdrpInitializationFailure (7c85f7aa) 7c84a44c 57 push edi 7c84a44d e890e0fdff call ntdll!RtlRaiseStatus (7c8284e2) 7c84a452 cc int 3
Выше по стеку вызовов — только
ntdll!KiUserApcDispatcher+0x25
Если честно добить файл нулями, проблема будет воспроизводиться?
Да.
0
Естественно. LdrpInitializeProcess возвращает 0xC000007B, а уже верхний уровень бросает исключение.
Тупой способ выяснить, откуда оно — после останова на LdrInitializeThunk выполнить команду
подождать, посмотреть, где остановилось, и посмотреть команды перед этим — чтобы понять, почему управление дошло до этой ветки кода.
Более интеллектуальный — настроить символы
(папку c:\symcache потом можно почистить), поставить
Тупой способ выяснить, откуда оно — после останова на LdrInitializeThunk выполнить команду
r;t;z(eax!=c000007b)
подождать, посмотреть, где остановилось, и посмотреть команды перед этим — чтобы понять, почему управление дошло до этой ветки кода.
Более интеллектуальный — настроить символы
.sympath SRV*c:\symcache*http://msdl.microsoft.com/download/symbols
.reload
(папку c:\symcache потом можно почистить), поставить
bp ntdll!LdrpSnapIAT
, дождаться второго срабатывания (первый вызов — для kernel32 -> ntdll) и запустить команду выше уже с этого момента.0
При отсутствии IMAGE_DIRECTORY_ENTRY_IAT = 0xC в XP есть засада, что таблица импорта должна быть в какой-нибудь секции, не в заголовке, но это проблема, только если делать программу целиком в заголовке без секций.
Возвращаясь к старой теме: у меня на Windows 10, если нет секций и загружается только заголовок, то импорты не резолвятся. Получается, что программу без секций вообще нет смысла делать: десять лишних IMAGE_DATA_DIRECTORY занимают намного больше места, чем одна IMAGE_SECTION_HEADER.
0
Для загрузки заголовка выделяется ALIGN_UP(SizeOfHeaders, max(SectionAlignment, PAGE_SIZE)). Так что можно поставить SizeOfHeaders больше страницы и без секций обойтись.
А можно пример? А то у меня с
SizeOfHeaders
больше 0x1000 прога напрочь отказывается загружаться.0
На XP и семёрке, казалось бы, никаких проблем: yadi.sk/d/4yHs4lWioPtmW
В восьмёрке добавили несколько странную проверку, что EntryPoint должна быть либо 0, либо не меньше SizeOfHeaders, причём 0 для exe-шника — валидное значение (MZ = dec ebp, pop edx), так что можно так: yadi.sk/d/jY0Tn_lSoPvGc
Но вообще формула выше — таки только для ветки с SectionAlignment >= PAGE_SIZE, на ветке с SectionAlignment < PAGE_SIZE весь файл просто маппится одним куском, так что можно просто сделать ImageSize побольше и даже не менять SizeOfHeaders: yadi.sk/d/c_Oc3oyooPwS8
В восьмёрке добавили несколько странную проверку, что EntryPoint должна быть либо 0, либо не меньше SizeOfHeaders, причём 0 для exe-шника — валидное значение (MZ = dec ebp, pop edx), так что можно так: yadi.sk/d/jY0Tn_lSoPvGc
Но вообще формула выше — таки только для ветки с SectionAlignment >= PAGE_SIZE, на ветке с SectionAlignment < PAGE_SIZE весь файл просто маппится одним куском, так что можно просто сделать ImageSize побольше и даже не менять SizeOfHeaders: yadi.sk/d/c_Oc3oyooPwS8
0
если хотя бы одна секция объявлена, то FileAlignment должен быть не меньше 0x200, а SectionAlignment должен быть 0x1000
Строго говоря, можно. Например, если размеры всех секций кратны 0x1000, то проблем не будет и при SectionAlignment, меньшем размера страницы. (Вообще-то, соответствующий код в подсистеме WOW64 писался не под энтузиастов минимизации вроде нас с вами, а ровно под такую ситуацию. Конкретно — эмуляция x86 на Itanium, где винда использует размер страницы 0x2000.) Но не очень полезно — если честно записывать все дополняющие нули в файл, то о минимизации размера можно забыть, а если не писать, то винда от такой наглости может даже в BSOD выпасть. (ЕМНИП починили где-то между XP SP1 и SP2. Это к вопросу о винтажности. Хотя, конечно, истинно винтажная система — Windows 95.)
+2
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
«Digital Rain» для Windows в 314 байтах