Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
z80-sans — Z80 명령어를 디스어셈블하는 OpenType 글꼴 | Kitploit
도구/GitHubGitHub/nevesnunes/z80-sans
Reverse EngineeringFuzzingCTFHardware SecurityBinary AnalysisLearning & Education
GitHubnevesnunes/z80-sans

z80-sans

Z80 명령어를 디스어셈블하는 OpenType 글꼴

저장소 보기
50631년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Z80 Sans

당신이 가장 좋아하는 디스어셈블러는 무엇인가요? 저는 폰트입니다:

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

이 폰트는 OpenType의 Glyph Substitution Table (GSUB) 및 Glyph Positioning Table (GPOS)를 광범위하게 사용하여 16진수 소문자 시퀀스를 디스어셈블된 Z80 명령어로 변환합니다.

테스트해보고 싶다면 ./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개의 조합을 가질 수 있음을 의미합니다;
  • 순서가 다른 피연산자: 예를 들어 레지스터와 오프셋이 한 순서로 16진수 바이트에 인코딩되지만 다른 순서로 디스어셈블되어 백트래킹/룩어헤드 규칙을 복잡하게 만듭니다;
  • 리틀 엔디언 주소: 최하위 바이트의 문자를 최상위 바이트보다 먼저 렌더링해야 합니다;
  • 부호 있는 오프셋: 범위 0x80..0xff 내의 모든 오프셋은 음의 2의 보수 숫자로 렌더링되어야 합니다;

이 모든 것은 프로그래매틱 솔루션을 필요로 합니다. fontcustom과 ImageMagick이 글리프 생성을 처리하지만, 룩업 규칙을 작성하는 편리한 방법은 .fea 형식인 것 같지만, fonttools의 .ttx 형식(기본적으로 xml)과 통합하는 방법을 찾지 못했습니다. 저는 Noto Sans Mono의 .ttx를 직접 편집하는 최소 공통 분모 접근 방식을 취했습니다(글리프 모양은 Droid Sans Mono에서 계산되지만, FontForge에 패치를 적용할 때 시작한 것이기 때문입니다).

재귀 하향 파서를 사용하여 가능한 모든 글리프를 생성하며, 이는 인코딩에서 표현식을 평가하는 데 도움을 줍니다(예: SET b,(IX+o)는 비트와 변위를 사용하며 DD CB o C6+8*b로 인코딩됨). 그런 다음 이러한 인코딩을 피연산자가 가질 수 있는 모든 가능한 값으로 확장한 후, 확장된 명령어를 렌더링하는 데 필요한 각 디스어셈블 글리프에 하나 이상의 16진수 바이트를 연결합니다.

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 ISA의 흥미로운 속성은 비트와 레지스터가 최대 8가지 변형을 가지며, 이러한 순서가 다른 경우는 오프셋과 해당 특정 피연산자 중 하나만 관련된다는 것입니다. 따라서 비트나 레지스터를 리터럴로 인코딩할 수 있습니다. 충분한 룩어헤드를 사용하면 마지막 16진수 바이트까지 일치시키고 각 경우에 대한 전용 룩업을 생성할 수 있습니다. 마지막 리터럴은 접미사 글리프와 일치하는 합자를 생성하여 줄일 수 있습니다. 최종 결과는 이러한 경우에 대해 수십 개의 추가 룩업이 생성되었습니다(이는 그룹화하여 이 숫자를 줄일 수 있음).

알려진 문제

  • 모든 원래 명령어 세트는 디스어셈블되어야 하지만, 일부 명령어에 사소한 결함이 있습니다:
    • 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 라이선스에 따라 배포됩니다;
  • Noto Sans Mono는 Open Font 라이선스에 따라 배포됩니다;
  • ./resources/instructions.json은 GNU Lesser General Public License 버전 3에 따라 배포됩니다;
  • 기타 파일은 MIT 라이선스에 따라 배포됩니다;
도구 다운로드