Здравствуйте, RealSQUALL, Вы писали:
RSQ>Вопрос. Хочу сжимать UPX'ом (к нему больше доверия). Как это можно сделать? (скажу, что такой-же текст, собраный MS VC++ 4 жмётся "на ура").
Указывай --force. Судя по документации это не ошибка, а предупреждение, что при упаковке некоторые метаданные PE могут ыть потеряны. Собственно у меня проблем при использовании --force никогда не возникало.
Если не шаманить с объединением секций, получаем exe 2Kb.
RSQ>upx124w\upx.exe -9 program.exe RSQ>... upx: program.exe: CantPackException: file is possibly packed/protected (try --force) ...
RSQ>upx124w\upx.exe -9f program.exe RSQ>.. upx: program.exe: NotCompressibleException ... RSQ>
RSQ>В то же время ASPack 2.12 со свистом превращает его в 17.5Кб execuable.
Есть ещё куча других пакеров — FSG, PeX, ...
RSQ>Вопрос. Хочу сжимать UPX'ом (к нему больше доверия).
Лучше не использовать пакеры. Некоторые файерволлы начинают ругаться при скачивании таких файлов .
RSQ>Как это можно сделать? (скажу, что такой-же текст, собраный MS VC++ 4 жмётся "на ура").
Обнулить поле LOAD CONFIGURATION Table в IMAGE_OPTIONAL_HEADER (найти его можно с помощью PEview) или использовать способ, предложенный adontz.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Собрал. Получил 10Кб — WoW! И не думал, что студия на такое способна.
#pragma comment(linker, "/subsystem:windows")
Тут ты указываешь компилятору, что приложению не надо консоли (отсюда отпадает необходимость в 3м параметре WinMain()), т.к. оно само создаст всё для себя необходимое. И даёшь студии (или ОС) возможность не ломать себе голову и не искать WinMain(), а сразу работать таким образом.
#pragma comment(linker, "/entry:myMain")
Эта директива говорит, что точкой входа в программу теперь будет не функция WinMain(), а функция myMain(). Тоесть ОС теперь будет вызывать не WinMain, а myMain (куда только денется три параметра — )
BOOL WINAPI myMain()
Таким образом HINSTANCE hInstance оказывается недоступным, и поэтому ты делаешь
HINSTANCE hInstance = (HINSTANCE)0x400000;
Вот тут у меня ещё один вопрос. Как я думал, при запуске приложения ОС создаёт ему уникальный номер, который будет "номером процесса" и передаёт его через WinMain. Ты же, здесь, отбрасываешь этот вариант и сам указываешь номер процесса. Тоесть приложение запустилось, ему присвоился номер (??? ???) и теперь ты говоришь "нет, предидущий номер нафик — использовать мой".
Параметр int nCmdShow тоже можно не необходим (всё равно либо 1 либо, реже, 7) — ты использовал SW_SHOWDEFAULT.
Ну а теперь я не понимаю — куда сократилось 16Кб? Если только и всего — было указано, что приложению не нужно консоли и немного подрихтована WinMain().
Re[3]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, RealSQUALL, Вы писали:
RSQ>Собрал. Получил 10Кб — WoW! И не думал, что студия на такое способна.
Дело в том, что ты только что избавился от CRT. У глобальных переменных больше не вызываются конструкторы, Си+ исключения не работают. Вобщем проблем больше, чем пользы.
Здравствуйте, RealSQUALL, Вы писали:
RSQ>Собрал. Получил 10Кб — WoW!
У меня получилось 2Kb.
Компилировал так:
cl u.cpp kernel32.lib user32.lib gdi32.lib
Попробуйте добавить ключ линкера /opt:nowin98
cl u.cpp kernel32.lib user32.lib gdi32.lib /link /opt:nowin98
RSQ>И не думал, что студия на такое способна.
Можно и полтора килобайта, если объеденить секции PE файла:
RSQ>Тут ты указываешь компилятору, что приложению не надо консоли (отсюда отпадает необходимость в 3м параметре WinMain()), т.к. оно само создаст всё для себя необходимое. И даёшь студии (или ОС) возможность не ломать себе голову и не искать WinMain(), а сразу работать таким образом.
Единственная цель прагмы — установить в заголовке PE файла флаг IMAGE_SUBSYSTEM_WINDOWS_GUI. Если прагму не указать, то линкер не будет знать, какой флаг нужно устанавливать. (Есть ещё IMAGE_SUBSYSTEM_WINDOWS_CUI — консольное приложение, и другие).
RSQ>
RSQ>#pragma comment(linker, "/entry:myMain")
RSQ>Эта директива говорит, что точкой входа в программу теперь будет не функция WinMain(), а функция myMain(). Тоесть ОС теперь будет вызывать не WinMain, а myMain (куда только денется три параметра — )
Почти так. Только в случае с WinMain точкой входа будет функция из CRT, которая передаёт параметры в WinMain. Поскольку точка входа переопределена, то параметров нет, и если они нужны, их нужно получать самостоятельно.
RSQ>
RSQ>BOOL WINAPI myMain()
RSQ>Таким образом HINSTANCE hInstance оказывается недоступным, и поэтому ты делаешь RSQ>
RSQ>HINSTANCE hInstance = (HINSTANCE)0x400000;
Верно.
RSQ>Вот тут у меня ещё один вопрос. Как я думал, при запуске приложения ОС создаёт ему уникальный номер, который будет "номером процесса" и передаёт его через WinMain. Ты же, здесь, отбрасываешь этот вариант и сам указываешь номер процесса. Тоесть приложение запустилось, ему присвоился номер (??? ???) и теперь ты говоришь "нет, предидущий номер нафик — использовать мой".
hInstance — это анахронизм времён windows 3.1. В 32х разрядных ОС hInstance равен адресу загрузки файла. Для exe он по умолчанию равен 0x400000 (можно изменить указав линкеру ключ /BASE:xxxxx)
RSQ>Параметр int nCmdShow тоже можно не необходим (всё равно либо 1 либо, реже, 7) — ты использовал SW_SHOWDEFAULT.
RSQ>Ну а теперь я не понимаю — куда сократилось 16Кб? Если только и всего — было указано, что приложению не нужно консоли и немного подрихтована WinMain().
Исчезла куча ненужного для данного приложения кода из библиотеки libc.lib.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, gear nuke, Вы писали:
GN>hInstance — это анахронизм времён windows 3.1. В 32х разрядных ОС hInstance равен адресу загрузки файла. Для exe он по умолчанию равен 0x400000 (можно изменить указав линкеру ключ /BASE:xxxxx)
Это нигде не документированно. Надо пользоваться GetModuleHandle(NULL) для EXE и первым параметром DllMain для DLL
Кроме того менять имя стандартной точки входа не объязательно. По умолчанию это
Здравствуйте, adontz, Вы писали:
RSQ>>Собрал. Получил 10Кб — WoW! И не думал, что студия на такое способна.
A>Дело в том, что ты только что избавился от CRT. У глобальных переменных больше не вызываются конструкторы, Си+ исключения не работают. Вобщем проблем больше, чем пользы.
Это всё верно, но для данного случая не важно . Кроме того, __try __except всё равно будет работать, что в некоторых случаях достаточно. Форум же по WinAPI, а не С++ .
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, RealSQUALL, Вы писали:
RSQ>Тогда получается, что освобождая ОС от поиска start point'a в программе экономится 16Кб исп. файла
OS и так ничего не ищет — адрес точки входа указан в заголовке EXE файла. Просто в обычной программе WinMain это не entry point. Вызывается _WinMainCRTStartUp которая подготавливает много чего и уже потом вызывает WinMain.
Здравствуйте, gear nuke, Вы писали:
GN>Это всё верно, но для данного случая не важно . Кроме того, __try __except всё равно будет работать, что в некоторых случаях достаточно. Форум же по WinAPI, а не С++ .
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, gear nuke, Вы писали:
GN>>hInstance — это анахронизм времён windows 3.1. В 32х разрядных ОС hInstance равен адресу загрузки файла. Для exe он по умолчанию равен 0x400000 (можно изменить указав линкеру ключ /BASE:xxxxx)
A>Это нигде не документированно.
А как же:
The /BASE option sets a base address for the program, overriding the default location for an .exe file (at 0x400000)
A>Надо пользоваться GetModuleHandle(NULL) для EXE и первым параметром DllMain для DLL
Я бы заменил слово "надо" на "правильнее". Для dll тоже есть альтернативный способ — взять адрес любой функции или статической переменной, расположенной в первых (0x100000 — размер PE заголовка) байтах файла, и сделать с ним операцию & 0xfff00000. Релоки сделают всю остальную работу при загрузке файла . Правда, тут польза сомнительна, разве что для вирей каких-то.
A>Кроме того менять имя стандартной точки входа не объязательно. По умолчанию это
A>__declspec(noreturn) extern "C" void __cdecl WinMainCRTStartup() A>__declspec(noreturn) extern "C" void __cdecl mainCRTStartup() A>extern "C" BOOL WINAPI _DllMainCRTStartup(HANDLE hDllHandle, DWORD reason, LPVOID)
Писанины больше .
A>Уже нельзя делать return msg.wParam, надо ExitProcess(msg.wParam);
Можно. В стеке лежит адрес возврата в kernel32.dll.
A>И по поводу "кучи ненужного кода" — не согласен.
Применительно к данной программе он не нужен.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[6]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, gear nuke, Вы писали:
A>>Это нигде не документированно. GN>А как же:
The /BASE option sets a base address for the program, overriding the default location for an .exe file (at 0x400000)
Тfк в том-то всё и дело, что default. Нигде не написано, что base address of EXE file always is 0x400000.
A>>Уже нельзя делать return msg.wParam, надо ExitProcess(msg.wParam); GN>Можно. В стеке лежит адрес возврата в kernel32.dll.
Это не одно и то же. return завершит главный поток, но не приложение.
A>>И по поводу "кучи ненужного кода" — не согласен. GN>Применительно к данной программе он не нужен.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, gear nuke, Вы писали:
GN>>Это всё верно, но для данного случая не важно . Кроме того, __try __except всё равно будет работать, что в некоторых случаях достаточно. Форум же по WinAPI, а не С++ .
A>Ну Hello World и на ассемблере можно написать
В случае Hello World никакого выигрыша от использования ассемблера не будет, в отличае от более сложных проектов . Другое дело, если заказчик хочет сорцы — то он предпочитает языки для которых проще найти человека способного сопровождать код.
А вообще, исходля из названия топика можно предположить, что требуется минимальный размер exe.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, adontz, Вы писали:
A>Указывай --force. Судя по документации это не ошибка, а предупреждение, что при упаковке некоторые метаданные PE могут ыть потеряны. Собственно у меня проблем при использовании --force никогда не возникало.
Не надо указывать --force. И вообще, не пакуйте UPX-ом executables, сделанные 2003 студией. Под windows 2003 такой EXE, скорее всего, упадет. Один из авторов UPX говорит, что проблема известная, но фиксить они ее в ближайшее время не собираются.
Успехов,
Виталий.
Re[7]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, gear nuke, Вы писали:
GN>А вообще, исходля из названия топика можно предположить, что требуется минимальный размер exe.
Например у меня была DLL с кучей текстовых строк. При сжатии размер уменьшился с 3Мб, до 260Кб.
А если таких DLL много, то вопрос может стоять как поместиться ли приложение на носитель XYZ.
Здравствуйте, adontz, Вы писали:
A>>>Это нигде не документированно. GN>>А как же:
The /BASE option sets a base address for the program, overriding the default location for an .exe file (at 0x400000)
A>Так в том-то всё и дело, что default. Нигде не написано, что base address of EXE file always is 0x400000.
Это можно гаронтировать используя вышеприведённый ключик .
A>>>Уже нельзя делать return msg.wParam, надо ExitProcess(msg.wParam); GN>>Можно. В стеке лежит адрес возврата в kernel32.dll.
A>Это не одно и то же. return завершит главный поток, но не приложение.
В случае, когда tread всего один, это будет одно и тоже.
И вот что находится по адресу лежащему в стеке (на который попадёт return):
A>>>И по поводу "кучи ненужного кода" — не согласен. GN>>Применительно к данной программе он не нужен.
A>И она никогда не вырастет?
У меня плохо получается предсказывать будущее .
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[8]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, adontz, Вы писали:
GN>>А вообще, исходля из названия топика можно предположить, что требуется минимальный размер exe.
A>Например у меня была DLL с кучей текстовых строк. При сжатии размер уменьшился с 3Мб, до 260Кб.
Я бы не стал упаковывать такую dll — это снизит производительность, поскольку секции PE после распаковки будут отображаться на файл подкачки, а не на оригинальный PE.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: UPX 1.24w NotCompressibleException (MS VC++ .NET Pro
Здравствуйте, retalik, Вы писали:
R>Не надо указывать --force. И вообще, не пакуйте UPX-ом executables, сделанные 2003 студией. Под windows 2003 такой EXE, скорее всего, упадет. Один из авторов UPX говорит, что проблема известная, но фиксить они ее в ближайшее время не собираются.
Мои как раз там сейчас и работают. Ссылку на описание проблемы не дашь?
RSQ>EXE-шник становится меньше. Но тогда программа запускается, появляется в процессах и дальше ничего.
RSQ>Тоесть теперь параметры WinMain не работают. Значит RSQ>
RSQ>#pragma comment(linker, "/subsystem:windows")
RSQ>BOOL WINAPI WinMain(
RSQ> HINSTANCE hInstance, // указывается явно
RSQ> HINSTANCE hPrevInstance,
RSQ> LPSTR lpCmdLine, // отменяется стоЯщей выше прагмой
RSQ> int nCmdShow // указывается явно
RSQ>)
RSQ>
WinMain нельзя указывать в качестве входной точки, поскольку параметры для неё не определены!!
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth