도입: 시뮬레이터가 아니라 "진짜 iOS"가 뜬다
모바일 앱 CI 파이프라인 붙여본 사람은 다 아는 통증이 있다. Xcode Simulator는 x86/arm64 macOS 바이너리를 돌리는 물건이라 진짜 iOS 커널이 아니다. 그래서 코드사이닝, 키체인, 백그라운드 태스크, 디바이스 특성 타는 SDK(결제, 지문/FaceID, DRM)는 시뮬레이터에서 재현이 안 된다. 결국 랙에 실기기를 꽂아놓고 USB 허브와 씨름하게 된다. 나도 사무실 구석에 아이폰 8대 물린 맥미니를 몇 년 굴려봤는데, 케이블 접촉 불량과 배터리 스웰링이 진짜 장애 원인 1, 2위였다.
vphone-cli가 HN 상위에 오르면서 9천 스타를 넘긴 이유가 이거다. Apple이 macOS에 넣어둔 Virtualization.framework — 원래 macOS/Linux 게스트 부팅용으로 공개된 그 프레임워크 — 안에 Apple의 PCC(Private Cloud Compute) 리서치 VM 인프라 경로가 있고, 이걸 타고 실제 iPhone IPSW를 게스트로 부팅시킨다. 시뮬레이터가 아니라 iOS 커널이 뜨고, SSH가 붙고, VNC로 화면이 나온다.
brew install zqxwce/tap/vphone-cli
# 다운로드 → 패치 → DFU 복원 → CFW 설치 → 첫 부팅까지 한 방
vphone-cli vm create myphone -V jb
vphone-cli vm launch myphone
핵심: PCC 리서치 VM이라는 뒷문과 "패치 개수"의 의미
동작을 거칠게 비유하면 이렇다. Apple은 PCC 보안 검증을 위해 연구자에게 "제한된 Apple OS를 VM으로 띄워 뜯어보라"는 경로를 열어뒀다. 이때 하이퍼바이저 쪽에 PV=3 같은 사적(private) entitlement가 필요하고, 이건 원래 Apple이 서명한 바이너리만 쓸 수 있다. vphone-cli는 이 문을 열기 위해 호스트에서 SIP/AMFI를 완화하고, 서명 안 된 자기 바이너리에 그 entitlement를 얹는다. 즉 게스트가 아니라 호스트의 보안 정책을 먼저 깎는 구조다. 이 지점이 실무 도입의 핵심 판단 포인트다.
그 다음이 게스트 쪽. 그냥 iPhone IPSW를 던진다고 부팅되지 않는다. iBoot → 커널 → AMFI/SSV(서명된 시스템 볼륨)/Img4/TXM으로 이어지는 부트체인 검증이 VM 환경을 거부한다. 그래서 도구가 IPSW를 받아 부트체인 바이너리를 패치하고, DFU 모드로 띄운 뒤 SHSH를 받아 복원하고, CFW(커스텀 펌웨어)를 호스트 마운트로 밀어 넣는다. README의 수동 절차를 보면 파이프라인이 그대로 드러난다.
vphone-cli vm new myphone # 1. 빈 번들
vphone-cli fw prepare myphone --iphone-version 26.1 # 2. IPSW 다운로드 + 병합
vphone-cli fw patch myphone --variant jb # 3. 부트체인 패치
vphone-cli vm launch myphone --dfu # 4. DFU 부팅(백그라운드)
vphone-cli restore myphone --get-shsh # 5. SHSH 획득
vphone-cli restore myphone # DFU 복원
vphone-cli vm stop myphone
vphone-cli cfw install myphone --variant jb # 6. CFW 설치 (sudo 요구)
vphone-cli vm launch myphone # 7. 첫 부팅
재밌는 건 --variant다. 보안 우회 강도를 5단계로 나눠놨고, README에 패치 개수와 CFW 단계 수가 명시돼 있다.
less— 4패치 / 2단계. 패치리스에 가깝고 iOS 완화 기능 대부분 유지regular— 42패치 / 10단계. AMFI/SSV/Img4/TXM 우회dev— 53패치 / 12단계. TXM entitlement·디버그 우회 추가jb— 113패치 / 14단계. 풀 탈옥, 첫 부팅 시 Sileo·TrollStore 자동 설치exp— 141패치 / 18단계. jb 상위집합 + 안티-VM-디텍션 리서치 패치
이 숫자를 "많을수록 좋다"로 읽으면 안 된다. 패치를 많이 할수록 부팅한 iOS는 실기기와 멀어진다. 앱 동작 검증이 목적이면 오히려 less나 regular가 진실에 가깝고, 내부를 뜯어보거나 파일시스템에 자유롭게 접근해야 하면 jb가 편하다. 안티-VM-디텍션이 붙은 exp는 이름 그대로 리서치용이다.
실무 관점: 도입 전에 계산해야 할 비용과 함정
1) 호스트 보안을 깎는다 = CI 러너로 쓰기 곤란하다
README가 제시하는 두 가지 길 중 A안은 SIP를 완전히 끄고 AMFI까지 부트아그로 무력화한다.
# 복구 모드 터미널
csrutil disable
csrutil allow-research-guests enable
# macOS 재부팅 후
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
이 상태 머신을 사내 CI 러너로 쓰겠다는 건, 서명 검증이 꺼진 맥에 사내 코드사이닝 인증서와 App Store Connect API 키를 올려놓겠다는 뜻이다. 보안팀이 있는 조직이라면 그대로는 못 통과한다. B안(csrutil enable --without debug + vphone-amfidont로 해당 바이너리만 허용)이 그나마 낫지만, "debug 제한만 뺀 SIP"도 완전한 SIP는 아니다. 현실적인 타협은 격리 VLAN에 물린 전용 맥, 시크릿 없이, 결과물만 아티팩트로 뽑아내는 구조다.
2) 중첩 가상화 불가 — 클라우드 맥 대부분 탈락
이게 제일 크다. 실무에서 맥 인프라는 보통 클라우드 맥(호스팅 업체의 가상 맥)으로 굴리는데, 그런 환경에서는 아예 뜨지 않는다.
Virtualization is not available on this hardware
README FAQ가 명확히 짚는다. 호스트 맥 자체가 VM이면 PV=3 게스트 부팅을 중첩할 수 없다. 즉 비중첩 물리 Apple Silicon 맥 + macOS 15(Sequoia) 이상이 최소 조건이다. 베어메탈 맥미니를 새로 사거나, 물리 맥을 제공하는 업체를 찾아야 한다. 도입 검토서 첫 줄에 이 문장을 박아두는 게 좋다.
3) 실제로 만나는 에러들
가장 흔한 첫 관문은 이거다. 빌드도 됐고 실행했는데 그냥 죽는다.
$ ./vphone-cli --help
zsh: killed ./vphone-cli
커널이 SIGKILL을 쐈다는 뜻이고, 원인은 십중팔구 AMFI다. amfi_get_out_of_my_way=1 부트아그가 안 먹었거나(=SIP가 완전히 꺼져 있지 않았거나), vphone-amfidont로 allowlist를 안 걸었거나. 특히 A안에서 csrutil disable 없이 nvram만 건드리면 부트아그 자체가 무시된다. nvram boot-args로 값이 남아 있는지, csrutil status로 SIP 상태가 어떤지 둘 다 확인해야 한다.
다음으로 삽질 유발 1위는 cfw install이 시스템 바이너리 재서명 중에 멈추면서 메모리가 무한정 올라가는 현상이다. README에 원인이 꽤 상세히 적혀 있는데, ldid-procursus 2.1.5-procursus7까지의 버그다. bytes(uint64_t)가 __builtin_clzll(0)을 제로 가드 없이 호출해 UB가 되고, 그 결과 길이가 0으로 잡히면서 unsigned 루프 카운터가 언더플로 → 1바이트씩 무한히 버퍼에 쓰며 종료하지 않는다. entitlements plist에 정수 값 0이 들어 있는 Apple 시스템 바이너리를 만나면 터진다. 대응은 이렇다.
sudo kill -9 <hung ldid pid> # 이미 걸렸으면 먼저 죽이고
brew install --HEAD ldid-procursus
brew link --overwrite ldid-procursus
업스트림에서 고쳐졌지만 아직 태그된 릴리스에 안 들어가서, Homebrew stable을 쓰면 그대로 밟는다. 나 같으면 사내 프로비저닝 스크립트에 이 --HEAD 설치를 아예 박아두겠다.
그 밖에 실제로 자주 걸리는 것들:
- "Press home to continue"에서 멈춤 — VNC(
vnc://vm-ip:5901)로 붙어서 우클릭(두 손가락 클릭)이 홈 버튼이다. 하드웨어 버튼이 없으니 당연한데 모르면 5분 날린다. - 시스템 앱이 설치되지 않음 — iOS 초기 설정에서 지역을 일본이나 EU로 고르면 안 된다. VM이 만족시킬 수 없는 규제 검사가 추가로 붙는다. 미국 같은 지역을 선택하라는 게 README 권고다. 이거 모르고 "한국 옆이니까 일본" 골랐다가 재설치하는 사람 나온다.
- 앱이 EXC_GUARD / GUARD_TYPE_MACH_PORT로 크래시 —
vphone-cli fw patch <name> --variant <v> --force-exc-guard로 다시 패치한 뒤 재복원·재설치. iOS 18 베이스에서는 항상 켜야 한다고 명시돼 있다.
4) 그래도 매력적인 지점: 자동화 소켓
실무자 입장에서 제일 눈이 간 건 사실 이 부분이다. VM 번들 안에 vphone.sock 호스트 컨트롤 소켓이 있어서 스크린샷·터치·스와이프·하드웨어 키·클립보드를 프로그래밍으로 조작할 수 있고, 각 액션이 스크린샷을 인라인으로 반환한다. AI 기반 E2E 테스트를 염두에 둔 설계고, 이를 MCP 서버로 감싼 vphone-mcp도 같이 언급돼 있다.
실기기 팜에서 이걸 하려면 WebDriverAgent 띄우고 USB 세션 관리하고 스크린샷 파이프 뚫느라 인프라가 꽤 나온다. VM이면 vm clone이 APFS 클론이라 빠르고 디바이스 아이덴티티도 새로 발급된다. 테스트 케이스마다 깨끗한 기기를 몇 초 만에 찍어내는 그림은 확실히 탐난다.
vphone-cli vm clone myphone myphone-2 # APFS 클론 + 새 디바이스 아이덴티티
vphone-cli vm list --json # 스크립팅용
vphone-cli vm export myphone --out ./backup/ # zstd, 기본 fast (--max = xz -9)
5) 트레이드오프와 대안
정리하면 이렇다. 얻는 것은 진짜 iOS 커널, 스냅샷/클론, 케이블 없는 팜, 루트 셸(ssh -p 22222 mobile@<vm-ip>, 비밀번호 alpine). 내주는 것은 호스트 보안 정책, 물리 맥 하드웨어 비용, 그리고 법적·정책적 리스크다. IPSW와 iOS는 Apple EULA 대상이고, 이 도구는 부트체인 패치와 탈옥을 포함한다. 회사 제품 테스트 인프라로 상용 도입하겠다면 법무 검토 없이는 못 간다. 개인 리서치나 보안 분석 목적과, 사내 CI 표준화는 완전히 다른 문제다.
대안은 여전히 셋이다. (1) 순수 기능 검증은 Xcode Simulator + XCUITest, (2) 실기기 커버리지는 클라우드 디바이스 팜(BrowserStack, Firebase Test Lab 계열) 또는 자체 실기기 팜, (3) 보안 리서치·펌웨어 분석이면 vphone-cli. 세 번째 칸의 대안이 사실상 없었다는 게 이 프로젝트의 진짜 가치다.
정리
한 줄로: Apple의 PCC 리서치 VM 경로를 이용해 물리 Apple Silicon 맥 위에 실제 iPhone 펌웨어를 부팅시키는 도구이고, 그 대가로 호스트의 SIP/AMFI를 깎는다.
- 지금 써볼 사람 — iOS 보안 리서처, 펌웨어/커널 분석가, 탈옥 생태계 도구 개발자, "실기기 없이 iOS 내부를 뜯어보고 싶다"는 사람. 여기엔 대체재가 사실상 없다.
- 관망할 사람 — 앱 CI/CD 담당자. 아이디어는 매력적이지만 SIP off 머신을 파이프라인에 넣는 순간 보안 리스크가 이득을 넘는다. 자동화 소켓 + MCP 조합이 어떻게 성숙하는지 6개월쯤 지켜볼 가치는 충분하다.
- 쓰면 안 되는 사람 — 클라우드 맥(중첩 VM)만 있는 팀. 하드웨어부터 다시 사야 한다.
테스트된 조합도 README에 표로 정리돼 있는데, 호스트 macOS 26대, 게스트 iPhone 펌웨어 18.6.2부터 27.0 베타대까지 꽤 넓다. 다만 표에 없는 조합은 언제든 깨질 수 있는 성격의 프로젝트로 보이니, 실제 검증 전에 Tested Environments 표부터 확인하는 게 맞다.
참고 자료
- Lakr233/vphone-cli — GitHub (원문)
- research/0_binary_patch_comparison.md — variant별 패치 비교
- Issue #291 — EXC_GUARD / --force-exc-guard 관련
- Apple Developer — Virtualization framework 공식 문서
- Apple Developer — SIP 비활성화/활성화 안내
- Apple Security Research — Private Cloud Compute (PCC) Virtual Research Environment
- wh1te4ever/super-tart-vphone-writeup — README가 밝힌 참고 자료
'Tech_News' 카테고리의 다른 글
| 윈도우 라이선스 환불받기: 노트북에 딸려온 OS 값, 실제로 돌려받을 수 있을까 (0) | 2026.08.31 |
|---|---|
| Nvidia의 Hugging Face 인수설, 인프라 엔지니어가 지금 점검해야 할 것들 (0) | 2026.08.29 |
| Tailcat 뜯어보기: 계정도 제어 서버도 없이 WireGuard로 방화벽 뒤 두 서버를 잇는 법 (0) | 2026.08.28 |
| [블로그 초안] 프롬프트 인젝션은 입력 검증으로 못 막는다 — PlannerCritic 실험으로 본 에이전트 아키텍처 방어선 (0) | 2026.08.27 |
| 에이전트가 멍청한 게 아니다: 컨텍스트를 메모리 계층으로 쪼개는 법 (0) | 2026.08.26 |
