Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
z80-sans — Police OpenType qui désassemble les instructions Z80 | Kitploit
Outils/GitHubGitHub/nevesnunes/z80-sans
Rétro-ingénierieFuzzingCTFSécurité MatérielleAnalyse de BinairesApprentissage et Éducation
GitHubnevesnunes/z80-sans

z80-sans

Police OpenType qui désassemble les instructions Z80

Voir le dépôt
50633il y a 2 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Z80 Sans

Quel est votre désassembleur préféré ? Le mien est une police :

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

Cette police convertit des séquences de caractères hexadécimaux minuscules en instructions Z80 désassemblées, en faisant un usage intensif de la Table de substitution de glyphes (GSUB) et de la Table de positionnement de glyphes (GPOS) d'OpenType.

Si vous souhaitez simplement l'essayer, une copie est disponible sous ./test/z80-sans.ttf.

Installation

Testé sur Debian GNU/Linux 12. Notez que cette version de Debian est livrée avec Ruby version 3, alors que fontcustom a été écrit pour Ruby version 2 et est incompatible avec les versions ultérieures (p. ex., erreurs de syntaxe). Une installation de Ruby nécessite également une version compatible d'OpenSSL. Par conséquent, RVM peut être utilisé pour gérer à la fois Ruby et une installation locale d'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
)

Exécution

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

Le fichier de police .ttf est copié dans ~/.local/share/fonts/, qui est utilisé par exemple par LibreOffice.

Conception

Comparée à d'autres polices maudites, Z80 Sans présente les défis suivants :

  • Plusieurs caractères à rendre : il serait impractical de définir manuellement caractère par caractère toutes les règles de substitution pour le rendu, donc nous pouvons créer des glyphes qui combinent plusieurs littéraux (par exemple, des mnémoniques comme CALL), mais cela nous amène au point suivant...
  • Combinaisons multiples : rappelons que certaines instructions Z80 peuvent prendre des adresses 16 bits et des registres comme opérandes, ce qui signifie qu'une seule instruction peut avoir jusqu'à 65536 * 7 = 458752 combinaisons possibles ;
  • Opérandes dans le désordre : par exemple, les registres et les décalages peuvent être encodés en octets hexadécimaux dans un ordre, mais désassemblés dans un autre ordre, ce qui complique les règles de backtracking/lookahead ;
  • Adresses little-endian : les caractères pour l'octet de poids faible doivent être rendus avant l'octet de poids fort ;
  • Décalages signés : tous les décalages dans la plage 0x80..0xff doivent être rendus comme un nombre négatif en complément à deux ;

Tout cela invite à une solution programmatique. Alors que fontcustom et ImageMagick se chargent de générer les glyphes, il semble qu'une manière pratique d'écrire des règles de recherche soit le format .fea, mais je n'ai pas trouvé de moyen de l'intégrer au format .ttx de fonttools (qui est essentiellement du xml). J'ai adopté l'approche du plus petit dénominateur commun en éditant directement le .ttx de Noto Sans Mono (bien que les formes des glyphes soient calculées à partir de Droid Sans Mono, car c'est avec cela que j'ai commencé en patchant FontForge).

Un analyseur par descente récursive est utilisé pour générer tous les glyphes possibles, ce qui aide à évaluer les expressions dans les encodages (par exemple, SET b,(IX+o) prend un bit et un déplacement, encodé comme expression DD CB o C6+8*b). Ces encodages ont ensuite été étendus à toutes les valeurs possibles que les opérandes peuvent prendre, avant d'associer finalement 1 ou plusieurs octets hexadécimaux à chaque glyphe de désassemblage nécessaire pour rendre une instruction étendue.

Voici quelques bonnes références pour les fonctionnalités OpenType, mais elles sont rédigées à un niveau élevé ou au format .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 : Une introduction aux fonctionnalités OpenType pour les concepteurs de polices.
  • Fonctionnalités, partie 3 : alternatives contextuelles avancées | Glyphs
  • Substitution OpenType plusieurs par plusieurs (nombre différent) - Glyphs Forum

