Skip to content

Commit a24ec7a

Browse files
committed
chore: improve ci to build for mac too & improved docs.
1 parent 32f7eb0 commit a24ec7a

8 files changed

Lines changed: 995 additions & 527 deletions

File tree

.github/workflows/ci.yml

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Install Rust toolchain
2222
uses: dtolnay/rust-toolchain@stable
2323
with:
24-
targets: aarch64-apple-ios
24+
targets: aarch64-apple-ios,aarch64-apple-darwin
2525
components: rustfmt, clippy
2626

2727
- name: Cache cargo registry
@@ -51,7 +51,7 @@ jobs:
5151
- name: Install Rust toolchain
5252
uses: dtolnay/rust-toolchain@stable
5353
with:
54-
targets: aarch64-apple-ios
54+
targets: aarch64-apple-ios,aarch64-apple-darwin
5555

5656
- name: Cache cargo registry
5757
uses: actions/cache@v4
@@ -65,24 +65,36 @@ jobs:
6565
restore-keys: |
6666
${{ runner.os }}-cargo-
6767
68-
- name: Type-check (aarch64-apple-ios)
68+
- name: Type-check (iOS)
6969
run: cargo check --target aarch64-apple-ios
7070

71-
- name: Build libspecter.a
71+
- name: Type-check (macOS)
72+
run: cargo check --target aarch64-apple-darwin
73+
74+
- name: Build libspecter.a (iOS + macOS)
7275
run: make
7376

74-
- name: Verify exported symbols
77+
- name: Verify exported symbols (iOS + macOS)
7578
run: make check
7679

77-
- name: Upload library artifact
80+
- name: Upload iOS artifact
7881
uses: actions/upload-artifact@v4
7982
with:
80-
name: libspecter-${{ github.sha }}
83+
name: libspecter-ios-${{ github.sha }}
8184
path: |
8285
target/aarch64-apple-ios/release/libspecter.a
8386
specter.h
8487
retention-days: 7
8588

89+
- name: Upload macOS artifact
90+
uses: actions/upload-artifact@v4
91+
with:
92+
name: libspecter-macos-${{ github.sha }}
93+
path: |
94+
target/aarch64-apple-darwin/release/libspecter.a
95+
specter.h
96+
retention-days: 7
97+
8698
publish-package:
8799
name: Publish GitHub Package
88100
needs: [lint, build]
@@ -97,7 +109,7 @@ jobs:
97109
- name: Install Rust toolchain
98110
uses: dtolnay/rust-toolchain@stable
99111
with:
100-
targets: aarch64-apple-ios
112+
targets: aarch64-apple-ios,aarch64-apple-darwin
101113

102114
- name: Cache cargo registry
103115
uses: actions/cache@v4
@@ -111,7 +123,7 @@ jobs:
111123
restore-keys: |
112124
${{ runner.os }}-cargo-
113125
114-
- name: Build libspecter.a
126+
- name: Build libspecter.a (iOS + macOS)
115127
run: make
116128

117129
- name: Install ORAS
@@ -127,6 +139,7 @@ jobs:
127139
oras push "ghcr.io/${REPO_LC}:${{ github.ref_name }}" \
128140
--artifact-type "application/vnd.specter.library.v1" \
129141
target/aarch64-apple-ios/release/libspecter.a:application/octet-stream \
142+
target/aarch64-apple-darwin/release/libspecter.a:application/octet-stream \
130143
specter.h:text/plain
131144
132145
if [[ "${{ github.ref_name }}" != *-* ]]; then
@@ -146,7 +159,7 @@ jobs:
146159
- name: Install Rust toolchain
147160
uses: dtolnay/rust-toolchain@stable
148161
with:
149-
targets: aarch64-apple-ios
162+
targets: aarch64-apple-ios,aarch64-apple-darwin
150163

151164
- name: Cache cargo registry
152165
uses: actions/cache@v4
@@ -160,20 +173,28 @@ jobs:
160173
restore-keys: |
161174
${{ runner.os }}-cargo-
162175
163-
- name: Build libspecter.a (release)
176+
- name: Build libspecter.a (iOS + macOS)
164177
run: make
165178

166179
- name: Verify exported symbols
167180
run: make check
168181

