diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index d5e5c9c..62aeb5a 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1 +1,42 @@ -FROM mcr.microsoft.com/devcontainers/python:dev-3.12 +FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 + +# ── Reverse Engineering Tools (apt) ── +# radare2 : ARM64 逆アセンブル・バイナリ解析 (Mach-O / ELF) +# apktool : Android APK リソース展開・smali 逆アセンブル +RUN \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt-get update && apt-get install -y \ + wget \ + unzip \ + jq \ + radare2 \ + apktool + +# ── jadx (GitHub Release) ── +# Android APK → Java 逆コンパイル (プラットフォーム非依存 JAR、JRE は devcontainer feature の Java で提供) +RUN JADX_URL=$(wget -qO- https://api.github.com/repos/skylot/jadx/releases/latest | jq -r '.assets[] | select(.name | test("^jadx-[0-9].*\\.zip$")) | .browser_download_url') && \ + wget -q "$JADX_URL" -O /tmp/jadx.zip && \ + unzip -q /tmp/jadx.zip -d /opt/jadx && \ + ln -s /opt/jadx/bin/jadx /usr/local/bin/jadx && \ + ln -s /opt/jadx/bin/jadx-gui /usr/local/bin/jadx-gui && \ + rm /tmp/jadx.zip + +# ── Ghidra (Headless) ── +# NSA 製リバースエンジニアリングツール。ヘッドレスモードで C++ 擬似コード生成に使用 +# 使い方: analyzeHeadless /tmp/project name -import +RUN GHIDRA_URL=$(wget -qO- https://api.github.com/repos/NationalSecurityAgency/ghidra/releases/latest | jq -r '.assets[] | select(.name | test("PUBLIC.*\\.zip$")) | .browser_download_url') && \ + wget -q "$GHIDRA_URL" -O /tmp/ghidra.zip && \ + unzip -q /tmp/ghidra.zip -d /opt && \ + GHIDRA_DIR=$(find /opt -maxdepth 1 -name 'ghidra_*' -type d) && \ + ln -s "$GHIDRA_DIR" /opt/ghidra && \ + rm /tmp/ghidra.zip +ENV PATH="/opt/ghidra/support:$PATH" + +# ── ipsw ── +# Go 製 Mach-O 解析ツール。iOS バイナリの ObjC/Swift クラスダンプ、シンボル解析に使用 +# 使い方: ipsw macho info --class-dump +RUN IPSW_URL=$(wget -qO- https://api.github.com/repos/blacktop/ipsw/releases/latest | jq -r '.assets[] | select(.name | test("^ipsw_.*linux_arm64\\.tar\\.gz$")) | .browser_download_url') && \ + wget -q "$IPSW_URL" -O /tmp/ipsw.tar.gz && \ + tar xzf /tmp/ipsw.tar.gz -C /usr/local/bin ipsw && \ + rm /tmp/ipsw.tar.gz diff --git a/.devcontainer/compose.yaml b/.devcontainer/compose.yaml index 3b84ac6..1de7a7e 100644 --- a/.devcontainer/compose.yaml +++ b/.devcontainer/compose.yaml @@ -6,6 +6,17 @@ services: volumes: - ../:/home/vscode/app:cached - venv:/home/vscode/app/.venv + ports: + - 9080:9080 + tty: true + stdin_open: true + + theos: + build: + context: ./theos + dockerfile: Dockerfile + volumes: + - ../:/home/vscode/app:cached tty: true stdin_open: true diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 38c0725..37b601d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "Frida Container", + "name": "Mobile RE Toolkit", "dockerComposeFile": [ "compose.yaml" ], @@ -7,11 +7,18 @@ "workspaceFolder": "/home/vscode/app", "shutdownAction": "stopCompose", "remoteUser": "vscode", + "containerEnv": { + "CLAUDE_CONFIG_DIR": "/home/vscode/.claude" + }, "mounts": [ - "source=${env:HOME}/home/vscode/.ssh,target=/.ssh,type=bind,consistency=cached,readonly" + "source=${env:HOME}/.aws,target=/home/vscode/.aws,type=bind,consistency=cached,readonly", + "source=${env:HOME}/.claude,target=/home/vscode/.claude,type=bind,consistency=cached", + "source=${env:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached,readonly", + "source=${env:HOME}/.mitmproxy,target=/home/vscode/.mitmproxy,type=bind,consistency=cached" ], "remoteEnv": { "WAKATIME_API_KEY": "${localEnv:WAKATIME_API_KEY}", + "GH_TOKEN": "${localEnv:GH_TOKEN}", "UV_LINK_MODE": "copy" }, "features": { @@ -21,10 +28,30 @@ "ghcr.io/devcontainers/features/common-utils:2": { "configureZshAsDefaultShell": true }, + "ghcr.io/devcontainers/features/python:1": { + "version": "3.12" + }, "ghcr.io/devcontainers/features/github-cli:1": {}, "ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}, - "ghcr.io/christophermacgown/devcontainer-features/direnv:1": {} + "ghcr.io/stu-bell/devcontainer-features/claude-code:0": {}, + "ghcr.io/christophermacgown/devcontainer-features/direnv:1": {}, + "ghcr.io/devcontainers/features/node:1": { + "version": "25.9.0" + }, + "ghcr.io/shyim/devcontainers-features/bun:0": {}, + "ghcr.io/devcontainers/features/java:1": { + "version": "21", + "installMaven": false, + "installGradle": false + }, + "ghcr.io/devcontainers/features/docker-in-docker:2": { + "moby": false + }, + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "moby": false + } }, + "forwardPorts": [], "postAttachCommand": "/bin/sh .devcontainer/postAttachCommand.sh", "postCreateCommand": "/bin/sh .devcontainer/postCreateCommand.sh", "customizations": { @@ -45,10 +72,11 @@ "ms-python.python", "pHofer94.vscode-taskviewexplorer", "redhat.vscode-yaml", + "swiftlang.swift-vscode", "tamasfe.even-better-toml", "vsls-contrib.gitdoc" ], "settings": {} } } -} \ No newline at end of file +} diff --git a/.devcontainer/theos/Dockerfile b/.devcontainer/theos/Dockerfile new file mode 100644 index 0000000..456d7a9 --- /dev/null +++ b/.devcontainer/theos/Dockerfile @@ -0,0 +1,50 @@ +FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 + +# ── Theos + Swift 依存パッケージ ── +RUN \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt-get update && apt-get install -y --no-install-recommends \ + make \ + perl \ + fakeroot \ + zip \ + unzip \ + xz-utils \ + lzma \ + libtinfo6 \ + libxml2 \ + libncurses6 \ + libz3-dev + +# ── Theos 本体 ── +USER vscode +ENV THEOS=/home/vscode/theos +RUN git clone --recursive https://github.com/theos/theos.git ${THEOS} + +# ── Toolchain (L1ghtmann, aarch64 対応) ── +RUN ARCH=$(uname -m) && \ + curl -fsSL "https://github.com/L1ghtmann/llvm-project/releases/latest/download/iOSToolchain-${ARCH}.tar.xz" \ + | tar xJ -C ${THEOS}/toolchain + +# ── Swift Toolchain (kabiroberai, iOS クロスコンパイル用) ── +RUN ARCH=$(uname -m) && \ + curl -fsSL "https://github.com/kabiroberai/swift-toolchain-linux/releases/download/v2.3.0/swift-5.8-ubuntu22.04-${ARCH}.tar.xz" \ + | tar xJ -C ${THEOS}/toolchain + +# ── ホスト Swift (SPM ビルド用) ── +USER root +RUN ARCH=$(uname -m) && \ + curl -fsSL "https://download.swift.org/swift-5.8.1-release/ubuntu2204-${ARCH}/swift-5.8.1-RELEASE/swift-5.8.1-RELEASE-ubuntu22.04-${ARCH}.tar.gz" \ + | tar xz --strip-components=2 -C /usr +USER vscode + +# ── iOS SDKs (15.6 + 16.5) ── +RUN curl -fsSL "https://github.com/theos/sdks/archive/master.tar.gz" \ + | tar xz -C /tmp && \ + mv /tmp/sdks-master/iPhoneOS15.6.sdk ${THEOS}/sdks/ && \ + mv /tmp/sdks-master/iPhoneOS16.5.sdk ${THEOS}/sdks/ && \ + rm -rf /tmp/sdks-master + +# ── ビルド用作業ディレクトリ ── +WORKDIR /home/vscode/app diff --git a/.envrc b/.envrc index 7cab2f3..f218490 100644 --- a/.envrc +++ b/.envrc @@ -1,5 +1,11 @@ source .venv/bin/activate +source_env_if_exists .envrc.local dotenv +export GIT_AUTHOR_NAME="${GIT_AUTHOR_NAME:-$(git config user.name)}" +export GIT_AUTHOR_EMAIL="${GIT_AUTHOR_EMAIL:-$(git config user.email)}" +export GIT_COMMITTER_NAME="${GIT_COMMITTER_NAME:-$(git config user.name)}" +export GIT_COMMITTER_EMAIL="${GIT_COMMITTER_EMAIL:-$(git config user.email)}" + alias frida-trace="frida-trace -H $HOST --ui-port $UI_PORT" alias frida-ps="frida-ps -H $HOST" \ No newline at end of file diff --git a/.envrc.local.example b/.envrc.local.example new file mode 100644 index 0000000..cbd3d3d --- /dev/null +++ b/.envrc.local.example @@ -0,0 +1,9 @@ +# リポジトリ別にGitHub CLIのアカウントを切り替えたい場合のみ設定 +# 未設定ならホスト側の GH_TOKEN が使われます +# export GH_TOKEN=ghp_your_token_here + +# 必要な場合のみ設定(未設定なら ~/.gitconfig の値が使われます) +# export GIT_AUTHOR_NAME="Your Name" +# export GIT_AUTHOR_EMAIL="you@example.com" +# export GIT_COMMITTER_NAME="Your Name" +# export GIT_COMMITTER_EMAIL="you@example.com" diff --git a/.gitignore b/.gitignore index 97ed4fb..3a05144 100644 --- a/.gitignore +++ b/.gitignore @@ -265,18 +265,40 @@ $RECYCLE.BIN/ *.apk *.ipa *.dylib +*.mp4 # Extracted / dumped extracted_ipa/ extracted_apk/ +# Assets (large binaries) +assets/ + # Logs & captures logs/ +raws/ +cache/ +output/ cookie.txt +cookies.txt headers.md +capture.ndjson +console.log # Locks uv.lock # Secrets / env .env +.envrc.local +secrets/ + +# Node.js (frida-compile toolchain) +node_modules/ + +# Frida compiled output +packages/frida/*.js +!packages/frida/src/**/*.js + +# Chrome extension build output +packages/chrome-extension/dist/ diff --git a/.vscode/settings.json b/.vscode/settings.json index 336e52e..8af5ca1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,11 @@ ], "gitdoc.pushMode": "push", "gitdoc.timeZone": "Asia/Tokyo", - "gitlens.ai.generateCommitMessage.customInstructions": "Generate a commit message in Japanese following the Conventional Commits specification and `commitlint` rules. Use the format `(): ` and choose `` from `build`, `ci`, `docs`, `feat`, `fix`, `perf`, `chore`, `refactor`, `revert`, `format`, `test`. Limit `` to 72 characters. If `` starts with an English word, it must be in lowercase." + "gitlens.ai.generateCommitMessage.customInstructions": "Generate a commit message in Japanese following the Conventional Commits specification and `commitlint` rules. Use the format `(): ` and choose `` from `build`, `ci`, `docs`, `feat`, `fix`, `perf`, `chore`, `refactor`, `revert`, `format`, `test`. Limit `` to 72 characters. If `` starts with an English word, it must be in lowercase.", + "files.exclude": { + "**/__pycache__": true, + "**/.venv": true, + "**/.ruff_cache": true, + "**/cache": true + } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ddd15b8 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,132 @@ +{ + "version": "2.0.0", + "tasks": [ + // ── Build ── + { + "label": "frida: build (iOS)", + "type": "shell", + "command": "npm run build:ios", + "options": { "cwd": "${workspaceFolder}/packages/frida" }, + "group": "build", + "problemMatcher": [] + }, + { + "label": "frida: build (Android)", + "type": "shell", + "command": "npm run build:android", + "options": { "cwd": "${workspaceFolder}/packages/frida" }, + "group": "build", + "problemMatcher": [] + }, + { + "label": "frida: build (Chrome CDM)", + "type": "shell", + "command": "npm run build:chrome", + "options": { "cwd": "${workspaceFolder}/packages/frida" }, + "group": "build", + "problemMatcher": [] + }, + { + "label": "chrome-extension: build", + "type": "shell", + "command": "bun run build", + "options": { "cwd": "${workspaceFolder}/packages/chrome-extension" }, + "group": "build", + "problemMatcher": [] + }, + // ── Watch ── + { + "label": "frida: watch (iOS)", + "type": "shell", + "command": "npm run watch:ios", + "options": { "cwd": "${workspaceFolder}/packages/frida" }, + "isBackground": true, + "problemMatcher": [] + }, + { + "label": "frida: watch (Android)", + "type": "shell", + "command": "npm run watch:android", + "options": { "cwd": "${workspaceFolder}/packages/frida" }, + "isBackground": true, + "problemMatcher": [] + }, + // ── Run (Hook) ── + { + "label": "frida: hook iOS (Netflix)", + "type": "shell", + "command": "uv run python tools/run.py packages/frida/hook_netflix.js", + "dependsOn": "frida: build (iOS)", + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "dedicated", + "clear": true + }, + "problemMatcher": [] + }, + { + "label": "frida: hook Android (Netflix)", + "type": "shell", + "command": "uv run python tools/run.py --android packages/frida/hook_netflix_android.js", + "dependsOn": "frida: build (Android)", + "group": "test", + "presentation": { + "reveal": "always", + "panel": "dedicated", + "clear": true + }, + "problemMatcher": [] + }, + // ── Tweak (Theos) ── + { + "label": "tweak: build", + "type": "shell", + "command": "docker compose -f .devcontainer/compose.yaml exec theos make -C /home/vscode/app/${relativeFileDirname}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "tweak: clean", + "type": "shell", + "command": "docker compose -f .devcontainer/compose.yaml exec theos make -C /home/vscode/app/${relativeFileDirname} clean", + "problemMatcher": [] + }, + { + "label": "tweak: package", + "type": "shell", + "command": "docker compose -f .devcontainer/compose.yaml exec theos make -C /home/vscode/app/${relativeFileDirname} package", + "group": "build", + "problemMatcher": [] + }, + // ── Proxy ── + { + "label": "mitmproxy: Netflix iOS capture", + "type": "shell", + "command": "uv run mitmdump --listen-port 9080 --set block_global=false --ssl-insecure -s packages/mitmproxy/netflix_ios_capture.py", + "isBackground": true, + "presentation": { + "reveal": "always", + "panel": "dedicated", + "clear": true + }, + "problemMatcher": [] + }, + { + "label": "frida: hook Chrome CDM", + "type": "shell", + "command": "uv run python tools/run_chrome_cdm.py", + "dependsOn": "frida: build (Chrome CDM)", + "group": "test", + "presentation": { + "reveal": "always", + "panel": "dedicated", + "clear": true + }, + "problemMatcher": [] + } + ] +} diff --git a/pyproject.toml b/pyproject.toml index 89fe529..8bf13aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,8 +11,8 @@ dependencies = [ "colorama>=0.4.6", "cryptography>=46.0.5", "enum34>=1.1.10", - "frida>=17.8.0", - "frida-tools>=14.6.1", + "frida>=17.9.1", + "frida-tools>=14.8.1", "idna>=3.11", "ipaddress>=1.0.23", "objection>=1.12.3", @@ -27,7 +27,12 @@ dependencies = [ "six>=1.17.0", "tqdm>=4.67.3", "wcwidth>=0.6.0", - "protobuf>=3.19.0,<3.21.0", + "protobuf>=4.25.1,<5.0.0", "pycryptodome>=3.20.0", "cbor2>=5.8.0", + "pywidevine>=1.8.0", + "lief>=0.17.6", + "unicorn>=2.1.4", + "capstone>=5.0.7", + "mitmproxy>=12.2.1", ]