
바이너리 시각화 및 트라이지 도구 — 단일 공유 주소 공간 모델 위에서 엔트로피, 바이트 클래스 및 힐베르트 곡선, 닷 플롯과 제어 흐름 그래프를 제공합니다.
바이너리 시각화 및 트라이지(triage) 도구: 단일 공유 주소 공간 모델 위에서 상호 연결된 대화형 뷰(엔트로피, 히스토그램, 이미지/닷플롯 표면, 제어 흐름 그래프)를 제공합니다.
pipx install binviz && binviz serve
파일을 열면 모든 뷰가 동일한 주소 공간을 바라봅니다. 한 뷰에서 범위를 선택하면 나머지 뷰도 따라옵니다 — 핵심은 "이 영역이 무엇인가"라는 질문에 여러 방식으로 동시에 답하는 것입니다.
binviz model은 LIEF를 통해 ELF/PE/Mach-O를 파싱하여 영역, 심볼, 오프셋↔가상 주소 매핑을 생성하고, 갭과 오버레이를 구체화합니다. 잘못된 입력은 실패 대신 원시 모델로 폴백합니다.binviz triage는 파일이 어떻게 보이는지와 그 이유를 말해줍니다. UI에서 각 발견 사항은 해당 바이트로 클릭하여 이동할 수 있습니다.UI는 동일한 선택 영역 위에 Overview, Bytes, Patterns, Code, All의 5개 워크스페이스로 구성됩니다. 정적 분석만 수행합니다: 샘플은 파싱만 되며 실행되지 않습니다.




