Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .actrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-P ubuntu-22.04=catthehacker/ubuntu:act-22.04
-P ubuntu-latest=catthehacker/ubuntu:act-latest
--container-architecture linux/arm64
23 changes: 23 additions & 0 deletions .commitlintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
extends:
- "@commitlint/config-conventional"
rules:
header-max-length:
- 2
- always
- 128
type-enum:
- 2
- always
- - build
- ui
- ci
- docs
- feat
- fix
- perf
- refactor
- revert
- format
- test
- chore
135 changes: 81 additions & 54 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,80 +1,107 @@
# syntax=docker/dockerfile:1.7
# iOS Tweak / Reverse Engineering environment.
# Bundles Theos + iOS cross-compile toolchain + reverse engineering suite
# (radare2, jadx, Ghidra, ipsw, class-dump, libimobiledevice).
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
ARG _REMOTE_USER_HOME=/home/vscode

# ── Reverse Engineering Tools + Theos 依存パッケージ (apt) ──
# ── Reverse engineering tools + Theos build dependencies ──
RUN \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
--mount=type=cache,target=/var/cache/apt,sharing=locked \
rm -f /etc/apt/apt.conf.d/docker-clean && \
apt-get update && apt-get install -y --no-install-recommends \
wget \
unzip \
jq \
radare2 \
apktool \
make \
perl \
fakeroot \
zip \
xz-utils \
lzma \
libtinfo6 \
libxml2 \
libncurses6 \
libz3-dev
wget unzip jq git-filter-repo \
radare2 apktool \
make perl fakeroot zip xz-utils lzma xxd binutils \
libtinfo6 libxml2 libncurses6 libz3-dev \
adb android-sdk-platform-tools \
# libimobiledevice for idevicesyslog / os_log capture over USB.
# class-dump-style tooling; recon primary.
libimobiledevice-utils libimobiledevice6 ideviceinstaller libplist-utils \
# Relay / port forward helpers for jailbroken device sessions.
socat netcat-openbsd \
# Mach-O / FAT identification.
file llvm

# ── 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 && \
# ── jadx (Android APK → Java decompiler) ──
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
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') && \
JADX_FILE=/var/cache/dl/$(basename "$JADX_URL") && \
{ [ -f "$JADX_FILE" ] || wget -q "$JADX_URL" -O "$JADX_FILE"; } && \
unzip -q "$JADX_FILE" -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
ln -s /opt/jadx/bin/jadx-gui /usr/local/bin/jadx-gui

