Форум программистов, компьютерный форум, киберфорум
Замабувараев
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Скачивание файла из URL

Запись от Замабувараев размещена 30.11.2021 в 18:41
Показов 1896 Комментарии 7

Предупреждение: это программа из категории «Спойлер: 2048 байт», если вы считаете, что в 21 веке нельзя экономить на диске, памяти и возиться с битами и байтами, обязательно напишите об этом комментарий.

Как‐то на одном разделе форума Я обратил внимание, что их компилятор, когда в коде есть функция загрузки файла, вместо программ создаёт 180‐килобайтное Bloatware.

Я подумал, а насколько можно вручную уменьшить размер исполняемого файла средствами компилятора, не прибегая к модификации екзешника? Оказалось, что функциональность загрузки файла с сайта можно уместить в 2048 байт. Потребуется всего лишь компилятор FreeBASIC.

(Я не буду приводить весь код, только объясню что он делает, весь код лежит на гитхабе по ссылке)

Чтобы уместиться в 2048 байт:

* запретим линковку со статическими библиотеками вроде Runtime Library
* будем вызывать функции ОС напрямую
* установим собственную точку входа

Начнём с конца.

Создадим простой текстовый файл и напишем там функцию EntryPoint:

Code
1
2
3
Sub EntryPoint()
    ' скачиваем байты и сохраняем в файл
End Sub
Это будет наша точка входа, где мы получаем параметры программы и запускаем функцию сохранения URL в файл. Скачивает файл объект XmlHttpRequest из библиотеки mshtml, тот самый, которым все пользуются для асинхронных запросов в JavaScript в браузёре.

А компилятору мы скажем, чтобы он только оттранслировал код в промежуточное представление и остановился:
Code
1
fbc -gen gcc -r -maxerr 1 -w all -O 0 -s console -d UNICODE GetWebSiteData.bas
Дальше из этого промежуточного представления мы получаем ассемблерный код, из ассемблерного кода → объектный файл, из объектного файла → исполняемый файл. Для линковщика указываем точку входа в виде -e ENTRYPOINT.

Таким образом мы получим программу примерно три килобайта. Чтобы уменьшить ещё, необходимо объединить секции .data и .text. Для этого у нас есть специальный сценарий линковщика, который удаляет всё лишнее и объединяет секции:
Code
1
2
3
4
5
6
7
8
9
10
11
SECTIONS
{
    /DISCARD/ :
    {
        *(.fbctinf) *(.comment) *(.note)
    }
    .text :
    {
        *(.text) *(.data) *(.rdata)
    }
}
В коде используется объект XmlHttpRequest, для его создания необходимы IID интерфейса и CLSID класса. Они есть в библиотеке uuid поставляемой вместе с компилятором. Но если использовать их прямо, то IID и CLSID помещаются в секцию .rdata и наотрез отказываются объединяться с секциями .data и .text. Я решил объявить эти CLSID и IID вручную:

Code
1
2
3
4
5
6
7
8
9
10
11
Type IID_IXmlHttpRequest_inline
    b(3) As ULong
End Type
 
    Dim iidXml As IID_IXmlHttpRequest_inline = Any
    iidXml.b(0) = &hED8C108D
    iidXml.b(1) = &h11D24349
    iidXml.b(2) = &hC000A491
    iidXml.b(3) = &hE869794F
 
' Аналогично для CLSID_XMLHTTPREQUEST
Секция .idata не захотела объединяться с остальными секциями, наверное потому что она модифицируется во время запуска программ. Но это объединение не уменьшило бы размер, потому что .idata заполнена под завязку, итак уже 512 байт. Забавно, вызов какой‐ниибудь новой функции добавит её в таблицу импорта — и секция .idata переполненная всего лишь на несколько байт, будет занимать уже не 512 + N, а все 1024 байта, что увеличит екзешник, который теперь будет окажется 2560 байт.

Программа консольная, можно переписать для GUI и окошек, но тогда будет пожирнее и помаслянистее, чем 2048 байт сейчас.

Ещё в программе нет удаления созданной памяти. Во‐первых, ещё одна функция в таблице импорта приведёт к её переполнению. Во‐вторых, в данном случае это не актуально, программа не выделяет память в цикле, скачивает файл и тут же завершается, система сама всё очистит.

Ссылка на исходный код:
https://github.com/zamabuvaraeu/DownloadFile

