Программирование в машинных кодах
decu emu
Я остался под впечатлением от прочитанной первой или второй главы про хакерство в книге Криса Касперского «Техника отладки программ без исходных текстов».
Хоть я и знал о том, что раньше писали в машинных кодах, но когда Крис так подал интересно материал, что я замотивировался сделать небольшой компьютер эмулятор, который бы позволял обрабатывать мой машинный код. Тут дело проще чем кажется, так как я решил взять всего 16 инструкций для этого дела. Плюс ко всему я как-то давно мечтал сделать hex редактор на ncurses, но каждый раз не было смысла его делать просто так, а теперь сделал.
Инструкция храниться в старшем полубайте, вот их битовые обозначения.
* 0000 ADD - Команда сложения
* 0001 SUB - вычитание
* 0010 AND - битовое И
* 0011 OR - битовое ИЛИ
* 0100 XOR - ксор регистров или числа
* 0101 SHL - сдвиг влево
* 0110 SHR - сдвиг вправо
* 0111 LD - запись в регистр аккумулятор
* 1000 IN - входящие данные по порту
* 1001 NOP - нет команды
* 1010 OUT - исходящие данные по порту
* 1011 PUSH - пуш байта
* 1100 POP - поп байта
* 1101 TEST - вычитание без записи в регистр A
* 1110 JC - условный и безусловный переход
* 1111 HALT - останова программы
Эти команды формируют старший полубайт опкода. Младший полубайт опкода указывает на регистры или регистр число.
флаги
Z - флаг нуля, то-есть если делается тест, вычитается значение, если результат равно нулю, то устанавливается этот флаг
S - флаг отрицательного числа, если в результате стало равно меньше нуля, или то-есть установлен 0x80 бит.
C - флаг переполнения
Условия у переходов
0000 JC
0001 JS
0010 JZ
0011 JMP
младший полубайт
* A - 0b00
* X - 0b01
* Y - 0b10
* число/адрес - 0b11
адреса
0x00 in, out - таймер, можно задать время обновления в миллисекундах
0x01 in, out - экран, 22x10. Значение заноситься из регистров. В регистре A находится символ, в регистре X координата по x, в регистре Y координата по y. Например [IN 0x01]; [1000 0000 0000 0001]; 0x80 0x01
0x02 out - чтение в регистр A значения стрелок. Четыре стороны, 0b1000 - это только влево. 0b1100 - это влево и вверх. Как в vim [jkl;]
0x03 out - чтение в регистр A нажатой клавиши, всего 4 клавиши.
Я написал этот эмулятор за одну ночь и один вечер. Когда решил начать писать код, я немного испугался, ведь я не помню ни одной инструкции. Тогда я открыл текствый файл с обозначениями всей архитектуры и начал писать код. Мне удалось вывести одну букву в видео память. Далее хотел вывести строку, но это пока что оказалось для меня более сложной задачей.
Как можно работать с памятью. Например рассмотрим инструкцию LD, которая загружает в регистр какое-то число. Регистр может быть регистром данных или регистром адресом.
LD инструкция это 0111 — то-есть 0×7x. Например хотим загрузить в регистр A число 0×14, будет так. LD 0111; A 00; число 11; 0×14 0001 0100; Получается 0×73 0×14.
Команд мало и их можно запомнить, плюс потренировать свою память.
В этом эмуляторе есть стек, который начинается с адреса 0xffff, мы можем контроллировать стек только с помощью PUSH и POP. С помощью LD мы можем загружать только байт, и адрес может быть только байт (хотя можно сделать и два байта). Пока адрес для LD есть как один байт, поэтому все переменные нужно хранить в первых 256 байтах.
Цель проекта почувствовать что такое программировать в машинных кодах на упрощенной архитектуре. Я бы хотел даже электронное устройство такое иметь, где можно было бы ходить с ним и в память вбивать опкоды, чтобы на экране потом что-нибудь выводилось.
Такое я смог написать только под вдохновением, когда как разработка моего эмулятора i386 простаивает.
В любом случае, можно теперь почувствовать ту боль или то восхищение, когда код писался с помощью чисел.
Вот ссылка на проект, если кому-то тоже интересно почувствовать как это было, хотя бы примерно, в те годы.
https://github.com/xverizex/decu_emu
Если интерес не пропадет, то сделаю сборку для android или аврора.
Еще в планах сделать пошаговый отладчик.
Заканчивая статью, хочу сказать, когда речи прекрасны, они мотивируют на подвиги, и даже, когда я занялся реверс инжинирингом, то всё-же уделил пару дней на написания эмулятора, потому что в душе я не только исследователь, но и творец!