LINUX.ORG.RU

Объявлены победители 29 конкурса по написанию запутанного кода на языке Си

 , ,


0

4

Опубликованы исходные тексты работ, победивших в двадцать девятом конкурсе IOCCC (International Obfuscated C Code Contest), участникам которого предлагалось подготовить наиболее запутанный и трудноразбираемый код на языке Си. Участвующие в конкурсе работы, с одной стороны, должны препятствовать анализу кода и пониманию сути решаемой задачи, но, с другой стороны, код должен быть интересен и чем-то примечателен (работы могут быть необычно оформлены или выделять неожиданные стороны языка Си). Размер файла с кодом программы не должен превышать 4993 байтa, а чистый код не должен превышать 2503 байта после обработки утилитой iocccsize.

Среди победителей:

  • Эмулятор компьютера с архитектурой URISC, набор команд в котором ограничивается одной инструкцией SUBLEQ (SUbtract and Branch if Less than or EQual to zero). Размер эмулятора всего 366 байт, при том, что помимо CPU он эмулирует фреймбуфер с разрешением 800x512, используя для вывода графики библиотеку SDL3, и может загрузить образ с Linux и запустить в нём игру doom.
  • Генератор изображения чёрной дыры. Приложение включает простой интерпретатор для подмножества языка Fortran 66, программа для которого задана в форме перфокарт, закодированных через пробелы и табуляции в исходном коде. Закодированная Fortran-программа повторяет первый код для симуляции чёрной дыры, опубликованный Жан-Пьером Люмине в 1978 году. Изображение формируется в виде облака точек и сохраняется в формате PGM. Кроме симуляции чёрной дыры предложены варианты с закодированными «перфокартами» для расчёта множества Мандельброта, вычисления простых чисел и трассировки лучей.
  • Вариант утилиты patch, генерирующий утилиту diff через серию трансформаций собственного кода. На первом этапе скомпилированной утилите patch передаётся собственный исходных код, на основе которого формируется diff-файл. После применения этого diff-а к собственному коду на выходе получается программа, которая в цикле на основе своего кода генерирует набор коммитов с патчами в формате git am. При объединении данных коммитов командой git log --pretty=format:%s > final.c получается код с реализацией утилиты diff.
  • Игра (на скриншоте) в жанре Roguelike, работающая в текстовом терминале и позволяющая проходить автоматически генерируемый лабиринт, собирать артефакты и избегать монстров. Код оформлен в виде изображения подземного жителя и обфусцирован (строки зашифрованы, циклы реализованы через goto, при работе с массивами используется синтаксис «индекс[массив]»).
  • Генератор ASCII-анимации, воссоздающий заставку сериала «Доктор Кто» с симуляцией видеоэффекта «HowlRound» (туннель из уменьшающихся копий изображения), применявшегося в заставке 1963 года.
  • Эмулятор игровой приставки GameBoy, оптимизированный для запуска тетриса, но способный выполнять и другие игры (протестирован запуск ROM-файлов для десятка игр). Вывод формируется в форме псевдографики из Unicode-символов.
  • Симулятор звука морского прибоя на фоне автоматически генерируемой медитативной музыки. На выходе генерируется wav-файл, продолжительностью 5 минут.
  • Реализация самомодифицирующегося игрового автомата Quine Pong, предоставляющего две игры - пинг-понг и перепрыгивающий препятствия динозавр (как в пасхальном яйце из Google Chrome). Программа примечательна тем, что отображение кадров реализовано через цикличную перегенерацию кода программы (запуск приводит к выводу исходного кода для первого кадра, после компиляции этого кода формируется код для следующего кадра и так далее). Игровой процесс реализован через shell-скрипт, выполняющий цикличную перекомпиляцию кода.
  • Компилятор и генератор кода для языка Zoltraak. Язык включает только одно слово «zoltraak», которое комбинируется в разной форме с пробелами и пустыми строками. На вход подаётся любой текстовый файл, который преобразуется в программу на языке Си, состоящую из заголовка и последовательности на языке Zoltraak. Компиляция и выполнение сгенерированной Си-программы приводит к выводу содержимого исходного текстового файла.

Видео на youtube, длительность: 2:57:20.

>>> Источник: OpenNET

★★★★★

Проверено: maxcom ()
Последнее исправление: dataman (всего исправлений: 3)
Ответ на: комментарий от madcore

Проблемы с очередью команд дофига чего вызывает. И это исключительно проблемы конструкции этой очереди, между прочим.

Stanson ★★★★★
()
Ответ на: комментарий от Stanson

ога, а ещё они провинились тем, что чисто фон-неймовских сейчас а природе не существует, все как-то больше гарвардские при вскрытии
почему бы так?