169182
- name: Package release artifacts
170183
run: |
171-
ARCHIVE="specter-${{ github.ref_name }}-aarch64-apple-ios.tar.gz"
172-
tar -czf "$ARCHIVE" \
173-
target/aarch64-apple-ios/release/libspecter.a \
174-
specter.h
175-
echo "ARCHIVE=$ARCHIVE" >> "$GITHUB_ENV"
176-
shasum -a 256 "$ARCHIVE" > "$ARCHIVE.sha256"
184+
IOS_ARCHIVE="specter-${{ github.ref_name }}-aarch64-apple-ios.tar.gz"
185+
tar -czf "$IOS_ARCHIVE" \
186+
-C target/aarch64-apple-ios/release libspecter.a \
187+
-C "$GITHUB_WORKSPACE" specter.h
188+
shasum -a 256 "$IOS_ARCHIVE" > "$IOS_ARCHIVE.sha256"
189+
190+
MACOS_ARCHIVE="specter-${{ github.ref_name }}-aarch64-apple-darwin.tar.gz"
191+
tar -czf "$MACOS_ARCHIVE" \
192+
-C target/aarch64-apple-darwin/release libspecter.a \
193+
-C "$GITHUB_WORKSPACE" specter.h
194+
shasum -a 256 "$MACOS_ARCHIVE" > "$MACOS_ARCHIVE.sha256"
195+
196+
echo "IOS_ARCHIVE=$IOS_ARCHIVE" >> "$GITHUB_ENV"
197+
echo "MACOS_ARCHIVE=$MACOS_ARCHIVE" >> "$GITHUB_ENV"
177198
178199
- name: Create GitHub Release
179200
env:
@@ -187,5 +208,7 @@ jobs:
187208
--title "Specter ${{ github.ref_name }}" \
188209
--generate-notes \
189210
$PRERELEASE \
190-
"${{ env.ARCHIVE }}" \
191-
"${{ env.ARCHIVE }}.sha256"
211+
"${{ env.IOS_ARCHIVE }}" \
212+
"${{ env.IOS_ARCHIVE }}.sha256" \
213+
"${{ env.MACOS_ARCHIVE }}" \
214+
"${{ env.MACOS_ARCHIVE }}.sha256"

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "specter-mem"
3-
version = "1.0.1"
3+
version = "1.0.2"
44
edition = "2024"
55
description = "ARM64 memory manipulation framework for iOS/macOS — inline hooking, stealth code patching, hardware breakpoints, and shellcode loading"
66
license = "MIT"

Makefile

Lines changed: 57 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
# Makefile — build libspecter.a (Rust static library) for aarch64-apple-ios
2-
# and optionally compile + link a C/C++ consumer against it.
2+
# and aarch64-apple-darwin, and optionally compile + link a C/C++ consumer.
33
#
44
# Usage:
5-
# make — build libspecter.a (release)
6-
# make debug — build libspecter.a (debug)
5+
# make — build libspecter.a for both iOS and macOS (release)
6+
# make ios — build for iOS only
7+
# make macos — build for macOS only
8+
# make debug — build for both (debug)
79
# make clean — remove build artefacts
810
# make check — build and run a quick symbol-presence sanity check
911
#
1012
# Consumer targets (set CONSUMER_SRC):
1113
# make consumer CONSUMER_SRC=tests/test.c
1214
# make consumer CONSUMER_SRC=tests/test.cpp
13-
#
14-
# Override any variable on the command line, e.g.:
15-
# make CARGO_TARGET=aarch64-apple-macosx14.0
1615

1716
# Rust / Cargo
1817
CARGO := cargo
19-
CARGO_TARGET := aarch64-apple-ios
2018
RUST_PROFILE := release
21-
CARGO_FLAGS := --target $(CARGO_TARGET)
2219

23-
ifeq ($(RUST_PROFILE),release)
24-
CARGO_FLAGS += --release
25-
endif
20+
IOS_TARGET := aarch64-apple-ios
21+
MACOS_TARGET := aarch64-apple-darwin
22+
23+
IOS_LIB_DIR := target/$(IOS_TARGET)/$(RUST_PROFILE)
24+
MACOS_LIB_DIR := target/$(MACOS_TARGET)/$(RUST_PROFILE)
25+
IOS_LIB := $(IOS_LIB_DIR)/libspecter.a
26+
MACOS_LIB := $(MACOS_LIB_DIR)/libspecter.a
2627

