Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
z80-sans — OpenType шрифт, который дизассемблирует инструкции Z80 | Kitploit
Инструменты/GitHubGitHub/nevesnunes/z80-sans
Обратная инженерияФаззингCTFАппаратная БезопасностьАнализ Бинарных ФайловОбучение и Образование
GitHubnevesnunes/z80-sans

z80-sans

OpenType шрифт, который дизассемблирует инструкции Z80

Репозиторий
50631 год назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Z80 Sans

Какой у вас любимый дизассемблер? Мой — шрифт:

https://github.com/user-attachments/assets/bb6ceb18-c2fd-40a9-be4f-202321a214d9

Этот шрифт преобразует последовательности шестнадцатеричных символов нижнего регистра в дизассемблированные инструкции Z80, используя широкие возможности Glyph Substitution Table (GSUB) и Glyph Positioning Table (GPOS).

Если вы хотите просто попробовать, копия доступна по пути ./test/z80-sans.ttf.

Установка

Протестировано на Debian GNU/Linux 12. Обратите внимание, что эта версия Debian поставляется с Ruby версии 3, в то время как fontcustom был написан для Ruby версии 2 и несовместим с более поздними версиями (например, синтаксические ошибки). Установка Ruby также требует совместимой версии OpenSSL. Поэтому RVM можно использовать для управления как Ruby, так и локальной установкой OpenSSL.

root@kitploit:~
apt install imagemagick potrace
pip install fonttools

git submodule update --init --recursive

# fontforge
(
cd ./modules/fontforge/
git checkout 4f4907d9541857b135bd0b361099e778325b4e28
git apply ../../resources/fontforge.diff
mkdir -p build
cd build
cmake -GNinja ..
ninja
ninja install
)

# woff2
(
cd ./modules/woff2/
make clean all
)

# fontcustom
rvm use 2.7
rvm pkg install openssl
rvm install 2.4 --with-openssl-dir=$HOME/.rvm/usr
gem update --system 3.3.22
(
export PATH=$PWD/modules/woff2/build:$PATH
cd ./modules/fontcustom/
git apply ../../resources/fontcustom.diff
gem build fontcustom.gemspec
gem install ./fontcustom-2.0.0.gem
)

Запуск

root@kitploit:~
cp ./resources/droid-sans-mono.ttf /tmp/base.ttf
./gen.py ./resources/instructions.json

Файл шрифта .ttf копируется в ~/.local/share/fonts/, который используется, например, LibreOffice.

Дизайн

По сравнению с другими проклятыми шрифтами, Z80 Sans имеет следующие сложности:

  • Несколько символов для отображения: было бы непрактично вручную определять все правила замены для каждого символа, поэтому мы можем создавать глифы, объединяющие несколько литералов (например, мнемоники типа CALL), однако это также связано со следующим пунктом...
  • Множество комбинаций: напомним, что некоторые инструкции Z80 могут принимать 16-битные адреса и регистры в качестве операндов, что означает, что одна инструкция может иметь до 65536 * 7 = 458752 возможных комбинаций;
  • Операнды не по порядку: например, регистр и смещение могут быть закодированы в шестнадцатеричные байты в одном порядке, но дизассемблированы в другом, что усложняет правила обратного отслеживания/опережающего просмотра;
  • Little-endian адреса: символы для младшего байта должны отображаться перед старшим байтом;
  • Знаковые смещения: все смещения в диапазоне 0x80..0xff должны отображаться как отрицательное число в дополнительном коде;

Всё это требует программного решения. В то время как fontcustom и ImageMagick занимаются генерацией глифов, удобным способом написания правил подстановки, по-видимому, является формат .fea, но я не нашёл способа интегрировать его с форматом .ttx от fonttools (который по сути является xml). Я пошёл по пути наименьшего общего знаменателя, напрямую редактируя .ttx от Noto Sans Mono (хотя формы глифов вычислены из Droid Sans Mono, так как именно с него я начинал, патча FontForge).

Для генерации всех возможных глифов используется рекурсивный нисходящий парсер, что помогает вычислять выражения в кодировках (например, SET b,(IX+o) принимает бит и смещение, закодированные как выражение DD CB o C6+8*b). Затем эти кодировки расширялись до всех возможных значений, которые могут принимать операнды, после чего каждому глифу дизассемблирования, необходимому для отображения расширенной инструкции, сопоставлялся один или несколько шестнадцатеричных байтов.