# ── Ghidra (Headless) ──
# NSA 製リバースエンジニアリングツール。ヘッドレスモードで C++ 擬似コード生成に使用
# 使い方: analyzeHeadless /tmp/project name -import <binary>
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 (NSA reverse engineering suite, headless mode) ──
# Usage: analyzeHeadless /tmp/project name -import <binary>
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
GHIDRA_URL=$(wget -qO- https://api.github.com/repos/NationalSecurityAgency/ghidra/releases/latest | jq -r '.assets[] | select(.name | test("PUBLIC.*\\.zip$")) | .browser_download_url') && \
GHIDRA_FILE=/var/cache/dl/$(basename "$GHIDRA_URL") && \
{ [ -f "$GHIDRA_FILE" ] || wget -q "$GHIDRA_URL" -O "$GHIDRA_FILE"; } && \
unzip -q "$GHIDRA_FILE" -d /opt && \
GHIDRA_DIR=$(find /opt -maxdepth 1 -name 'ghidra_*' -type d) && \
ln -s "$GHIDRA_DIR" /opt/ghidra && \
rm /tmp/ghidra.zip
ln -s "$GHIDRA_DIR" /opt/ghidra
ENV PATH="/opt/ghidra/support:$PATH"

# ── ipsw ──
# Go 製 Mach-O 解析ツール。iOS バイナリの ObjC/Swift クラスダンプ、シンボル解析に使用
# 使い方: ipsw macho info <binary> --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
# ── ipsw (Go-based Mach-O analyzer) ──
# Usage: ipsw macho info <binary> --class-dump
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
IPSW_URL=$(wget -qO- https://api.github.com/repos/blacktop/ipsw/releases/latest | jq -r --arg arch "$ARCH" '.assets[] | select(.name | test("^ipsw_.*linux_" + $arch + "\\.tar\\.gz$")) | .browser_download_url') && \
IPSW_FILE=/var/cache/dl/$(basename "$IPSW_URL") && \
{ [ -f "$IPSW_FILE" ] || wget -q "$IPSW_URL" -O "$IPSW_FILE"; } && \
tar xzf "$IPSW_FILE" -C /usr/local/bin ipsw

# ── yq (mikefarah/yq, Go) ──
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') && \
YQ_URL=$(wget -qO- https://api.github.com/repos/mikefarah/yq/releases/latest | jq -r --arg arch "$ARCH" '.assets[] | select(.name == "yq_linux_\($arch)") | .browser_download_url') && \
YQ_FILE=/var/cache/dl/yq_linux_${ARCH} && \
{ [ -f "$YQ_FILE" ] || wget -q "$YQ_URL" -O "$YQ_FILE"; } && \
install -m 0755 "$YQ_FILE" /usr/local/bin/yq

# ── Theos 本体 ──
# ── Theos core ──
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
# ── L1ghtmann iOS toolchain (aarch64 support) ──
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
ARCH=$(uname -m) && \
TC_FILE=/var/cache/dl/iOSToolchain-${ARCH}.tar.xz && \
{ [ -f "$TC_FILE" ] || curl -fsSL -o "$TC_FILE" "https://github.com/L1ghtmann/llvm-project/releases/latest/download/iOSToolchain-${ARCH}.tar.xz"; } && \
tar xJf "$TC_FILE" -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
# ── kabiroberai Swift toolchain (iOS cross-compile) ──
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
ARCH=$(uname -m) && \
SWIFT_TC_FILE=/var/cache/dl/swift-5.8-ubuntu22.04-${ARCH}.tar.xz && \
{ [ -f "$SWIFT_TC_FILE" ] || curl -fsSL -o "$SWIFT_TC_FILE" "https://github.com/kabiroberai/swift-toolchain-linux/releases/download/v2.3.0/swift-5.8-ubuntu22.04-${ARCH}.tar.xz"; } && \
tar xJf "$SWIFT_TC_FILE" -C ${THEOS}/toolchain

# ── ホスト Swift (SPM ビルド用) ──
# ── Host Swift (for SPM builds that run on the container itself) ──
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
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
ARCH=$(uname -m) && \
HOST_SWIFT_FILE=/var/cache/dl/swift-5.8.1-RELEASE-ubuntu22.04-${ARCH}.tar.gz && \
{ [ -f "$HOST_SWIFT_FILE" ] || curl -fsSL -o "$HOST_SWIFT_FILE" "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 xzf "$HOST_SWIFT_FILE" --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 && \
# ── iOS SDKs (15.6 + 16.5 from theos/sdks) ──
RUN \
--mount=type=cache,target=/var/cache/dl,sharing=locked,uid=1000,gid=1000 \
SDKS_FILE=/var/cache/dl/theos-sdks-master.tar.gz && \
{ [ -f "$SDKS_FILE" ] || curl -fsSL -o "$SDKS_FILE" "https://github.com/theos/sdks/archive/master.tar.gz"; } && \
tar xzf "$SDKS_FILE" -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
25 changes: 24 additions & 1 deletion .devcontainer/compose.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
services:
app:
# By default we pull the pre-built image published by the upstream
# template repo's CI (~5 min pull vs. ~25 min local build of Theos +
# iPhoneOS SDK + Ghidra + Swift toolchain).
#
# DOCKER_OWNER defaults to the upstream maintainer of this template; if
# you fork and want to publish your own image (or run
# `.github/workflows/devcontainer-build.yaml` in your fork), override
# DOCKER_OWNER in a .env file next to this compose.yaml:
# DOCKER_OWNER=your-github-username
#
# To force a local build instead of pulling — useful when hacking the
# Dockerfile — comment out `image:` and the pre-built pull is skipped
# (Compose falls through to `build:`).
image: ghcr.io/${DOCKER_OWNER:-yuki-minakami}/devcontainer-swift-ios-tweak:latest
build:
context: .
dockerfile: Dockerfile
volumes:
- ../:/home/vscode/app:cached
- venv:/home/vscode/app/.venv
- uv-cache:/home/vscode/.cache/uv
- bun-cache:/home/vscode/.bun/install/cache
- npm-cache:/home/vscode/.npm
- pip-cache:/home/vscode/.cache/pip
# host networking helps talking to physical devices via libimobiledevice
# / iproxy over USB, and simplifies port relays to jailbroken hosts.
network_mode: host
tty: true
stdin_open: true

volumes:
venv:
driver: local
uv-cache:
bun-cache:
npm-cache:
pip-cache:
145 changes: 74 additions & 71 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,78 +1,81 @@
{
"name": "Mobile RE Toolkit",
"dockerComposeFile": [
"compose.yaml"
],
"service": "app",
"workspaceFolder": "/home/vscode/app",
"shutdownAction": "stopCompose",
"remoteUser": "vscode",
"containerEnv": {
"CLAUDE_CONFIG_DIR": "/home/vscode/.claude"
"name": "Swift iOS Tweak",
"dockerComposeFile": [
"compose.yaml"
],
"service": "app",
"workspaceFolder": "/home/vscode/app",
"shutdownAction": "stopCompose",
"remoteUser": "vscode",
"remoteEnv": {
"ANTHROPIC_BASE_URL": "${localEnv:ANTHROPIC_BASE_URL}",
"ANTHROPIC_AUTH_TOKEN": "${localEnv:ANTHROPIC_AUTH_TOKEN}",
"GH_TOKEN": "${localEnv:GH_TOKEN}",
"UV_LINK_MODE": "copy",
"WAKATIME_API_KEY": "${localEnv:WAKATIME_API_KEY}"
},
"containerEnv": {
"CLAUDE_CONFIG_DIR": "/home/vscode/.claude",
"THEOS": "/home/vscode/theos"
},
"mounts": [
"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}/.config/gh,target=/home/vscode/.config/gh,type=bind,consistency=cached,readonly"
],
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"configureZshAsDefaultShell": true
},
"mounts": [
"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"
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.12"
},
"features": {
"ghcr.io/devcontainers/features/git:1": {
"version": "2.52.0"
},
"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/stu-bell/devcontainer-features/claude-code:0": {},
"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/va-h/devcontainers-features/uv:1": {
"version": "latest"
},
"forwardPorts": [9080],
"otherPortsAttributes": {
"onAutoForward": "ignore"
"ghcr.io/devcontainers/features/node:1.5.0": {
"version": "26.5.0"
},
"postAttachCommand": "/bin/sh .devcontainer/postAttachCommand.sh",
"postCreateCommand": "/bin/sh .devcontainer/postCreateCommand.sh",
"customizations": {
"vscode": {
"extensions": [
"Anthropic.claude-code",
"EditorConfig.EditorConfig",
"GitHub.copilot",
"GitHub.copilot-chat",
"PKief.material-icon-theme",
"antfu.file-nesting",
"bierner.markdown-mermaid",
"bierner.markdown-preview-github-styles",
"charliermarsh.ruff",
"eamodio.gitlens",
"jebbs.markdown-extended",
"ms-python.black-formatter",
"ms-python.python",
"pHofer94.vscode-taskviewexplorer",
"redhat.vscode-yaml",
"swiftlang.swift-vscode",
"tamasfe.even-better-toml",
"vsls-contrib.gitdoc"
],
"settings": {}
}
"ghcr.io/shyim/devcontainers-features/bun:0": {},
"ghcr.io/devcontainers/features/java:1": {
"version": "21",
"installMaven": false,
"installGradle": false
},
"ghcr.io/stu-bell/devcontainer-features/claude-code:0": {
"version": "latest"
},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
"moby": false,
"dockerDashComposeVersion": "v2"
},
"ghcr.io/dhoeric/features/act:1": {},
"ghcr.io/devcontainers-community/features/direnv:1": {},
"ghcr.io/swift-server-community/swift-devcontainer-features/swift-format:0": {}
},
"otherPortsAttributes": {
"onAutoForward": "ignore"
},
"postAttachCommand": "/bin/sh .devcontainer/postAttachCommand.sh",
"postCreateCommand": "/bin/sh .devcontainer/postCreateCommand.sh",
"customizations": {
"vscode": {
"extensions": [
"EditorConfig.EditorConfig",
"PKief.material-icon-theme",
"antfu.file-nesting",
"bierner.markdown-mermaid",
"bierner.markdown-preview-github-styles",
"charliermarsh.ruff",
"ms-python.python",
"ms-python.vscode-pylance",
"redhat.vscode-yaml",
"swiftlang.swift-vscode",
"tamasfe.even-better-toml"
],
"settings": {}
}
}
}
Loading
Loading