배경
이전 글에서 다룬 ghidra-agent-mcp는 Docker headless Ghidra를 HTTP로 래핑한 MCP 서버다. 한 프로젝트에 여러 바이너리를 동시에 상주시키고 deps_cross_xref / callgraph_path 같은 도구를 LLM에 노출해 크로스 바이너리 추적을 자동화했다.
문제가 있다면, 이전에 llm이 직접 바이너리 import를 수행했는데 이 과정이 생각보다 시간이 오래 걸려 llm이 타임아웃되버리는 경우가 있었다. 사람이 직접 import 하는 방향으로 구생해보았다. 디버깅하면서 "지금 컨테이너에 뭐가 올라와 있지?", "이 엔드포인트는 어떤 JSON을 반환하지?" 를 확인하려면 매번 curl로 두드려보거나 LLM 세션을 띄워야 했다. 이 문제들을 해결하기 위해서 v1.0.0에서 데스크톱 GUI를 추가하였다.

구성
GUI와 MCP 브리지가 같은 HTTP 서버(127.0.0.1:18089)를 본다. GUI에서 import한 바이너리는 LLM이 그대로 find_function / decompile_function으로 조회하고, 결과 JSON은 docker/results/ 아래 같은 트리에 누적된다.
페이지
Dashboard

- 드래그 드롭으로 바이너리 업로드. 큰 바이너리도 즉시 job_id가 반환되고 분석은 백그라운드에서 돈다 (최대 30분 대기).
- 로드된 프로그램 카드 그리드.
current뱃지가 활성 프로그램을 표시한다. - 컨테이너 로그가 우측 패널에 라이브로 흐른다 — auto-scroll / pause / clear / download. 분석이 멈췄을 때 별도 터미널을 띄우지 않고 그 자리에서 확인.
Programs

- 좌: 필터 가능한 프로그램 리스트.
- 우: force-directed 노드·엣지 그래프. Show externals 토글로 import만 잡힌 외부 DLL까지 펼친다.
- 노드 클릭 시 해당 프로그램 디테일 페이지로 이동 (Functions / Imports / Strings / Results 탭).
캡처는 Claude Setup.exe 한 개만 로드된 상태다. Show externals를 켜면 KERNEL32 / USER32 / ADVAPI32 / OLE32 / OLEAUT32 / SHELL32 / SHLWAPI / COMCTL32 / URLMON 9개 외부 의존이 한 화면에 뜬다. KERNEL32.DLL을 추가로 import하면 외부 노드가 내부 노드로 승격되고, 그 export를 부르는 다른 프로그램과의 엣지가 자동으로 연결된다.
Search

- Function / Symbol / String 통합 검색, case-sensitivity 토글.
- 한 번의 호출로 로드된 모든 프로그램을 검색한다 (
/search/functions,/search/symbols,/search/strings). - 결과 클릭 시 owning program의 디테일 탭으로 deep-link.
캡처는 Write 쿼리에 대해 DloadAcquireSectionWriteAccess 부터 __crt_stdio_output::stream_output_adapter::write_* 시리즈까지 24건이 매칭된 모습이다.
Console

/schema를 자동 로드해 좌측에 45개 엔드포인트를 GET/POST 뱃지와 함께 나열한다.- 선택한 엔드포인트에 대해 파라미터 폼이 자동 생성되고, 응답은 신택스 하이라이팅된 JSON으로 표시된다.
- 호출 50건이 localStorage에 저장돼 우하단 History 패널에서 재실행할 수 있다.
새 엔드포인트를 추가하거나 MCP 도구의 입출력을 검증할 때 curl / HTTPie 대신 사용한다.
Settings

- Container — 데스크톱 앱에서 docker compose up/down/restart 버튼이 활성. (브라우저로 띄웠을 때는 비활성)
- Server — Ghidra HTTP Server URL 변경. 변경값이 브라우저에 저장돼 다음 실행에 그대로 적용되고, 3초 간격으로
/health를 통해 상태를 리프레싱 한다. - Project paths — 시작 시점에 자동 감지된 binaries / results / meta 경로.
- About — 버전 정보.
v1.0.0과 v1.0.1
v1.0.0 (2026-04-27) — 첫 GUI 릴리즈
- 데스크톱 GUI 추가 — Dashboard / Programs / Search / Console / Settings.
- 긴 분석을 백그라운드로 — 업로드/임포트 호출이 즉시 반환되고 GUI가 진행 상태를 폴링. 큰 바이너리에 LLM 세션이나 GUI 창이 묶이지 않는다.
- 프로젝트 상태 유지 — 컨테이너를 껐다 켜도 로드된 프로그램이 그대로 유지된다.
- 의존성 그래프 + Show externals 토글.
- 크로스 프로그램 심볼 매칭 — A의 import가 B의 export에 어떻게 붙는지 한 번에 매칭.
- Dashboard 라이브 컨테이너 로그.
v1.0.1 (2026-04-28) — 언어 확장 번들
백엔드가 다룰 수 있는 바이너리 종류를 넓혔다.
- Go 바이너리 분석 — Go 1.6 ~ 1.26 함수명/문자열을 복원 (GolangAnalyzerExtension 1.3.0). Go 바이너리는 분석을 안 돌리면 함수가 거의 다 익명으로 잡힌다.
- C++ 클래스 복원 — vtable에서 클래스 구조를 추론하고 함수를 핑거프린팅 (CERTCC Kaiju).
- v1.0.1부터 두 확장이 실제로 활성화 — 이전 빌드는 확장 파일이 들어 있어도 idle 상태였다.
- Rust / Swift / Kotlin은 Ghidra 12 빌트인 demangler와 DEX loader가 이미 커버해 별도 번들은 추가하지 않았다.
정리
- v1.0.0에서 데스크톱 GUI를 추가했다. 같은 HTTP 서버를 GUI와 MCP 브리지가 공유하므로 GUI에서 import한 바이너리를 LLM이 그대로 조회할 수 있고, 결과 파일도 같은 트리에 누적된다.
- 다섯 페이지 중 Programs의 의존성 그래프와 Console의 엔드포인트 러너가 기존 워크플로우(
curl+ LLM 세션)를 대체한다. - v1.0.1은 GUI는 그대로 두고 Golang/Kaiju 확장을 번들해 Go·C++ 바이너리에서 GUI에 올라오는 함수·심볼의 질을 보강했다.