27-
RUST_LIB_DIR := target/$(CARGO_TARGET)/$(RUST_PROFILE)
28-
RUST_LIB := $(RUST_LIB_DIR)/libspecter.a
28+
CARGO_FLAGS_RELEASE := --release
2929

3030
# Apple SDK / toolchain
3131
SDK := iphoneos
@@ -57,7 +57,7 @@ LDFLAGS := \
5757
-arch $(ARCH) \
5858
-isysroot $(SYSROOT) \
5959
-miphoneos-version-min=$(MIN_IOS) \
60-
-L$(RUST_LIB_DIR) \
60+
-L$(IOS_LIB_DIR) \
6161
-lspectre \
6262
-lc++ \
6363
-framework Foundation \
@@ -70,24 +70,32 @@ HEADER := specter.h
7070
CONSUMER_SRC ?=
7171
CONSUMER_OUT ?= build/consumer
7272

73-
.PHONY: all debug release consumer check clean help
73+
.PHONY: all ios macos debug debug-ios debug-macos release consumer check check-ios check-macos clean help
74+
75+
all: ios macos
76+
77+
release: all
78+
79+
ios:
80+
$(CARGO) build --target $(IOS_TARGET) $(CARGO_FLAGS_RELEASE)
81+
@echo "Built: $(IOS_LIB)"
7482

75-
all: release
83+
macos:
84+
$(CARGO) build --target $(MACOS_TARGET) $(CARGO_FLAGS_RELEASE)
85+
@echo "Built: $(MACOS_LIB)"
7686

77-
release:
78-
$(CARGO) build $(CARGO_FLAGS)
79-
@echo "Built: $(RUST_LIB)"
87+
debug: debug-ios debug-macos
8088

81-
debug: RUST_PROFILE := debug
82-
debug: CARGO_FLAGS := --target $(CARGO_TARGET)
83-
debug: RUST_LIB_DIR := target/$(CARGO_TARGET)/debug
84-
debug: RUST_LIB := target/$(CARGO_TARGET)/debug/libspecter.a
85-
debug:
86-
$(CARGO) build --target $(CARGO_TARGET)
87-
@echo "Built: target/$(CARGO_TARGET)/debug/libspecter.a"
89+
debug-ios:
90+
$(CARGO) build --target $(IOS_TARGET)
91+
@echo "Built: target/$(IOS_TARGET)/debug/libspecter.a"
8892

89-
# Compile + link a C or C++ consumer file
90-
consumer: release
93+
debug-macos:
94+
$(CARGO) build --target $(MACOS_TARGET)
95+
@echo "Built: target/$(MACOS_TARGET)/debug/libspecter.a"
96+
97+
# Compile + link a C or C++ consumer file (against iOS build)
98+
consumer: ios
9199
@if [ -z "$(CONSUMER_SRC)" ]; then \
92100
echo "Error: set CONSUMER_SRC=path/to/file.{c,cpp}"; exit 1; \
93101
fi
@@ -102,29 +110,40 @@ consumer: release
102110
$$COMPILER $$CFLAGS_USED $(CONSUMER_SRC) $(LDFLAGS) -o $(CONSUMER_OUT)
103111
@echo "Linked: $(CONSUMER_OUT)"
104112