Релиз:
https://github.com/zamabuvarae... g/v1.0.0.0
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 7
Комментарии
  1. Старый комментарий
    Я обратил внимание, что их компилятор, когда в коде есть функция загрузки файла, вместо программ создаёт 180‐килобайтное Bloatware.
    При при этом почему-то умалчиваете что код кроссплатформенный (Windows, Linux, MacOS и др.) с поддержкой HTTPS. Ваш код только для винды.
    180 КБ с учетом кроссплатформенности это очень немного.

    Читая остальную часть статьи, возникает смыл - а зачем такие сложности? Затрата времени и сил больше чем возможная выгода.

    Релиз
    Зачем одни и те же исходники продублировали в zip и tar.gz архивах?
    Запись от locm размещена 02.12.2021 в 19:16 locm на форуме
  2. Старый комментарий
    Аватар для Замабувараев
    180 КБ с учетом кроссплатформенности это очень немного.
    Ну могли бы транслировать функции языка PureBasic в вызовы ОС вместо того, чтобы велосипедить закачку. Не поверю, что там где запускается PureBasic нет таких функций в ОС.
    а зачем такие сложности? Затрата времени и сил больше чем возможная выгода
    В 2021 году говорить об маленьких программах, уменьшении размера бинарника, экономии на памяти — это правило дурного тона. Я могу себе позволить писать маленькие программы.
    Зачем одни и те же исходники продублировали в zip и tar.gz архивах?
    Это причуды гитхаба при создании Release, я ничего такого не делал.
    Запись от Замабувараев размещена 02.12.2021 в 19:44 Замабувараев вне форума
  3. Старый комментарий
    из этого промежуточного представления мы получаем ассемблерный код, из ассемблерного кода → объектный файл, из объектного файла → исполняемый файл. Для линковщика указываем точку входа в виде -e ENTRYPOINT.

    Таким образом мы получим программу примерно три килобайта. Чтобы уменьшить ещё, необходимо объединить секции .data и .text. Для этого у нас есть специальный сценарий линковщика, который удаляет всё лишнее и объединяет секции:
    Почему бы тогда сразу со сценария линковщика не начать?
    Или не написать на Бейсике программу, которая сама пишет виндовую DLL, выполняющую скачивание?
    Запись от politoto размещена 02.12.2021 в 20:28 politoto вне форума
  4. Старый комментарий
    В 2021 году говорить об маленьких программах, уменьшении размера бинарника, экономии на памяти — это правило дурного тона. Я могу себе позволить писать маленькие программы.
    Все эти правила как мода, которая приходит и уходит, а нормальное программирование остаётся.
    В 2022 году может появиться что-то ещё. Но самое главное уже давно создано, а ерунда-2021 лишь отвлекает от реального дела.
    Запись от wer1 размещена 02.12.2021 в 20:35 wer1 вне форума
  5. Старый комментарий
    Аватар для Замабувараев
    Или не написать на Бейсике программу, которая сама пишет виндовую DLL, выполняющую скачивание?
    DLL уже написана и лежит в system32, я лишь вызываю её функции.
    Запись от Замабувараев размещена 04.12.2021 в 03:56 Замабувараев вне форума
  6. Старый комментарий
    Я имею ввиду самодельную DLL, которая вызывает функцию из system32
    Запись от politoto размещена 04.12.2021 в 19:10 politoto вне форума
  7. Старый комментарий
    Аватар для Замабувараев
    Я имею ввиду самодельную DLL, которая вызывает функцию из system32
    Не считается. А то так вообще можно сделать пакетный файл с содержимым «wget https://www.cyberforum.ru/», это будет всего лишь 30 байт, смотрите как коротко.
    Запись от Замабувараев размещена 06.12.2021 в 19:23 Замабувараев вне форума
 
Новые блоги и статьи
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
Модель здравосохранения 17. Планы на выгорание
anaschu 23.05.2026
Вот конкретная схема реализации: В классе Работник добавить: накопленнаяУсталость — растёт каждый час работы, снижается в перерывы и болезни коэффициентПрезентеизма — снижает продуктивность. . .
Изменение цветов в палитре gif файла aka фавикона
russiannick 23.05.2026
Изменение цветов в палитре gif файла, юзаемого как фавиконка в составе html-файла, помещенная в base64, средствами нативного Java Script, навеянное сном в майский день. Для работы необходим браузер,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru