Господа, подскажите плиз как уменьшить размер выполняемого файла в МАСМ? Как менять выравнивание и все такое? И еще, какой упаковщик более эффективен для ассемблерных, небольших приложений? Спасибо!
Тут пути два либо совмещать секции, либо паковать, потому что и то и другое вместе чаще всего плохо уживаются, не все упаковщики переваривают файлы с совмещёнными секциями. Пакер для асм файлов лучше всего FSG или UPX.
Caesarus Всё нижеописанное относится к MASM. На других не знаю. Во-первых можно readonly инициализированные данные (всякие строки) вставлять среди кода. Так в небольших программах можно избавиться от лишней секции. Неиниц-ые данные отдельную секцию не занимают. Во-вторых, сделай себе stub 64 байт и прилинковывай к своей проге вместо стандартного 128. К опциям линкера добавляешь что-нибудь типа /STUB:"stub.exe". Стаб размером менее 64 байт не советую, так как там уже слишком большие проблемы возникают. Об этом смотри статью на WASM.RU. В-третьих, линкеру укажи такую опцию "/MERGE:.rdata=.text" Это часто помогает. Таблицу relocation прилепляет к секции кода. Кстати, так можно и переименовывать секции, кроме ".rsrc". В-четвёртых, укажи линкеру прямо, что секции выравнивать не более чем по 512 байт: "/FILEALIGN:512". А то он иногда любит их по 4Кб выравнивать. В-пятых, откажись от выравнивания в коде типа "align 16" В-шестых, если совсем увлекаться... Избавься от печати Баала. Ну и напоследок. Для совсем трудных случаев можно попробовать избавиться от секции импорта в файле. Для этого смотри статью о получения адресов всех процедур через SEH и kernel32.dll. Это, конечно, геморрой, но может помочь. Тогда отсутствуют таблицы импорта и символьные имена файлов. Программа сначала находит адрес kernel32.dll. Потом из неё выуживает адреса всех интересующих функций. Поиск идёт не сравнением имён, а сравнением хэша от каждого искомого имени. Тогда каждое имя хранится как 4 байта а не длинным именем. Потом через LoadLibrary получаешь любую другую библиотеку и подобным образом получаешь нужные функции. Это, конечно, техника вирусов. Но сама по себе возможная. И я не гарантирую, что дополнительный код, который для этого понадобится, выиграет в размере за счёт таблиц импорта. Да, мы ещё не говорили об использовании упаковщиков...
S_T_A_S_ > Что бы не было релоков Их и так не будет, по умолчанию masm для файла с ImageBase=0x400000 релоки не добавляет. ЗЫ: ещё, иногда, уменьшить размер exe'шника помогает указание линкеру /opt:nowin98 - справедливо для MSVC и masm.
выраанивание секций: /OPT:WIN98 - 4K /OPT:NOWIN98 - 512 ЗЫ: про релоки я точно напутал - нужно указывать /fixed, но это только для dll актуально, экзешники их по умолчанию не имеют.
Мы говорим о ещё большем уменьшении. С помощью FILEALIGN можно ставить любое выравнивание секций до 2. Т.е. /FILEALIGN:2. Тогда файл ещё уменьшится.
что такое печать Баала? можно ли вообще в масме выкинуть stub(как в фасме)? как это сделать растолкуйте плиз если не затруднит?
объясните пожалуйста это как? [add] забавно иногда получается.. есть секция .text (200h) и .rdata (200h) если их объединить то получается одна секция размером 600h, смотриш а там сначала .text затем куча нулей затем импорт а потом опять куча нулей как-то он их кривовато объединяет, кста ещё заметил что создаётся всегда секция .data даже если её и нет в сорце
slackhead Для повышения быстродействия, люди иногда пичкают код директивами align для выравнивания меток циклов, функций, массивов, ... Таким образом можно получить от 0 до 15 лишних байт в коде и/или данных на каждый align. На общий размер экзешника это врядли сильно повлияет, но у оптимизаторов-параноиков каждый байт на счету Должна получиться одна секция размером <= 400h. Покажите пример обратного - разберёмся. Становится ещё интересней! Пример в студию.
Quantum Лучше на ты, я конечно понимаю уважение и всё такое, но на ты как-то более по дружески, ок? так попорядку: То что ты так удивился на счёт этого вопроса подвергло сомнению мои прежние опыты.. перепроверил, оказывается точно мой косяк.. для секцтии .data? создаёться одноимённая секция .data ( до этого я думал то что это инициализированные данные секции из .data) c rawsize'ом = 0. привожу: а аттаче сорец, соберём его следующими коммандами Код (Text): ml /c /coff /Id:\mustdie\prog\masm32\include bindshell.asm link /subsystem:windows /libpath:d:\mustdie\prog\masm32\lib bindshell.obj и поглядим секции : Код (Text): .data ;rawsize этой секции = 0 .rdata ;rawsize = 200h .text ;rawsize = 200h размер: 1 536b теперь объединим ка .data + .text : Код (Text): ml /c /coff /Id:\mustdie\prog\masm32\include bindshell.asm link /subsystem:windows /libpath:d:\mustdie\prog\masm32\lib /merge:.text=.data bindshell.obj link.exe сказал warning, а оли ругнулся на то что EP outside.. секции: Код (Text): .data ;rawsize = 200h .rdata ;rawsize = 200h размер такой-же. Теперь замутим все секции в одну: Код (Text): ml /c /coff /Id:\mustdie\prog\masm32\include bindshell.asm link /subsystem:windows /libpath:d:\mustdie\prog\masm32\lib /merge:.text=.data /merge:.data=.rdata bindshell.obj на выходе получаем одну секцию .rdata размером 600h а суммарный размер бинари терь 2 048b Пробовал баловаться /ALIGN'ом но размер только увеличивался Заметим линкер версии 5.12.8078 поставляемый с masm9 очевидно по умолчанию принимает /FILEALIGN=512 т.к. если поставить меньше бинарник и вовсе не запускается (w2k3) а ставить больше смысла нет Насчет печати Баала конечно прикольно, что экономиться 40h байт и твой бинарник очищается от всякой нечисти (кстати знает ли кто нибудь какие там действительно компрометирующие данные хараняться?) но всё тотже FILEALIGN все эти усилия стирает подчистую. Если кто нить может сказать как ещё уменьшить этот бинарник (миннимальный размер 1 536) не собирая сорец winhex'ом, и не трахаясь и импортом (как указывалось выше SolidCod'ом, отказываясь от импотра как такового о получая API через hash'ы) welcome! респект всем кто это прочитал
slackhead Код (Text): /merge:.data=.text -ignore:4078 Чтоб и Оля не ругалась, и варнинга не было. Дело в том, что линкер обьединяет секции в таком порядке: _text (IAT) _text (.CODE) _data (.DATA?) _idata$4 \ _idata$5 | (.rdata) _idata$6 / Последние 3 - это огрызки из секции rdata, которые содержат имена импортируемых функций. Т.е. эти данные являются инициализированными и попадают ПОСЛЕ неинициализированных данных секции .DATA. Поэтому данные секции .DATA после обьединения автоматически становятся инициализированными и размер экзешника заметно возрастает. Такой порядок наблюдается независимо от порядка аргументов директивы /MERGE. Конечно, если бы секция .DATA клеилась в самом хвосте (после IAT _text, основной _text и огрызков _idata), размер бы не пострадал. Весь фокус заключается в суффиксах $4, $5 и $6. Линкер твёрдо уверен, что аналогичные секции (_data и _idata обе принадлежат категории DATA) должны склеиваться в порядке возрастания суффиксов. Поэтому проблему можно решить просто переименовав секцию неинициализированных данных во что-то типа _idata$7. Как это сделать - см. ссылку в параллельной ветке.