105-
# Sanity check: verify exported symbols are present in the static lib
106-
check: release
107-
@echo "── Checking exported symbols in $(RUST_LIB) ──"
108-
@nm -gU $(RUST_LIB) | grep ' T _mem_' | sort
113+
# Sanity check: verify exported symbols are present in both builds
114+
check: check-ios check-macos
115+
116+
check-ios: ios
117+
@echo "── Checking exported symbols in $(IOS_LIB) ──"
118+
@nm -gU $(IOS_LIB) | grep ' T _mem_' | sort
119+
@EXPECTED=$$(grep -E '^(int32_t|size_t|void)[[:space:]]+mem_[a-z]' $(HEADER) | wc -l | tr -d ' '); \
120+
FOUND=$$(nm -gU $(IOS_LIB) | grep -c ' T _mem_'); \
121+
echo "Declared in header: $$EXPECTED | Found in lib: $$FOUND"; \
122+
if [ "$$FOUND" -ge "$$EXPECTED" ]; then echo "OK (iOS)"; else echo "MISMATCH — check ffi.rs"; exit 1; fi
123+
124+
check-macos: macos
125+
@echo "── Checking exported symbols in $(MACOS_LIB) ──"
126+
@nm -gU $(MACOS_LIB) | grep ' T _mem_' | sort
109127
@EXPECTED=$$(grep -E '^(int32_t|size_t|void)[[:space:]]+mem_[a-z]' $(HEADER) | wc -l | tr -d ' '); \
110-
FOUND=$$(nm -gU $(RUST_LIB) | grep -c ' T _mem_'); \
128+
FOUND=$$(nm -gU $(MACOS_LIB) | grep -c ' T _mem_'); \
111129
echo "Declared in header: $$EXPECTED | Found in lib: $$FOUND"; \
112-
if [ "$$FOUND" -ge "$$EXPECTED" ]; then echo "OK"; else echo "MISMATCH — check ffi.rs"; exit 1; fi
130+
if [ "$$FOUND" -ge "$$EXPECTED" ]; then echo "OK (macOS)"; else echo "MISMATCH — check ffi.rs"; exit 1; fi
113131

114132
clean:
115133
$(CARGO) clean
116134
rm -rf build
117135

118136
help:
119137
@echo "Targets:"
120-
@echo " all / release Build libspecter.a (release)"
121-
@echo " debug Build libspecter.a (debug)"
138+
@echo " all / release Build libspecter.a for iOS and macOS (release)"
139+
@echo " ios Build for aarch64-apple-ios only"
140+
@echo " macos Build for aarch64-apple-darwin only"
141+
@echo " debug Build both targets (debug)"
122142
@echo " consumer Compile + link CONSUMER_SRC against libspecter.a"
123-
@echo " check Verify exported symbols match memory.h declarations"
143+
@echo " check Verify exported symbols for both targets"
124144
@echo " clean Remove all build artefacts"
125145
@echo ""
126146
@echo "Variables:"
127-
@echo " CARGO_TARGET Default: aarch64-apple-ios"
128147
@echo " SDK Default: iphoneos (use iphonesimulator for Simulator)"
129148
@echo " MIN_IOS Default: 14.0"
130149
@echo " CONSUMER_SRC Path to .c/.cpp file for the 'consumer' target"

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Specter
22

33
[![CI](https://github.com/Batchhh/libspecter/actions/workflows/ci.yml/badge.svg)](https://github.com/Batchhh/libspecter/actions/workflows/ci.yml)
4+
[![Crates.io](https://img.shields.io/crates/v/specter-mem.svg)](https://crates.io/crates/specter-mem)
45

56

67
ARM64 memory manipulation framework for iOS/macOS. Compiled as a static library (`libspecter.a`) consumed via a plain C/C++ header (`specter.h`).
@@ -9,10 +10,14 @@ Provides inline function hooking, stealth code patching, hardware breakpoints, m
910

1011
## Build
1112

13+
The release targets **iOS** (`aarch64-apple-ios`) and **macOS** (`aarch64-apple-darwin`).
14+
1215
```bash
1316
rustup target add aarch64-apple-ios # once
14-
make # release → target/aarch64-apple-ios/release/libspecter.a
15-
make debug
17+
make # builds both iOS and macOS (release)
18+
make ios # iOS only
19+
make macos # macOS only
20+
make debug # both targets (debug)
1621
make check # verify exported symbols match specter.h
1722
```
1823

@@ -26,6 +31,8 @@ make check # verify exported symbols match specter.h
2631

2732
[docs/usage.md](docs/usage.md) — C/C++ API reference and examples
2833

34+
[docs/rust.md](docs/rust.md) — Rust API reference and examples
35+
2936
[docs/architecture.md](docs/architecture.md) — Internal design and data flows
3037

3138
## Contributing

0 commit comments

Comments
 (0)