조심하세요. 화면 글자, 스크립트, 콘솔 글자에는 비밀이 들어 있을 수 있고, 켜면 결과에 그대로 남아요. 필요할 때만 켜세요.
남기는 것, 버리는 것
REA는 기록을 내 컴퓨터에만 남기고, 몇 가지는 처음부터 버려요.
남겨요
전체 URL (아이디·비밀번호 부분만 빼고)
요청 방식·상태 코드·크기
화면 요소의 이름과 구조
스크립트 주소
버려요
쿠키
인증 헤더
저장소 값
화면 글자와 속성 값 (기본)
JSON·웹소켓의 실제 값
네트워크와 콘솔은 REA가 붙은 다음부터 기록해요. 목록에 없다고 없었던 일은 아니에요. 그 전에 읽힌 스크립트는 목록에 나와요.
기록하는 도중 페이지가 다른 곳으로 이동하면 섞인 결과를 버리고 target_changed를 알려 줘요.
다른 사이트에서 온 프레임과 스크립트는 빼요. 더 보고 싶으면 --allowed-origins에 추가하세요.
REA는 보호막이 아니에요. 페이지는 계속 돌아가고 스스로 요청을 보낼 수 있어요. 전용 프로필을 쓰고, 다 보면 브라우저를 직접 닫으세요.
Mac 앱은 집처럼 생겼어요
REA는 지붕을 열고 방마다 무엇이 있는지 지도를 그려요. 앱을 실행하지는 않아요.
넣을 수 있는 것
IPA
.app 폴더
ZIP
DMG
알려 주는 것
앱의 뿌리
방(번들) 구조
기술 힌트
브리지 후보
다 봤는지 여부
에이전트에게 이렇게 말해 보세요
~/Downloads/MyApp.dmg 안의 Mac 앱 구조를 REA로 그려 주고, 들어 있는 헬퍼와 로그인 항목을 알려줘.
방마다 하는 일경로 이름으로 역할을 정해요
Mac 앱은 MyApp.app이라는 집이고, 실제 살림은 Contents/ 안에 있어요.
Info.plist앱의 이름표. 실행 파일 이름과 번들 ID가 적혀 있어요.
Contents/MacOS/실행 파일이 사는 방. 앱의 주인공이에요.
*.framework앱이 빌려 쓰는 부품 묶음이에요.
Contents/Helpers/옆에서 일을 돕는 작은 프로그램이에요.
PlugIns/*.bundle · *.plugin기능을 끼워 넣는 플러그인이에요.
*.appex앱 밖에서 동작하는 앱 확장이에요.
*.xpc따로 떠서 일을 맡는 XPC 서비스예요.
Library/LoginItems/*.app로그인할 때 함께 켜질 수 있는 앱이에요.
Library/LaunchAgents · LaunchDaemons자동 실행 설정(.plist)이에요. Agents는 사용자용, Daemons는 시스템용이에요.
Library/LaunchServices/관리자 권한으로 도는 특권 헬퍼(SMJobBless)가 있는 곳이에요.
앱의 뿌리는 어디?상자 종류마다 달라요
REA는 먼저 "어디부터가 앱인지"를 정해요. 색칠된 곳이 앱의 뿌리예요.
IPA
Payload/ 안의 각 .app이 뿌리예요.
.app 폴더
넣은 폴더 그 자체가 뿌리예요.
ZIP · 폴더
Contents/가 있는 가장 바깥 .app이 뿌리예요.
DMG
디스크 이미지 안 볼륨의 .app이 뿌리예요. 속을 보려면 Mac에서 열 수 있어야 해요.
직접 해 보기명령어 5단계
1
파일 목록 만들기
파일마다 경로와 해시를 적은 목록(inventory)을 만들어요. 결과는 파일로 저장해 두세요.
rea inspect-artifact ~/Downloads/MyApp.dmg --json > inspection.json
2
구조 지도 그리기
<inventory_artifact Evidence> 자리에 1번 결과의 inventory Evidence를 넣어요. 같은 내용을 담은 JSON 파일 경로를 줘도 돼요.
rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'
3
이름표(plist) 읽기
지도는 plist 내용을 읽지 않아요. 실행 파일 이름, 번들 ID, URL scheme, 권한 설명은 이 명령으로 봐요.
rea inspect-plist /Applications/MyApp.app
4
서명 확인하기
실행 파일의 코드 서명 정보를 봐요.
rea inspect-signature /Applications/MyApp.app/Contents/MacOS/MyApp
5
불러오는 부품 따라가기 선택
실행 파일이 어떤 라이브러리 파일을 불러오는지 따라가요. 실행하지 않으니 Mac이 아니어도 돼요.
rea trace-dylib-resolution /Applications/MyApp.app --json
지도 읽는 법세 가지만 기억해요
기술 이름은 힌트예요
폴더 이름이 정확히 맞을 때만 "Flutter 같아요" 하고 알려 줘요. 정말 쓰였는지는 증명하지 않아요.
브리지는 추측이에요
같은 앱 안의 스크립트와 네이티브 파일을 경로로 짝지어 보여 줘요. 너무 많으면 앞부분만 싣고, 빠진 개수를 알려 줘요.
다 봤나, 일부만 봤나
목록을 다 받았으면 complete, 일부만 받았으면 partial이에요. partial일 때 "없다"는 "모른다"는 뜻이에요.
앱을 실행하지 않아요. 파일 목록과 경로만 보고 지도를 그려요.
DMG 속을 보려면 Mac이 디스크 이미지를 열 수 있어야 해요. 못 열면 결과가 partial이 되고, 앱이 없다고 단정하지 않아요.
._로 시작하는 파일과 __MACOSX/는 옆 파일을 설명하는 부속이라 방 구조에서 빼요.
바로가기(심볼릭 링크)는 경로만 적고 따라가지 않아요. 그래서 Versions/Current 대신 실제 버전 폴더를 봐요.
네이티브 분석
컴퓨터만 읽는 0과 1 프로그램을 사람이 읽을 수 있는 모양으로 풀어 봐요.
네이티브 프로그램이 뭔가요?
사람이 쓴 코드를 컴퓨터용 0과 1로 바꿔 둔 파일이에요. 우리 손에는 보통 가운데 것만 있어요.
풀어 쓴 코드는 원래 코드와 똑같지 않아요. 엔진이 0과 1을 보고 다시 만들어 낸 모양이라, 이름이 f1처럼 바뀌어 있을 수 있어요.
엔진을 하나 골라요
REA는 이미 설치된 분석 엔진을 빌려 써요. 셋 중 하나만 있으면 돼요.
Hopper
따로 파는 프로그램이에요. 제한이 있는 무료 데모가 있어요. 처음 준비할 때 설치를 제안받을 수 있어요.
macOS 12 이상
일부 Linux
Ghidra
분석할 때마다 임시 데이터베이스를 만들어 써요. 프로그램 파일은 바뀌지 않아요.
Ghidra 12.1.x
JDK 21 이상
Linux·macOS
Windows는 실험 단계
IDA
이미 가진 IDA와 IDA MCP 서버를 연결해요. 열려 있는 IDA 데이터베이스는 저장하거나 닫지 않아요.
내 IDA
IDA MCP 서버
REA_IDA_MCP_CONFIG
있는 엔진 보기
rea providers --json
엔진 건강 검진
rea doctor --provider ghidra --json
늘 쓸 엔진 정하기
export REA_ANALYSIS_PROVIDER=ghidra
명령에 --provider를 붙이면 그쪽이 먼저예요.
탐험 여정 6단계
큰 지도에서 시작해 한 기능까지 좁혀 가요. 아래는 Ghidra 예시예요. Hopper를 쓰면 --provider hopper로 바꾸세요.
1
전체 지도 보기 analyze
프로그램이 어떤 덩어리로 되어 있고 함수가 얼마나 있는지 훑어봐요. Mac 앱은 .app을 그대로 넣어도 돼요.
rea analyze /path/to/program --provider ghidra --json
2
단어로 찾기 search
궁금한 기능과 관련된 단어로 함수나 글자를 찾아요.
rea search /path/to/program "search" --provider ghidra --json
3
함수 신상 카드 function
함수 하나가 무엇을 부르고, 어떤 글자를 쓰는지 한 장에 모아 봐요. 이름은 1·2번 결과에서 그대로 가져오세요.
rea function /path/to/program main --provider ghidra --json
4
읽기 쉬운 코드로 풀기 decompile
기계어를 C 코드와 비슷한 모양(의사코드)으로 바꿔 보여 줘요. 이름이나 주소를 넣어요.
rea decompile /path/to/program 0x1000 --provider ghidra --json
5
누가 가리키나 보기 xrefs
이 주소를 부르거나 쓰는 다른 곳을 모아 줘요.
rea xrefs /path/to/program 0x1000 --provider ghidra --json
6
기능 따라가기 trace
단어 하나에서 출발해 관련 함수들을 이어서 따라가요.
rea trace /path/to/program "search" --provider ghidra --json
시작 함수 이름이 꼭 main이나 entry인 건 아니에요. 앞 단계 결과에 나온 이름과 주소를 그대로 쓰세요. 이름이 -로 시작하면 '--procedure=-[REAWidget delegate]'처럼 등호를 붙여 써요.
결과 저장하고 다시 쓰기
한 번 얻은 답을 파일로 남겨 두면, 다음에는 기다리지 않고 바로 꺼내 써요.
1
스냅샷으로 저장하기
같은 명령을 같은 파일 경로로 다시 실행하면 저장된 답을 바로 써요. 파일은 내 컴퓨터에만 남아요.
rea analyze /path/to/program --provider ghidra --snapshot /path/to/analysis/program.json
2
증거 묶음 비교하기
REA가 남긴 증거(Evidence) 파일 두 개를 나란히 놓고 달라진 점을 찾아요. 파일이 올바른지만 보려면 rea evidence-import를 써요.
rea compare /path/to/left.json /path/to/right.json
알아두기
Ghidra는 임시 데이터베이스에서 분석해요. 프로그램 파일 자체는 바뀌지 않아요.
IDA를 연결해도 열려 있는 IDA 데이터베이스는 저장하거나 닫지 않아요.
코드에서 길이 보여도, 실제 실행 중에 그 길로 간다는 증명은 아니에요.
검색 결과가 비어 있어도 그 글자가 프로그램에 없다는 뜻은 아니에요.
엔진이 안 될 때는 rea doctor --provider 엔진이름 --json으로 먼저 확인해요.
APK 상자 열어 보기
JADX라는 번역기로 APK 속 코드를 사람이 읽는 자바 코드로 바꿔 봐요. 앱은 실행하지 않아요.
필요한 것
전체 JDK 17 이상
jadx-headless-mcp 0.7.1
Linux라면 procps 호환 ps
어디서 되나요
macOS arm64 · 실제 검증
Windows x64 · 실제 검증
Linux · 지원 (새 방식 실제 검증 전)
Windows arm64 안 돼요
준비하기
REA는 Java와 JADX를 대신 설치하지 않아요. 직접 놓아 두고 위치만 알려 줘요.
1
진짜 JDK인지 확인하기
JDK 17 이상이 필요해요. 실행만 하는 JRE로는 안 돼요. 나오는 목록에 jdk.compiler가 보이면 통과예요.
java --list-modules
2
JADX 받고 지문 맞추기
받은 파일의 SHA-256 값이 REA에 적힌 값과 같아야 해요. 아래 명령은 받기, 확인, 위치 알려 주기까지 한 번에 해요.
MAC · LINUX
mkdir -p "$HOME/.local/share/rea/android" &&
cd "$HOME/.local/share/rea/android" &&
curl -fL -o jadx-headless-mcp-0.7.1-all.jar https://github.com/1013503897/jadx-headless-mcp/releases/download/v0.7.1/jadx-headless-mcp-0.7.1-all.jar &&
if command -v sha256sum >/dev/null; then
echo '6e5eacf500b64292bfb73c49797c1958f6ee44646e43e868039ae7feb573ff75 jadx-headless-mcp-0.7.1-all.jar' | sha256sum -c -
else
echo '6e5eacf500b64292bfb73c49797c1958f6ee44646e43e868039ae7feb573ff75 jadx-headless-mcp-0.7.1-all.jar' | shasum -a 256 -c -
fi &&
export REA_JADX_MCP_JAR="$PWD/jadx-headless-mcp-0.7.1-all.jar"
WINDOWS POWERSHELL
$jar = Join-Path $HOME '.local\share\rea\android\jadx-headless-mcp-0.7.1-all.jar'
New-Item -ItemType Directory -Force (Split-Path $jar) | Out-Null
Invoke-WebRequest -Uri 'https://github.com/1013503897/jadx-headless-mcp/releases/download/v0.7.1/jadx-headless-mcp-0.7.1-all.jar' -OutFile $jar
if ((Get-FileHash -Algorithm SHA256 $jar).Hash.ToLowerInvariant() -ne '6e5eacf500b64292bfb73c49797c1958f6ee44646e43e868039ae7feb573ff75') { throw 'JADX JAR SHA-256 does not match REA pinned metadata' }
$env:REA_JADX_MCP_JAR = $jar
3
위치 알려 주기
2번을 실행한 터미널에서는 이미 끝났어요. 새 터미널이나 에이전트(MCP 서버) 설정에도 같은 값을 넣어 주세요.
export REA_JADX_MCP_JAR=/absolute/path/jadx-headless-mcp-0.7.1-all.jar
# 선택: PATH의 java 대신 특정 JDK를 쓰고 싶을 때
export JAVA_HOME=/absolute/path/existing-jdk