{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Блоги: заметки с тегом ассемблер",
    "_rss_description": "Автоматически собираемая лента заметок, написанных в блогах на Эгее",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": false,
    "_itunes_explicit": "no",
    "home_page_url": "https:\/\/blogengine.ru\/blogs\/tags\/assembler\/",
    "feed_url": "https:\/\/blogengine.ru\/blogs\/tags\/assembler\/json\/",
    "icon": false,
    "authors": [
        {
            "name": "Илья Бирман",
            "url": "https:\/\/blogengine.ru\/blogs\/",
            "avatar": false
        }
    ],
    "items": [
        {
            "id": "130929",
            "url": "https:\/\/bolknote.ru\/all\/programma-s-imenem-0xff\/",
            "title": "Программа с именем 0xFF",
            "content_html": "<p>В ДОСе, как может кто-то ещё помнит, была своя, отличная от всего, кодировка русских букв, так называемая <i>CP866<\/i>. Это однобайтовая кодировка, то есть в таблице символов всего 256 позиций.<\/p>\n<p>Поэтому странно, что пробельных символов в ней два, один из них — обычный пробел с кодом 32, именно его операционная система считает пробелом, второй — с кодом 255, он выводится как пробел, но считается обычным символом.<\/p>\n<p>Не помню, использовалось ли это свойство для чего-то полезного или интересного, но на днях <a href=\"https:\/\/www.opennet.ru\/openforum\/vsluhforumID3\/134899.html#50\">прочитал<\/a> как развлекались с его помощью в те времена:<\/p>\n<blockquote>\n<p>А 255 символ запретили? 30 лет назад, еще под <i>MSDOS<\/i>, переименовали утилиту переворота экрана в 255 символ и вставили в <i>autoexec.bat<\/i>. Хозяин компа уже психовать начал и монитор переворачивать :)) Показали ему прикол…<\/p>\n<\/blockquote>\n<p>Ну то есть переименовали программу так, чтобы её имя выглядело как пробельный символ и добавили её в скрипт автозагрузки. Хозяин компьютера, видимо, проверял скрипт, ничего не находил и не понимал что происходит.<\/p>\n<p>Мне стало интересно проверить — действительно ли это работает? Благо ДОС можно сейчас запустить <a href=\"https:\/\/www.pcjs.org\/software\/pcx86\/sys\/dos\/microsoft\/6.22\/\">даже в браузере<\/a>.<\/p>\n<p>Тут надо пояснить, что «настоящий» пробел для этого не годится — ДОС просто не распознает его в автозагрузке как имя файла для запуска.<\/p>\n<p>Я не знаю как раньше вводили символ с кодом 255 в командную строку, поэтому просто набросал программу на ассемблере, которая переименовывает файл <tt>mem.exe<\/tt> (которая обычно есть в составе ДОСа) в <tt> .com<\/tt>:<\/p>\n<pre class=\"e2-text-code\"><code class=\"asm\">org 100h\n\nsection .data\n    oldName db &#039;MEM.EXE&#039;, 0\n    newName db 255, &#039;.COM&#039;, 0\n\nsection .text\nglobal _start\n\n_start:\n    mov ah, 56h\n    lea dx, oldName\n    lea di, newName\n    int 21h\n\n    mov ax, 4C00h\n    int 21h<\/code><\/pre><p>Необходимое пояснение: расширение обязательно, иначе ДОС не поймёт, что файл запускаемый. При запуске его можно не указывать — операционка догадается сама что именно подставить.<\/p>\n<p>На следующем шаге я скомпилировал программу у себя прямо в «МакОСи» и вывел в шестнадцатеричном виде:<\/p>\n<pre class=\"e2-text-code\"><code class=\"plaintext\">$ hexdump -C &lt;(nasm -f bin rename.asm -o \/dev\/stdout)\n00000000  b4 56 8d 16 14 01 8d 3e  1c 01 cd 21 b8 00 4c cd  |.V.....&gt;...!..L.|\n00000010  21 00 00 00 4d 45 4d 2e  45 58 45 00 ff 2e 43 4f  |!...MEM.EXE...CO|\n00000020  4d 00                                             |M.|\n00000022<\/code><\/pre><p>Далее набрал её в кодах при помощи команды <tt>DEBUG<\/tt> и запустил. В текущей директории появилась программа с нужным именем:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/bolknote.ru\/pictures\/2024.09.26.1@2x.webp\" width=\"872\" height=\"477\" alt=\"\" \/>\n<\/div>\n<p>Для последнего шага мне нужно было как-то снова получить символ 255 в командной строке. Для этого я перенаправил вывод команды <tt>DIR<\/tt> в файл <tt>START.BAT<\/tt> и отредактировал получившееся при помощи команды <tt>EDIT<\/tt> — убрал всё лишнее, кроме символа с именем команды (кажется у меня в файл попали ещё и лишние переводы строки, но они роли не играют).<\/p>\n<p>Попробовал запустить, сработало!<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/bolknote.ru\/pictures\/2024.09.26.2@2x.webp\" width=\"872\" height=\"477\" alt=\"\" \/>\n<\/div>\n",
            "date_published": "2024-09-26T10:59:20+05:00",
            "date_modified": "2024-09-26T12:02:12+05:00",
            "tags": [
                "dos",
                "ассемблер",
                "программирование"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Thu, 26 Sep 2024 10:59:20 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "130929",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        },
        {
            "id": "136262",
            "url": "https:\/\/bolknote.ru\/all\/4656\/",
            "title": "Дизассемблируй это",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"https:\/\/bolknote.ru\/pictures\/2018.01.27.jpg\" width=\"640\" height=\"400\" alt=\"\" \/>\n<div class=\"e2-text-caption\">«ДУМ», скомпилированный с использованием одних только команд <i>MOV<\/i><\/div>\n<\/div>\n<p>В моей жизни последовательно сменяли друг друга три ассемблера. Первый, для компьютера «Радио-86РК», я выучил по комментариям к ассемблерному коду в журнале «Радио» — другой литературы не было, а до моего знакомства с интернетом оставалось несколько лет. Потом были последовательно ассемблеры для «Спектрума» и интеловских процессоров.<\/p>\n<p>В те времена я думал, что всю жизнь буду программировать на ассемблере, на деле же последнюю программу на нём написал в начале 2000-х. Сейчас на чистом ассемблере мало кто пишет, а тем временем в этом мире иногда происходят интересные вещи.<\/p>\n<p>В ассемблере есть такая команда — <i>MOV<\/i> (в некоторых ассемблерах — <i>LD<\/i>), записывает содержимое одного аргумента в другой.  Сейчас набор комманд разросся, аргументом может быть почти что угодно — регистр, ячейка в памяти, сумма некоторого числа, одного регистра и другого, умноженного на число, но по сути это всегда присваивание.<\/p>\n<p>И вот оказалось, что эта команда — полная по Тьюрингу. Звучит невероятно, но это так. Некие ребята заморочились и сделали компилятор, который компилирует любую программу на Си в последовательность команд <i>MOV<\/i>. Причём им даже <a href=\"https:\/\/github.com\/xoreaxeaxeax\/movfuscator\/tree\/master\/validation\/doom\">ДУМ удалось скомпилировать<\/a>, правда один кадр рисуется семь часов. Кстати, такая программа неуязвима для горюшка века — Мелтдауна и Спектра.<\/p>\n<p>Есть <a href=\"https:\/\/github.com\/xoreaxeaxeax\/movfuscator\/blob\/master\/slides\/domas_2015_the_movfuscator.pdf\">небольшая (на 156 страниц и 90% воды) презентация<\/a>, достаточно популярно объясняющая как этого удалось достичь, но для её чтения надо знать ассемблер, поэтому я позволю себе раскрыть детали трансляции двух инструкций, чтобы пояснить принцип для тех, кто ассемблера не знает или ленится причитать.<\/p>\n<p>Например, сравнение двух чисел делается при помощи следующего псеводокода:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">mov [X], 0\nmov [Y], 1\nmov R, [X]<\/code><\/pre><p>У нас есть два числа в аргументах «<i>X<\/i>» и «<i>Y<\/i>», результат сравнения которых попадает в «<i>R<\/i>» — там будет ноль, если числа не равны и единица в противном случае. Как же это работает?<\/p>\n<p>Первой командой ноль записывается в ячейку по адресу «<i>X<\/i>». Это ассемблер, у нас тут всё — число, остальное — человеческие интерператации, поэтому записанное в «<i>X<\/i>» мы используем как адрес. Второй командой единица записывается в ячейку по адресу «<i>Y<\/i>». Третьей командой мы читаем значение по адресу «<i>X<\/i>» и если значения в «<i>X<\/i>» и «<i>Y<\/i>» совпадают, то ноль перетрётся единицей (и она попадёт в <i>R<\/i>), если нет, то в ячейке по адресу «<i>X<\/i>» ноль останется (который попадёт в <i>R<\/i>).<\/p>\n<p>Несложно. Но из кода выше непонятно как получаются другие необходимые инструкции. Увы, но какого-то единого принципа для всего нет, авторам для каждого набора приходилось придумывать что-то новое. Думаю интересно будет взглянуть на реализацию чего-нибудь ещё.<\/p>\n<p>Возьмём, например, логическое «ИЛИ» («OR»), тут чуточку сложнее:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">OR_ADDRS: dd OR_0, OR_1\nOR_0: dd 0, 1\nOR_1: dd 1, 1\n; …\nmov eax, X\nmov edx, [OR_ADDRS + eax]\nmov eax, Y\nmov eax, [eax + edx]\nmov R, eax<\/code><\/pre><p>Во всех логических операциях ребята используют записанные заранее неизменяемые массивы значений.<\/p>\n<p>Что тут происходит? В регистр (переменную, с которыми работает процессор) «<i>eax<\/i>» записывается значение «<i>X<\/i>» (возможные входные значения у нас тут — ноль или единица, численное представление булевых значений).<\/p>\n<p>Далее в регистр «<i>edx<\/i>» записывается число из адреса, который является суммой адреса массива <i>OR_ADDRS<\/i> и содержимого регистра <i>eax<\/i>. Таким образом в <i>eax<\/i> попадёт <i>OR_0<\/i> или <i>OR_1<\/i>, в зависимости от того былы записаны в <i>eax<\/i> ноль или единица. Эти значения — тоже числа и являются адресами двух других массивов из двух элементов.<\/p>\n<p>Далее в <i>eax<\/i> мы записываем аргумент <i>Y<\/i>, его значение складывается с адресом полученным на предыдущем шаге и из получившегося адреса мы читаем записанное там значение. В переводе на ПХП получается следующее:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">function mov_or(int $X, int $Y): int\n{\n    define(&#039;OR_0&#039;, [0, 1]);\n    define(&#039;OR_1&#039;, [1, 1]);\n\n    define(&#039;OR_ADDRS&#039;, [OR_0, OR_1]);\n\n    $R = OR_ADDRS[$X][$Y];\n\n    return $R;\n}<\/code><\/pre><p>Кстати, интересно, что у знаменитого дисассемблера «<a href=\"https:\/\/ru.wikipedia.org\/wiki\/IDA\">ИДА<\/a>» от полученной таким образом программы крепко уносит крышу — при попытке отладки диссасемблер не видит никаких ветвлений и падает на анализе кода. Получился бы неплохой метод защиты от анализа, если бы не производительность.<\/p>\n",
            "date_published": "2018-01-27T15:19:00+05:00",
            "date_modified": "2025-06-10T23:55:11+05:00",
            "tags": [
                "php",
                "ассемблер",
                "программирование"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Sat, 27 Jan 2018 15:19:00 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "136262",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        },
        {
            "id": "124596",
            "url": "https:\/\/bolknote.ru\/all\/3880\/",
            "title": "Пацакку",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"https:\/\/bolknote.ru\/pictures\/2013.02.22.png\" width=\"644\" height=\"257\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Пацак.Ку<\/div>\n<\/div>\n<p>Далёкие дни, Университет, вирус «<a href=\"https:\/\/web.archive.org\/web\/20130302102522\/http:\/\/www.securelist.com\/ru\/descriptions\/68323\/Virus.DOS.Pacakku.1120\">Пацакку<\/a>». С большим трудом припоминаю, что это был простой, написанный на Ассемблере вирус для ДОСа, который в день моего рождения выдвигал шторку сидирома (если он есть) и печатал на принтере (кажется; или в корень клал файл, или то и другое, не помню) фразу «в обществе где нет цветовой дифференциации штанов, нет и цели», цитату из любимого моего фильма «<a href=\"http:\/\/ru.wikipedia.org\/wiki\/Кин-дза-дза!\">Кин-дза-дза!<\/a>». Судя по названию, данному в Лаборатории Касперского, там где-то были фразы «пацак» и «ку», но я помню это как-то туманно.<\/p>\n<p>Кстати, в Университетe самодельных вирусов хватало. Особенно мне запомнился вирус «TV» (был так назван моим тогдашним другом А.Г. из-за того, что проверял своё содержимое в памяти по этим двум байтам, записанным по определённому адресу), который доводил студентов до истерик — он менял местами действие клавиш «<i>Esc<\/i>» и «<i>Enter<\/i>». Когда программа спрашивала «Сохранить?» на выходе, студент жал «энтер», на самом деле нажимался «эскейп» и вся работа за день терялась.<\/p>\n<p>Тогда же я придумал свой первый антивирус, который назвал просто «Вакцина» (файл запуска — «vac.com» или «vac.exe», не помню точно размер), «вакциной» он назывался вполне заслуженно, так как именно <i>вакцинировал<\/i> компьютеры. Это была одна из <a href=\"https:\/\/bolknote.ru\/all\/1899\/\">двух утилит<\/a>, которые сильно упрощали мою тогда лаборантскую жизнь. Принцип действия был следующий.<\/p>\n<p>Большинство вирусов того времени ставили какой-то маркер в памяти компьютера, чтобы определить заражали они этот компьютер уже или нет. Чаще всего перехватывался вектор прерывания <a href=\"http:\/\/en.wikipedia.org\/wiki\/INT_21h\">21h<\/a> и создавалась какая-нибудь функция, досом не используемая, но были и другие варианты (например, тот же «TV»). При появлении нового вируса я его анализировал, определял эту функцию и добавлял её в свою «вакцину».<\/p>\n<p>Вирус, запущенный на таком компьютере, думал, что он тут уже есть и не заражал машину. Кроме того, моя вакцина предупреждала о попытке заражения вируса при вызове этих самых функций. У вакцины был ещё встроенный монитор перехвата вектора <a href=\"http:\/\/en.wikipedia.org\/wiki\/INT_13h\">13h<\/a>, который использовали более серьёзные функции, принцип был подсказан тем же А.Г. — если обработчик 13h, при запуске моей программы, был не в БИОСе (а адреса его были известны), так же поднималась тревога.<\/p>\n<p>Если честно, я смутно помню, что принцип был чуть хитрее, но в чём была тонкость, не помню. Если вспомню, расскажу.<\/p>\n<p>Позднее я придумал и начал писать конфигуратор на Турбо Паскале, но так и не дописал, терпение кончилось на интерфейсе.<\/p>\n<p>У моего антивируса было несколько достоинств: он ловил все тогдашние студенческие поделки, ходившие в нашем Университете, включая мои собственные, ну и просто популярные вирусы того времени, он был бесплатен и быстро обновлялся, был крошечным, не жрал ресурсы компьютера (что было особенно актуально в нашем компьютерном классе на <i>IBM XT<\/i>, там процессоры были 8086 и даже «Нортон» работал медленно) и <i>предотвращал заражение<\/i>, а не просто поднимал тревогу, когда вирус уже внедрился, т. е. лечить такой компьютер было не нужно, что было очень актуально в случае печально известного вируса «<a href=\"http:\/\/ru.wikipedia.org\/wiki\/CIH\">Чернобыль<\/a>», эпидемию которого в своих классах я быстро пресёк на корню.<\/p>\n<p>И раз уж у меня сегодня рубрика «воспоминания в утренней пробке», расскажу как лечили порчу вирусом «Чернобылем» БИОСа. Лечил всё тот же А.Г. Поражённый компьютер вскрывался, в него ставился такой же чип БИОСа с другого компьютера (напоминаю, дело в компьютерных классах было, когда я лаборантом работал в Университете, там было много однотипных машин), компьютер загружался, обычной программой для прошивки БИОСа с чипа списывалось его содержимое (или оно, как вариант, бралось из интернета), потом <i>наживую<\/i> чип доставался и вставлялся испорченный, после чего пациент перепрошивался правильной прошивкой.<\/p>\n<p>Кстати, мне «повезло» учиться и лаборантить в классах где стоял весь зоопарк: 8086, 80286, 80386 и даже бездисковые станции, которые грузились по сети, настоящие (тормозные) тонкие клиенты с утилитами <a href=\"http:\/\/ru.wikipedia.org\/wiki\/Novell\">Новелла<\/a>.<\/p>\n",
            "date_published": "2013-02-22T08:53:00+05:00",
            "date_modified": "2025-01-06T18:26:31+05:00",
            "tags": [
                "ассемблер"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Fri, 22 Feb 2013 08:53:00 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "124596",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        }
    ],
    "_e2_version": 4079,
    "_e2_ua_string": "Aegea 11.0 (v4079e)"
}