UI가 그리는 것과 동일한 코드로 CLI에서 직접 렌더링됩니다 — python docs/make_plates.py로 재생성할 수 있습니다.
| 올바른 행 스트라이드 | 잘못된 행 스트라이드 |
|---|---|
![]() | ![]() |
동일한 바이트, 숫자 하나만 다릅니다. 이것이 스트라이드 추천 기능이 존재하는 이유입니다: 잘못된 행 스트라이드는 사진을 대각선 노이즈로 만들어 "사진이 없다"고 결론 내리게 합니다.
ARCHITECTURE.md는 구성 방식을 설명합니다: 무엇이 포함되는지, 모든 표면이 상속하는 브랜딩, 새 화면이 따라야 하는 규칙, 그리고 의도적인 한계. SECURITY.md는 보안 태세를 다룹니다.
python -m venv .venv
# -c는 스위트가 검증된 정확한 버전을 고정합니다. pyproject.toml은 범위를
# 게시하므로, 이 옵션 없이는 오늘 해석되는 버전이 사용됩니다.
.venv/Scripts/pip install -e ".[dev]" -c constraints-dev.txt # POSIX: .venv/bin/pip
# 실제 데이터 코퍼스 구축 (ziglang pip 패키지의 zig cc 사용;
# UPX가 PATH, $UPX에 있거나 corpus/tools/upx-*/에 압축 해제되어 있어야 함)
make -C corpus # 또는: python corpus/build.py
# 임계값은 하드코딩되지 않고 측정됩니다 (ARCHITECTURE.md §2.1 참조)
python corpus/calibrate.py # corpus/calibration.json 작성
pytest # 기능 테스트 스위트
pytest -m perf -s # 100 MB 성능 목표
binviz probe corpus/out/hello_O2
binviz model corpus/out/hello_upx
binviz signal corpus/out/hello_upx --name entropy_4096 --png out.png
binviz hist corpus/out/ramp16.bin --n 2 --dtype u16le --png bigram.png
# 표면: -p는 표면 매개변수를 전달합니다
binviz surface corpus/out/hello_static --name hilbert -p mode=byteclass --png h.png
binviz surface corpus/out/rgb_raw.bin --name image -p mode=rgb8 -p width=320 --png i.png
binviz surface corpus/out/repeats.bin --name dotplot -p mode=exact --png d.png
binviz stride corpus/out/bayer_raw.bin --mode bayer_RGGB_RGB_12
# 코드
binviz disasm corpus/out/hello_O2 --limit 20
binviz functions corpus/out/hello_static --sort size
binviz cfg corpus/out/hello_O2 --func main --dot main.dot
# 판정과 그 이유
binviz triage corpus/out/hello_upx
binviz serve # 127.0.0.1:8000
세션 토큰이 포함된 URL을 출력합니다 — 해당 URL을 여세요. 모든 /api 라우트는 토큰을 요구합니다. "localhost에서만 수신한다"는 것은 다른 탭의 웹 페이지에 대한 방어책이 아니기 때문입니다. 다른 탭의 페이지도 다른 오리진과 마찬가지로 127.0.0.1에 도달할 수 있습니다. SECURITY.md에 그 이유가 설명되어 있습니다.
파일 접근은 --root(기본값: 작업 디렉터리)로 제한되므로, 그 외부의 경로는 거부됩니다.
네 가지 모두 플래그와 환경 변수가 있으며, 모두 로컬 호출자가 의도한 것보다 더 많은 리소스를 소비하는 것을 막기 위한 것입니다. 기본값은 노트북 기준으로 선택되었습니다. 더 큰 머신이라면 높이세요.
분석은 콘텐츠 해시를 키로 ~/.cache/binviz(또는 $BINVIZ_CACHE)에 캐시되므로, 바이너리를 다시 열면 즉시 로드됩니다. 더 많이 유지하려면 --max-cache를 높이세요. 캐시는 언제든 수동으로 삭제해도 안전합니다 — 최악의 경우 다음 열기에서 다시 분석할 뿐입니다.
기타 플래그: 재시작 간 토큰을 고정하는 --token(Vite 개발 프록시에서 유용하며, BINVIZ_TOKEN을 읽음), --port, --cache, CI용 --no-auth. --no-auth는 무엇을 껐는지 알려주는 배너를 출력합니다. 공유하는 머신에서는 사용하지 마세요.
pip install "binviz[app]"
binviz app # 네이티브 창; --browser는 브라우저에서 열기
binviz serve와 동일한 서버, 동일한 토큰, 동일한 --root 제한 — 표시 방식만 다릅니다. pywebview가 설치되지 않은 경우 binviz app은 브라우저를 대신 엽니다.
서빙 중인 URL을 의도적으로 출력합니다: UI를 창에 감싸는 것은 네트워크 리스너를 제거하지 않으며, 리스너가 있다는 것을 잊기 쉽게 만들 뿐입니다. 리스너는 어느 쪽이든 인증되며, binviz app에는 --no-auth가 없습니다.
창은 페이지에 정확히 하나의 함수만 노출합니다 — 네이티브 파일 선택기 — 그 외에는 아무것도 없습니다. 그 목록이 왜 그렇게 짧은지에 대한 설명은 src/binviz/app.py를 참조하세요.
릴리스는 휠 하나만 제공합니다. capstone과 lief를 번들하고 패킹된 바이너리 분석을 위해 존재하는 서명되지 않은 프리즈된 Python 실행 파일은 SmartScreen과 AV 휴리스틱이 오탐하는 정확한 프로필입니다 — 그래서 배포하는 대신, 저장소는 직접 빌드하는 데 필요한 것을 제공하며, 이는 코드 서명을 완전히 우회합니다.
pip install pyinstaller # 6.x
python tools/build_ui.py # web/ 빌드 및 패키지에 스테이징
pyinstaller packaging/binviz.spec # -> dist/binviz/
약 100MB이며, 대부분 numpy와 lief가 차지합니다. 단일 자체 추출 파일이 아닌 onedir 번들입니다: 데스크톱 창을 위해 dist/binviz/binviz.exe를 실행하거나(또는 더블클릭), 하위 명령을 전달하세요 — dist/binviz/binviz.exe triage sample.exe — 프리즈된 빌드는 창뿐만 아니라 전체 CLI이기 때문입니다.
스테이징 단계는 필수입니다. web/dist는 Python 패키지 외부에 있으므로, 이를 건너뛰면 창이 JSON 404로 열리는 앱이 생성됩니다. 스펙은 조용히 그런 일이 발생하지 않도록 빌드를 거부합니다.
macOS에서는 동일한 명령이 packaging/icons/icon.icns에서 브랜딩된 dist/Striate.app도 생성합니다. 둘 다 Mac에서 실행된 적이 없습니다 — ARCHITECTURE.md §5 참조.
--root는 여전히 작업 디렉터리를 기본값으로 하므로, 더블클릭된 실행 파일은 시작된 폴더로 제한됩니다 — 보통 앱 자체의 폴더입니다. 바로가기의 "시작 위치"를 설정하거나 --root DIR로 실행하세요.
더블클릭된 실행 파일은 자격 증명을 요구합니다. 인수 없이 프리즈된 빌드는 binviz app --auth local을 실행하며, 이것이 휠의 기본값(로그인 화면 없음)과의 유일한 차이점입니다. 두 가지는 서로 다른 질문에 답합니다: 터미널에 입력된 binviz app은 세션 소유자의 의도적인 행동이지만, 더블클릭은 아무것도 확립하지 않습니다 — 터미널도, 입력된 명령도, 제한 결정도 없는 유일한 실행 경로입니다. 자격 증명을 요구하는 것은 창이 터미널이 말했을 것을 소리 내어 말하는 방식입니다. 먼저 binviz passwd를 실행하여 설정하거나, --auth none을 명시적으로 전달하여 건너뛰세요. 명령줄에서 제공하는 모든 것은 여전히 우선합니다.
기본적으로 로그인 화면도, 복사할 것도 없습니다: 서버가 세션 토큰을 생성하여 제공하는 페이지에 주입하므로, http://127.0.0.1:8000/을 열면 모든 API 호출이 여전히 인증되면서도 바로 작동합니다.
공유하는 머신에서는 로그인 화면을 켜세요:
binviz passwd # 프롬프트; scrypt 다이제스트, 모드 0600
binviz serve --auth local
binviz passwd를 건너뛰면 첫 로그인이 설치를 차지합니다 — 시작 배너가 이를 경고합니다. 포트에 먼저 도달하는 사람이 계정이 되기 때문입니다.
더블클릭된 프리즈드 실행 파일은 스스로 --auth local을 켭니다. 이 기본값이 휠과 다른 이유는 독립 실행형 앱 빌드를 참조하세요.
로그인 화면은 보안 경계가 아닙니다. 모든 /api 라우트의 토큰 검사가 보안 경계입니다. 머신의 어떤 것도 양식을 건너뛰고 API를 직접 호출할 수 있으며, 이것이 정확히 토큰이 존재하는 이유입니다. SECURITY.md 참조.
binviz는 공격자가 선택한 파일을 엽니다 — 이것은 엣지 케이스가 아니라 본연의 임무이며, 악성코드 분석이 분석가를 손상시키는 트라이지 도구는 가능한 최악의 실패입니다. 샘플은 파싱만 되며 실행되지 않습니다. 나머지에 대한 대응은 다음과 같습니다:
악성 바이너리에 대하여
/api/{id}/… 라우트의 id는 경로를 만드는 데 사용되기 전에 정확히 64개의 16진수 문자여야 합니다.악성 브라우저에 대하여 — "localhost에서만 수신한다"는 위협은 다루지 않습니다. 다른 탭의 페이지가 다른 오리진과 마찬가지로 127.0.0.1에 도달할 수 있기 때문입니다:
/api 라우트는 토큰을 요구합니다. 시작 시 생성되어 페이지에 주입되므로, 수동으로 붙여넣을 것도, 열려 있는 라우트도 없습니다.--root로 제한되며, 기본값은 작업 디렉터리입니다. 그 외부의 경로는 거부됩니다.Host 허용 목록과 좁은 CORS로, 접근이 필요한 오리진만 접근을 얻습니다.데스크톱 창은 네트워크 리스너를 제거하지 않으며, 잊기 쉽게 만들 뿐입니다. 따라서 binviz app에는 --no-auth가 없고, js_api 브리지는 정확히 하나의 메서드만 노출합니다 — 인수를 받지 않고 동일한 --root 제한을 통해 경로를 반환하는 pick_file(). 두 번째 메서드가 나타나면 테스트가 실패합니다.
--auth local의 자격 증명은 모드 0600으로 작성된 scrypt 다이제스트입니다. binviz는 평문 비밀번호를 저장하지 않습니다.
SECURITY.md에는 위협 모델, 각 통제背后的 근거, 의도적으로 아직 하지 않은 것, 취약점을 비공개로 신고하는 방법이 있습니다.
MIT — LICENSE 참조.
코퍼스는 zig cc로 ELF 샘플을 크로스 컴파일하므로 Windows/macOS에서 Linux 툴체인이 필요하지 않습니다 — 샘플은 파싱만 되며 실행되지 않습니다.
| 정적 바이너리 | 동일한 프로그램, UPX 패킹 |
|---|
![]() | ![]() |
| 코드, 문자열, 패딩이 보이는 영역으로 분리됩니다. | 구조가 균일한 노이즈로 붕괴됩니다 — 패킹의 신호입니다. |
![]() | ![]() |
| 윈도우 엔트로피는 띠 모양으로 낮게 유지됩니다. | 언패킹 스텁까지 평평하고 높습니다. |
| 플래그 | 환경 변수 | 기본값 | 제한 대상 |
|---|
--max-cache BYTES | BINVIZ_MAX_CACHE | 5 GiB | 캐시된 분석의 총 크기. 이를 초과하면 가장 오래 사용되지 않은 항목이 제거됩니다 — 분석 중이거나 조회 중인 항목은 절대 제거되지 않습니다. |
--max-upload BYTES | BINVIZ_MAX_UPLOAD | 8 GiB | 허용되는 최대 업로드 크기. |
--max-analyses N | — | 4 | 동시 분석 수. 이를 초과하면 /api/open이 503을 반환합니다. |
--root DIR | — | cwd | 서버가 파일을 읽을 수 있는 디렉터리. |