Есть хорошие источники по функциям OpenType, но они написаны на высоком уровне или в формате .fea(?):

  • OpenType Feature File Specification | afdko
  • GSUB — Glyph Substitution Table (OpenType 1.9.1) - Typography | Microsoft Learn
  • Fonts and Layout for Global Scripts
  • GitHub - brew/opentype-feature-intro: An introduction to OpenType features for type designers.
  • Features, part 3: advanced contextual alternates | Glyphs
  • Opentype subtitution many by many (different number) - Glyphs Forum

Никогда не было ясно, как перевести их в .ttx, поэтому в итоге я просто конвертировал всё семейство Noto Sans и использовал старый добрый метод перебора — «обучение на примерах». Это даже веселее, чем звучит, благодаря множеству молчаливых ошибок при конвертации из .ttx в .ttf, когда подстановки не срабатывают из-за некоторых предположений, не проверяемых fonttools (например, определения классов для замен в контекстных цепочках должны содержать хотя бы один охватывающий глиф с class value="1").

Практически все сложности были решены с помощью правил контекстной цепочки. Для обработки адресов каждый полубайт в диапазоне 0..f был закодирован отдельными глифами, с использованием пробельных символов для создания множественных подстановок по одному символу за раз. Смещения также имеют дополнительные знаковые варианты. Это даёт нам в общей сложности (4 + 2) * 16 глифов для чисел. Этого уже было достаточно, чтобы размер файла шрифта оставался в пределах лимита в 65536 глифов.

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

root@kitploit:~
["SET b,(IX+o)", "DD CB o C6+8*b"],
["SET b,(IY+o)", "FD CB o C6+8*b"],

Покрывается теми же правилами подстановки, что и:

root@kitploit:~
["SRA (IX+o)", "DD CB o 2E"],
["SRA (IY+o)", "FD CB o 2E"],
["SRL (IX+o)", "DD CB o 3E"],
["SRL (IY+o)", "FD CB o 3E"],

Интересное свойство архитектуры Z80 в том, что биты и регистры имеют до 8 вариаций, и эти случаи нарушения порядка включают только смещения и один из этих конкретных операндов. Поэтому мы можем кодировать биты или регистры как литералы. С достаточным опережающим просмотром мы можем сопоставить до последнего шестнадцатеричного байта и создать специальные подстановки для каждого случая. Последние литералы можно сократить, создав лигатуру, совпадающую с суффиксным глифом. В итоге для этих случаев было создано несколько десятков дополнительных подстановок (которые, вероятно, можно сгруппировать, чтобы уменьшить их количество).

Известные проблемы

  • Хотя весь исходный набор инструкций должен дизассемблироваться, некоторые инструкции имеют мелкие глюки:
    • LD (IX+o),r отображается как LD (IX+o r),;
    • SET b,(IX+o) отображается как SET b,(IX+o));
  • Код уровня «CTF» 😅;

Планы на будущее

FontForge поддерживает скриптовую модификацию функций с помощью команд GenerateFeatureFile() и MergeFeature() (кратко рассмотрено в The Terrible Secret of OpenType Glyph Substitution - Ansuz - mskala's home page). Я узнал об этом только после реализации на основе .ttx, но это могло бы избежать возни с файлами .ttx.

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

  • fuglede/llama.ttf: A font for writing tiny stories;
  • hsfzxjy/handwriter.ttf: Handwriting synthesis with Harfbuzz WASM.;

Благодарности

  • Droid Sans Mono и Noto Sans Mono были использованы как основа для Z80 Sans;
  • ./resources/instructions.json был адаптирован из maziac/z80-instruction-set;
  • Вдохновение для подстановок GSUB:
    • Font with Built-In Syntax Highlighting;
    • Fontemon, в частности «How I did it»;
    • Addition Font;
    • Sans Bullshit Sans;

Лицензия

  • Droid Sans Mono распространяется под Apache Licence;
  • Noto Sans Mono распространяется под Open Font License;
  • ./resources/instructions.json распространяется под GNU Lesser General Public License version 3;
  • Остальные файлы распространяются под MIT License;
Скачать инструмент