Всем привет. Я сейчас занимаюсь изучением Haskell. Недавно попробовал писать на нем GUI приложения с помощью библиотеки wxHaskell. Библиотека отличная, но меня беспокоит размер программ, получаемый с ее помощью. За две недели игр с флагами оптимизации и отключением ненужного функционала удалось уменьшить размер exe-шника с 26 Мб до 3.16 Мб. Однако тут я уперся в проблему, которая и привела меня сюда. За каким-то хреном компилятор прилепил к exe-шнику таблицу экспорта. На всякий случай погонял программу в OllyDbg, вроде она ничего сама из себя не импортирует. Пробовал удалить секцию с помощью PE Tools, но тогда ОС перестает запускать программу, дескать неверный формат EXE. С форматом PE я немного знаком. На всякий случай сверился с документацией, вдруг какие-то поля после удаления .edata нужно поправить. Так и не нашел, в чем косяк. Скажите пожалуйста, что я не учел при удалении таблицы экспорта? Может, есть уже готовый софт, который поможет мне решить проблему (PE Optimizer 1.4 не помог)? И еще пара вопросов для кучи. Нельзя ли чем-то оптимизировать таблицу импорта, а то msvcrt.dll в ней встречается дважды. Правильно ли я понимаю, что у рядовых пользователей Windows эта библиотека идет вместе с системой, то есть ее не нужно таскать вместе со своей программой? ЗЫ. Архив что-то не аттачится, залил сюда: http://zalil.ru/31486837
Занулите RVA таблицы экспорта в DataDirectory. Ну ещё при удалении секции в SizeOfImage в OptionalHeader надо выставить правильное значение.
Открываю в PE Tools. Жму "Directories". Зануляю RVA - работает. Зануляю size - работает. Иду в Sections. Забиваю .edata нулями - пашет. Делаю kill section (from file) - "не является приложением win32". Восстанавливаю из бэкапа. Делаю kill section (from header) - "не является приложением win32". Восстанавливаю. Закрываю PE Tools. Делаю strip -R .edata - "не является приложением Win32". Объясните, пожалуйста, где я дурак?
== До strip -R .edata == size of image: 00334000 size of headers: 00000400 .edata virtual size: 00006938 virtual offset: 00325000 raw size: 00006A00 raw offset: 0031D800 flags: 40300040 == После strip -R .edata == size of image: 00334000 size of headers: 00000400 Прописываю size of image: 32d6c8 (= 334000 - 6938) - не пашет. Жмакаю на знаки вопроса рядом с size of image и size of headers - пересчитывает по своему, но все равно не пашет. Заметил, что после strip появляется загадочная секция с названием "Д". Восстановил экзешник из бэкапа, пересчитал ему size of image в PE Tools - пашет. Сделал kill section from file - не пашет. Пересчитал size of image руками - (333254 - 6938), получилось 32с91с - все еще не пашет. Может, дело в смещении других секций?
qwe8013, Не, не помогает. Но спасибо за идею. Я так понимаю, в образе программы не должно быть "дырок" и изменением virtual size секции, которая идет перед .edata мы убиваем двух зайцев - компенсируем size of image и избавляемся от "дырок". Так? Только откуда вы взяли число C000h?
Хм... заметил что PE Tools при удалении секции пересчитывает raw offset других секций. А там у нас импорты, ресурсы и тп. Весь заголовок придется пересчитывать Попробовал убить секцию только из заголовка, в .bss прибавил virtual size и raw size секции .edata но даже такой вариант не работает. Похоже, все не просто.
afiskon На сколько я помню я делал так: Export RVA=0 Fill section (0) Kill section from header .bss VirtualSize=C000h У меня всё работает.
qwe8013, спасибо, работает. Избавиться от лишних экспортов - как камень с плеч. Правда, идея была в том, чтобы уменьшить размер экзешника. Хотя теперь он и будет лучше сжиматься. Если кто-нибудь знает простой способ сделать это, поделитесь пожалуйста инфой.