Il n'est jamais très clair comment les traduire en .ttx, donc au final j'ai simplement converti toute la famille Noto Sans et utilisé la bonne vieille approche de force brute de « l'apprentissage par l'exemple ». C'est encore plus amusant que cela n'en a l'air, grâce à de nombreux échecs silencieux lors de la conversion de .ttx en .ttf, où les recherches ne correspondent pas en raison de certaines hypothèses non validées par fonttools (par exemple, les définitions de classes pour les substitutions contextuelles en chaîne doivent avoir au moins un glyphe de couverture avec une valeur de classe="1").

La plupart des défis ont été résolus avec des règles de chaînage contextuel. Pour gérer les adresses, chaque quartet dans la plage 0..f a été encodé avec des glyphes distincts, avec des caractères d'espacement utilisés pour créer plusieurs substitutions, un caractère à la fois. Les déplacements ont également des variantes signées supplémentaires. Cela nous donne un total de (4 + 2) * 16 glyphes pour les nombres. Cela était déjà suffisant pour maintenir le fichier de police sous la limite de 65536 glyphes.

La pire partie était bien sûr les opérandes dans le désordre. Cependant, en raison du nombre limité de variations qu'ils ont dans les instructions, ils pouvaient être couverts par la même stratégie que les instructions avec des préfixes encodés de manière ambiguë, par exemple :

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

Est couvert par les mêmes règles de recherche que :

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"],

Une propriété intéressante du jeu d'instructions Z80 est que les bits et les registres ont jusqu'à 8 variations, et ces cas de désordre n'impliquent que des décalages et un de ces opérandes spécifiques. Par conséquent, nous pouvons encoder des bits ou des registres comme des littéraux. Avec suffisamment de lookaheads, nous pouvons faire correspondre jusqu'au dernier octet hexadécimal et créer des recherches dédiées pour chaque cas. Les derniers littéraux peuvent être réduits en générant une ligature qui correspond au glyphe suffixe. Le résultat final a été des dizaines de recherches supplémentaires générées pour ces cas (qui peuvent probablement être regroupées pour réduire ce nombre).

Problèmes connus

  • Bien que l'ensemble des instructions originales devrait être désassemblé, certaines instructions présentent des problèmes mineurs :
    • LD (IX+o),r est rendu comme LD (IX+o r), ;
    • SET b,(IX+o) est rendu comme SET b,(IX+o)) ;
  • Code de « qualité CTF » 😅 ;

Travaux futurs

FontForge prend en charge la modification scriptable des fonctionnalités à l'aide des commandes GenerateFeatureFile() et MergeFeature() (brièvement couvert dans The Terrible Secret of OpenType Glyph Substitution - Ansuz - mskala's home page). Je n'en ai eu connaissance qu'après avoir réalisé l'implémentation basée sur .ttx, mais cela aurait potentiellement évité de devoir toucher aux fichiers .ttx.

Pour des jeux d'instructions plus complexes, une approche alternative qui semble avoir moins de contraintes est d'utiliser des shapeurs de police. Quelques exemples :

  • fuglede/llama.ttf: Une police pour écrire de petites histoires ;
  • hsfzxjy/handwriter.ttf: Synthèse d'écriture manuscrite avec Harfbuzz WASM ;

Crédits

  • Droid Sans Mono et Noto Sans Mono ont été utilisés comme base pour Z80 Sans ;
  • ./resources/instructions.json a été adapté depuis maziac/z80-instruction-set ;
  • Inspiration pour les substitutions GSUB :
    • Police avec coloration syntaxique intégrée ;
    • Fontemon, en particulier "How I did it" ;
    • Addition Font ;
    • Sans Bullshit Sans ;

Licence

  • Droid Sans Mono est sous Licence Apache ;
  • Noto Sans Mono est sous Open Font License ;
  • ./resources/instructions.json est sous GNU Lesser General Public License version 3 ;
  • Les autres fichiers sont sous Licence MIT ;
Télécharger l’outil