{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Блоги: заметки с тегом *fuck",
    "_rss_description": "Автоматически собираемая лента заметок, написанных в блогах на Эгее",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": false,
    "_itunes_explicit": "no",
    "home_page_url": "https:\/\/blogengine.ru\/blogs\/tags\/fuck\/",
    "feed_url": "https:\/\/blogengine.ru\/blogs\/tags\/fuck\/json\/",
    "icon": false,
    "authors": [
        {
            "name": "Илья Бирман",
            "url": "https:\/\/blogengine.ru\/blogs\/",
            "avatar": false
        }
    ],
    "items": [
        {
            "id": "120405",
            "url": "https:\/\/bolknote.ru\/all\/sectorcfuck\/",
            "title": "SectorCFuck",
            "content_html": "<p>Очень интересно устроен разбор файла программы в <a href=\"https:\/\/web.archive.org\/web\/20230609141452\/https:\/\/habr.com\/ru\/companies\/ruvds\/articles\/740310\/\">компиляторе <i>SectorC<\/i><\/a>, который я ковыряю вечерами из любви к ненормальному программированию. Для тех, кто успел позабыть, напомню — этот компилятор занимает один сектор (512 байт) и способен выполнять программу на подмножестве Си.<\/p>\n<p>Когда смотришь на код такого маленького объёма, сразу возникает вопрос — каким чудом удалось туда запихнуть грамматику языка Си, даже если какое-то подмножество? Ответ — хеширование.<\/p>\n<p>Автор использует реализацию функции <tt>atoi<\/tt>, которая превращает любые строки в шестнадцатибитное числа:<\/p>\n<pre class=\"e2-text-code\"><code class=\"cpp\">unsigned short sectorc_atoi(const char *s)\r\n{\r\n    unsigned short n = 0;\r\n    for (;;) {\r\n        char c = *s++;\r\n        if (!c) break;\r\n\r\n        n = 10 * n + (c - &#039;0&#039;);\r\n    }\r\n\r\n    return n;\r\n}<\/code><\/pre><p>Все токены, которые встречаются в программе, обязательно разделяются пробелами (за исключением <tt>;<\/tt>, для него есть специальная обработка). Это позволяет довольно просто парсить программу — любой токен скармливаем <tt>atoi<\/tt>, получаем число и по таблице смотрим с чем имеем дело.<\/p>\n<p>Если в таблице число не находится, значит это переменная, её численное значение, умноженное на два, даёт двухбайтовую область памяти, где надо взять значение. Для чисел, видимо, есть какая-то отдельная логика, я не читал подробно исходник, но из моих экспериментов как будто бы следует, что числом считается всё, что не токен и не может быть именем переменной.<\/p>\n<p>Перед запуском программа проходит через линтер, который не является частью компилятора. Он нужен для поиска ошибок в коде и коллизий в получившихся хешированных значениях. В последнем случае линтер останавливается с ошибкой, показывая хеши каких токенов совпали между собой.<\/p>\n<p>Если линтер выключить, можно достигнуть интересного эффекта. Для каждого токена можно вычислить коллизию позаковыристей и написать всю программу без букв и цифр. <i>SectorC<\/i> как будто бы «из коробки» предназначен для запуска обфусцированного кода.<\/p>\n<p>Ниже программа, выводящая «<i>Hello<\/i>» (её надо запускать <i>без линтера<\/i>):<\/p>\n<pre class=\"e2-text-code\"><code class=\"plaintext\">&lt;**^ &#039;)&#039;|] \/=]\r\n    -_.@&quot; -[ )~( \/@&lt; $^+&gt;\\() \/&lt;&#039;\r\n    -_.@&quot; -[ \/&lt;&#039;&#039; \/@&lt; $^+&gt;\\() \/&lt;&#039;\r\n    -_.@&quot; -[ ,[~ \/@&lt; $^+&gt;\\() \/&lt;&#039;\r\n    -_.@&quot; -[ +^^` \/@&lt; $^+&gt;\\() \/&lt;&#039;\r\n    -_.@&quot; -[ \/&lt;(&#039; \/@&lt; $^+&gt;\\() \/&lt;&#039;\r\n,[_<\/code><\/pre><p>Я поленился и не стал рассчитывать разные значения для одинаковых токенов, которые упоминаются несколько раз, но можно сделать и это, тогда восстановление исходного текста будет безумно затратной задачей.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/bolknote.ru\/pictures\/2023.06.14@2x.jpg\" width=\"1000\" height=\"128\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Пример запуска обфусцированной программы без линтера<\/div>\n<\/div>\n<p>Обфусцированный таким образом листинг, запускающий файл и программу для поиска коллизий <a href=\"https:\/\/github.com\/bolknote\/SectorC-obstruction\">выложил на «Гитхаб»<\/a>, можно посмотреть подробности там.<\/p>\n<p>Кстати, такое развлечение, когда мы не используем в программе алфавитно-цифровые символы, называется <a href=\"https:\/\/bolknote.ru\/tags\/smthfuck\/\">ЧтоНибудь<i>Fuck<\/i><\/a>, уж так повелось, — <i>FuckJS<\/i>, <i>FuckPHP<\/i> и так далее. Отсюда и название заметки.<\/p>\n",
            "date_published": "2023-06-14T20:08:51+05:00",
            "date_modified": "2023-06-15T23:54:51+05:00",
            "tags": [
                "*fuck",
                "sectorc",
                "программирование",
                "си"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Wed, 14 Jun 2023 20:08:51 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "120405",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        },
        {
            "id": "136574",
            "url": "https:\/\/bolknote.ru\/all\/4620\/",
            "title": "F★ckJS на поло",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"https:\/\/bolknote.ru\/pictures\/2017.08.08@2x.jpg\" width=\"640\" height=\"360\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Поло с программой на ДжаваСкрипте, написанной четыре года назад<\/div>\n<\/div>\n<p>Очень в тему к <a href=\"https:\/\/bolknote.ru\/all\/4619\/\">предыдущему посту<\/a> на работе нашёлся мешок с поло размера <i>XXL<\/i> (из-за размера и сохранился, остальные разобрали).<\/p>\n<p>На поло программа на ДжаваСкрипте, которую я писал к какому-то событию, должно быть готовились к какой-то конфереции — если её запустить в консоли браузера, появляется надпись «<i>prihodite rabotat 88002005221<\/i>». У меня в «исходящих» сохранилось письмо от 11 марта 2013 года, где я высылаю оригинал этой программы нашему дизайнеру, четыре года уже прошло, надо же.<\/p>\n",
            "date_published": "2017-08-08T12:11:00+05:00",
            "date_modified": "2025-07-08T17:39:59+05:00",
            "tags": [
                "*fuck",
                "javascript",
                "программирование"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Tue, 08 Aug 2017 12:11:00 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "136574",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        },
        {
            "id": "133178",
            "url": "https:\/\/bolknote.ru\/all\/4251\/",
            "title": "Как работает Bashfuck",
            "content_html": "<p>Думаю, по горячим следам надо описать как работают мои <a href=\"\/2014\/12\/09\/~4248\"><i>Bashfuck<\/i><\/a> и <a href=\"\/2014\/12\/10\/~4250\"><i>Bashfuck-2<\/i><\/a>. Пока ещё сам детально помню.<\/p>\n<p>Поскольку буквы и цифры использовать запрещено, все имена переменных состоят исключительно из подчёркиваний — это единственный вариант в «Баше» в таком случае. Чтобы что-то напечатать, сначала надо получить какие-то буквы.<\/p>\n<p>К счастью, переменная с именем, состоящим из одного подчёркивания содержит полный путь к интерпретатору, которым был запущен наш скрипт. Поскольку путь может отличаться, а название интерпретатора — нет, путь надо удалить, оставив только слово «<i>bash<\/i>». Это делается в обоих случая в первой строке:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># Удаляем из переменной $_ всё до последнего слеша\n__=${_##*\/}<\/code><\/pre><\/pre><p>Теперь у нас есть четыре буквы «<i>b<\/i>», «<i>a<\/i>», «<i>s<\/i>» и «<i>h<\/i>». Из имеющегося надо как-то получить недостающее. Тут нам помогает следующий факт: можно запускать что угодно, по имени, которое содержится в переменной.<\/p>\n<p>Далее оба скрипта пытаются составить в одной из переменных команду «<i>base64<\/i>», чтобы передав ей на вход строку, получить недостающие буквы. В самом деле, передавая на вход разные строки и пропуская их по нескольку раз через «<i>base64<\/i>» команду, можно получить весь английский алфавит:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># bash тут — строка, которую мы уже получили\n$ base64&lt;&lt;&lt;bash\nYmFzaAo=\n$ base64&lt;&lt;&lt;bash | base64\nWW1GemFBbz0K<\/code><\/pre><\/pre><p>Например, в полученных строках некоторые буквы нам вполне интересны: «<i>Hell<b>o<\/b> <b>wo<\/b>rld<\/i>». Но как получить слово <i>base64<\/i>? С цифрами проще: имея строки разной длины и арифметические операции можно получить нужное:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># Переменная __ содержит слово bash\n__=bash\n# Очень просто получить цифру четыре: надо измерить длину строки:\n$ echo ${#__}\n4\n# Любым похожим путём получаем двойку, прибавляем к четвёртке и у нас есть 6\n$ echo $((${#__} + 2))\n6<\/code><\/pre><\/pre><p>Поскольку типы переменных «Баш» не особо-то различает, склеить всё остальное труда не представляет. Но нужно ещё откуда-то получить букву «<i>e<\/i>». Тут дорожки этих двух скриптов расходятся. Первый работает так: составляя из имеющихся букв команду «<i>hash<\/i>», запускает её и получает следующую строку:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">$ hash\nhash: hash table empty<\/code><\/pre><\/pre><p>Второй действует интереснее. Есть такой синтаксис для команд, которые на вход принимают только файл: можно передать вывод другой команды особым образом и интерпретатор подставит в параметр специальное имя псевдофайла из которого можно прочитать упомянутый вывод.<\/p>\n<p>Если использовать такой синтаксис с любой командой, которая принимает не файл, а строку, то строку и получим (цифры будут меняться от запуска к запуску, остальная строка останется неизменной):<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># пробуем вывести на печать\n$ echo &lt;(:)\n\/dev\/fd\/63<\/code><\/pre><\/pre><p>Нам это значение нужно в переменной и с присвоением этот трюк тоже сработет.<\/p>\n<p>В том и другом скрипте нужную букву мы получили и можем собрать нужное имя без проблем. Для этого воспользуемся следующей конструкцией, которая позволяет выбирать подстроки из переменных:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># переменная теперь содержит что-то вроде \/dev\/fd\/xx\n___=&lt;(:)\n# выбираем третий символ (отсчёт с нуля):\necho ${___:2:1}<\/code><\/pre><\/pre><p>Вместо двойки и единицы можно подставить переменные, которые эти числа содержат, либо вычислить их по ходу дела. Во втором примере применяется ещё и другая техника —  поскольку некоторые числа из подручных переменных вычислять сложно, я срезаю некоторое количество букв слева и справа, чтобы добраться до нужной буквы:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\"># переменная, где нужная мне буква в середине слова\nv=sed\n# так можно срезать последнюю букву\necho ${v%?}\n# а так —  первую\necho ${v#?}<\/code><\/pre><\/pre><p>По большому счёту, это всё. Используется ещё несколько приёмов, но для понимания происходящего осталось пояснить только ещё одну вещь. В четвёртом «Баше», который требуется для работы обоих скриптов, есть ещё такой специальный синтаксис, который позволяет менять регистр букв. Это позвояет не заморачиваться с тем, в каком регистре получаются отдельные буквы и првести всё к нужному ближе к концу:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">v=&#039;heLLo WORld&#039;\n# всё к нижнему (будет hello world)\necho ${v,,}\n# только первую —  к верхнему (будет HeLLo WORld)\necho ${v^}<\/code><\/pre><\/pre><p>Собранную строку осталось вывести на экран. Для этого в том же коде я попутно собираю из получающихся букв ещё и строку «<i>cat<\/i>» (что на одну букву меньше «<i>echo<\/i>», кода получается меньше) и с помощью этой команды получаю нужный результат:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">c=cat\nv=&#039;Hello world&#039;\n# Выведет Hello world\n$c&lt;&lt;&lt;$v<\/code><\/pre><\/pre><p>Можно, кстати, попробовать ещё задействовать функции, благо их объявление алфавитных символов не требует, а их имена могут подержать не только подчёркивания (но и, например, «собаку», что даёт бо́льшую свободу), но третий вариант я уже делать не буду, надоело.<\/p>\n",
            "date_published": "2014-12-10T21:44:00+05:00",
            "date_modified": "2024-12-09T15:25:33+05:00",
            "tags": [
                "*fuck",
                "bash",
                "программирование"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Wed, 10 Dec 2014 21:44:00 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "133178",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        },
        {
            "id": "124867",
            "url": "https:\/\/bolknote.ru\/all\/3954\/",
            "title": "JavaScript, совмещённый с Brainf*ck: «hello friends»",
            "content_html": "<p>Помните моё поздравление с <a href=\"\/2012\/01\/05\/~3535\/\">Новым годом<\/a>, написанное на запутанном Джаваскрипте? Такой же принцип я использовал для привлекающего внимание <a href=\"https:\/\/twitter.com\/bolknote\/status\/315333227718012929\/photo\/1\">баннера нашей компании<\/a>.<\/p>\n<p>Я давно уже заметил, что это сильно похоже на язык <a href=\"http:\/\/ru.wikipedia.org\/wiki\/Brainfuck\">Брейнфак<\/a>. Давно хотелось попробовать смешать эти два языка в одном листинге. Со стороны Брейнфака всё довольно гладко — надо только балансировать квадратные скобки (но Джаваскрипт требует того же) и избегать вечных циклов (тут уже сложнее, так как листинги на запутанном Джаваскрипте часто требуют пустых циклов), незнакомые символы этот язык пропускает. В Джаваскрипте синтаксис построже, там нужно было помучаться больше.<\/p>\n<p>Получилась следующая программа (используется расцветка для Брейнфака, чтобы было видно какие части программы он пропускает):<\/p>\n<pre class=\"e2-text-code\"><code class=\"hljs lang-plaintext\">($=!{}<span class=\"hljs-meta\">[<\/span>\/<span class=\"hljs-meta\">-<\/span>\/<span class=\"hljs-meta\">+<\/span>\/\\<span class=\"hljs-meta\">+<\/span>@<span class=\"hljs-meta\">+<\/span>@<span class=\"hljs-meta\">+<\/span>!<span class=\"hljs-meta\">+<\/span>\/)<span class=\"hljs-meta\">-<\/span>!{$:\/<span class=\"hljs-meta\">&gt;<\/span>\/<span class=\"hljs-meta\">+<\/span>\/!<span class=\"hljs-meta\">&gt;<\/span>\/<span class=\"hljs-meta\">+<\/span>\/<span class=\"hljs-meta\">&lt;<\/span>\/}<span class=\"hljs-meta\">+<\/span>\n(_=!<span class=\"hljs-meta\">-<\/span>{}<span class=\"hljs-meta\">-<\/span>$<span class=\"hljs-meta\">+<\/span>\/<span class=\"hljs-meta\">&gt;<\/span>\/)<span class=\"hljs-meta\">-<\/span>~(\/<span class=\"hljs-meta\">&lt;<\/span>\/)<span class=\"hljs-meta\">+<\/span>\n(_$=<span class=\"hljs-meta\">-<\/span>$<span class=\"hljs-meta\">-<\/span>{}<span class=\"hljs-meta\">-<\/span>$<span class=\"hljs-meta\">+<\/span>\/<span class=\"hljs-meta\">&gt;<\/span>\/)<span class=\"hljs-meta\">[<\/span>$$=<span class=\"hljs-meta\">-<\/span>(~<span class=\"hljs-meta\">-<\/span>~$<span class=\"hljs-meta\">+<\/span>~<span class=\"hljs-meta\">-<\/span>~$<span class=\"hljs-meta\">-<\/span>!<span class=\"hljs-meta\">+<\/span>{$:\/!<span class=\"hljs-meta\">&lt;<\/span>\/})<span class=\"hljs-meta\">+<\/span>\n_<span class=\"hljs-meta\">[<\/span>$$<span class=\"hljs-meta\">+<\/span>=~<span class=\"hljs-meta\">-<\/span>~{$:\/<span class=\"hljs-meta\">]<\/span>\/}<span class=\"hljs-meta\">+<\/span>\n_$<span class=\"hljs-meta\">-<\/span>~{}<span class=\"hljs-meta\">+<\/span>\n_$<span class=\"hljs-meta\">[<\/span>$$<span class=\"hljs-meta\">+<\/span>~{_:<span class=\"hljs-meta\">-<\/span>$<span class=\"hljs-meta\">&gt;<\/span>\/<span class=\"hljs-meta\">]<\/span>\/}<span class=\"hljs-meta\">+<\/span>\n$<span class=\"hljs-meta\">-<\/span>$$<span class=\"hljs-meta\">]<\/span><\/code>\n<\/pre>\n<p>Оба интерпретатора выполняют её с разным результатом, Брейнфак выводит «<i>hello<\/i>», а Джаваскрипт — «<i>friends<\/i>»:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">bolk@Bolk ~$ .\/brainfuck &lt;&lt;&lt;&#039;($=!{}+[\/-\/]+\/\\+@+@+!+\/)[-!{$:\/&gt;\/+\/!+&gt;\/+\/&lt;&lt;\/}]+(_=!-{}+[-$]+\/&gt;\/)[-~(\/&gt;[-&gt;+&gt;+&lt;&lt;]&gt;&gt;[-&lt;+&lt;+&gt;&gt;]&lt;&lt;&lt;\/)]+(_$=[-$][-{}]+[-$]+\/&gt;&gt;\/)\n[$$=-(~-~$+~-~$-!+{$:\/!+&gt;+&gt;+&gt;+&gt;+&gt;+&lt;&lt;&lt;&lt;&lt;\/})]+_[$$+=~-~{$:\/[-&gt;++++&gt;+&gt;++++++++&gt;++++++++&gt;+++++++++++[&lt;]]\/}]+_$[-~{}]+_$[$$+~{_:-$&gt;\/[.&gt;]\/}]+$[-+-$$]&#039;\n\nhello\n\nbolk@Bolk ~$ v8 -e &#039;print(($=!{}+[\/-\/]+\/+@+@+!+\/)[-!{$:\/&gt;\/+\/!+&gt;\/+\/&lt;&lt;\/}]+(_=!-{}+[-$]+\/&gt;\/)[-~(\/&gt;[-&gt;+&gt;+&lt;&lt;]&gt;&gt;[-&lt;+&lt;+&gt;&gt;]&lt;&lt;&lt;\/)]+(_$=[-$][-{}]+[-$]+\/&gt;&gt;\/)\n[$$=-(~-~$+~-~$-!+{$:\/!+&gt;+&gt;+&gt;+&gt;+&gt;+&lt;&lt;&lt;&lt;&lt;\/})]+_[$$+=~-~{$:\/[-&gt;++++&gt;+&gt;++++++++&gt;++++++++&gt;+++++++++++[&lt;]]\/}]+_$[-~{}]+_$[$$+~{_:-$&gt;\/[.&gt;]\/}]+$[-+-$$])&#039;\n\nfriends<\/code><\/pre><p>Повозиться пришлось прилично, если честно, некоторые конструкции ДжЭс делит с Брейфаком (большинство квадратных скобок), а кое-где торчат чистые инструкции Брейнфака, засунутые в те места программы, где они не могут помешать своему соседу. Пустые циклы, которые образуются квадратными скобками я старался сводить к операции зануления ячейки („[-]“), сильно мешали плюсы, используемые в Джаваскрипте для объединения букв — они увеличивали содержимое ячейки в Брейнфаке на единицу, это приходилось учитывать.<\/p>\n<p>Слово «<i>friends<\/i>» я выбрал потому что его легко записать:<\/p>\n<pre class=\"e2-text-code\"><code class=\"javascript\">&quot;false&quot;[0]+&quot;true&quot;[1]+&quot;undefined&quot;[5]+&quot;true&quot;[3]+&quot;undefined&quot;[1]+&quot;undefined&quot;[2]+&quot;false&quot;[3]<\/code><\/pre><\/pre><p>Принцип я когда-то более-менее <a href=\"\/2012\/01\/05\/~3535\/#n32932\">подробно разбирал<\/a>.<\/p>\n",
            "date_published": "2013-04-28T16:44:00+05:00",
            "date_modified": "2023-12-12T13:29:42+05:00",
            "tags": [
                "*fuck",
                "bf",
                "brainfuck",
                "javascript"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Sun, 28 Apr 2013 16:44:00 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "124867",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        }
    ],
    "_e2_version": 4079,
    "_e2_ua_string": "Aegea 11.0 (v4079e)"
}