madcore ★★★★★
()
Ответ на: комментарий от madcore

Реальных гарвардских мало, и в основном это однокристалки.

То, что конвейер и кеш разные сущности, не делает из фон-неймановской гарвардскую на самом деле.

Но можно наковырять ОС, которая будет делать страницы с кодом readonly, а страницы с данными noexec и позволять загружать только подписанные бинарники, но это будет костылегарвард только для userspace, и только для процессоров которые в noexec умеют.

Stanson ★★★★★
()
Ответ на: комментарий от Stanson

Нет вообще никакой разницы, насколько вычурные конструкции используются в ЯП. Всё равно они предназначены исключительно для создания чисто императивного кода для CPU, который и будет на самом деле выполняться.

Если бы не было разницы, все писали бы на ассемблере. И хранили бы исключительно целые числа от 0 до 255. Ведь как ни трактуй данные, в памяти они последовательность байтов.

Программа на любом языке используют исключительно возможности процессора фон-неймановской архитектуры по совершенно очевидным причинам.

Бывают языки программирования, для которых невозможно написать компилятор (например, PicoLisp).

Упомянутый выше Prolog позволяет писать недетерминированные программы.

Желание вывести свойства языка программирования из архитектуры процессора аналогично желанию вывести химические свойства веществ из физических свойств атомов, а поведение живых существ свести к химическим взаимодействиям.

monk ★★★★★
()
Ответ на: комментарий от shdown

Так ghc ещё не так давно в C компилировал. И сейчас может, хотя теперь нужно его специально компелять для этого.

Я не про то, что невозможно в Си преобразовать. Я про то, что при программировании на Си невозможно достаточно лаконично описать что-то вроде factorials = 1 : zipWith (*) factorials [1..]. И при преобразовании в Си получается очень тормозной код.

<ucontext.h> из POSIX.

И как с его помощью получить аналог

int f() 
{
  yield 1;
  yield g();
  yield 3;
}
?
monk ★★★★★
()
Ответ на: комментарий от Stanson

Программа на любом языке используют исключительно возможности процессора фон-неймановской архитектуры

Уже нет: https://habr.com/ru/articles/505360/

monk ★★★★★
()
Ответ на: комментарий от monk

вывести химические свойства веществ из физических свойств атомов

А что не так? Я думаю всю химию можно заменить чисто описанием физических процессов, при достаточной вычислительной мощности. Целесообразность, конечно, под вопросом, но всё же.

ptah_alexs ★★★★★
()
Ответ на: комментарий от Stanson

Мне кажется что на гарвардскую архитектуру намекают раздельные кэши L1 для инструкций и данных, которые есть во всех процессорах сейчас.

ptah_alexs ★★★★★
()
Ответ на: комментарий от ptah_alexs

Я думаю всю химию можно заменить чисто описанием физических процессов, при достаточной вычислительной мощности.

Проблема в терминах. Химические реакции не описываются в терминах координат и скоростей частиц и даже волновых функций.

У Шекли есть хорошая иллюстрация: https://litmir.club/br/?b=83905

monk ★★★★★
()
Ответ на: комментарий от Stanson

более того на явление что нотация человеков отличается от нотации исполнителя(асм как текстовое представление 1в1 машкода - оставляем в стороне макросы асмы и «оптимизирующие"асм_трансляторы) влияет что есть ещё „хранилище“

и зависит от коньюктуры хранят текстовый образ или бинарь готовый к исполнению (отложенная линковка и прочих адд-dll попытка усидеть на всех стульях разом без фатальных последствий)

да даже появление полей регистров в отличии от полей адрессов(которые в первую очередь были повсеместной причиной самомодификации когда нет ни косвенности ни флагов поэтому буквально вычисление и перезапись адресса в безусловном джампе единственный способ сделать ветвление — которое ещё и если ветвь выхода сверх редкая то буквально может быть быстрее чем переход по условию

т.е. реальный вопрос насколько код интерпретируемый(а проверка динамического условия это микро рефлексия) или прямой как шпала ( который будет реально сверх быстрым на линейных участках )

т.е. можно представить компилятор того же Си который будет выдавать код с минимум команд ветвления(ну профилировать нуна) что бы выход из цикла осуществлялся только тогда когда вычисления перетирают адрес куда „continue“ - и сама проверка не на каждой итерации а только по срабатывании кучи тригеров условий

:)

основная имхо причина отказа под самомодифицирующихся образов - то что есть язык реализации и язык исполнения и более того апаратная реализация стека и регистров уменьшило необходимость в прикладном коде переписывать поля команд

qulinxao3 ★☆
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.