Skip to content

Commit d1720ec

Browse files
committed
Initial commit
0 parents  commit d1720ec

File tree

17 files changed

+3700
-0
lines changed

17 files changed

+3700
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
arm64_runner
2+
mach/
3+
dyld
4+
*.a
5+
*.dylib
6+
rt_spawn
7+
DobbyX
8+
dobby.h

CydiaSubstrate.tbd

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
archs: [ armv7, armv7s, arm64, arm64e, i386, x86_64 ]
3+
platform: ios
4+
install-name: /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate
5+
current-version: 0.0.0
6+
compatibility-version: 0.0.0
7+
exports:
8+
- archs: [ armv7, armv7s, arm64, arm64e, i386, x86_64 ]
9+
symbols: [ _MSCloseImage, _MSDebug, _MSFindAddress, _MSFindSymbol,
10+
_MSGetImageByName, _MSHookClassPair, _MSHookFunction,
11+
_MSHookMemory, _MSHookMessageEx, _MSImageAddress,
12+
_MSMapImage ]
13+
...

README.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Reductant Translator
2+
**Translate and patch arm64e binaries or macOS arm64 binaries to run on an arm64 iPhones at runtime.**
3+
4+
As Macs move to ARM, there are many official command-line tools from Apple, Homebrew or others. But the instructions in these binaries are at least ARMv8.3+ since the first arm Mac was based on A12z.
5+
You can run these utilities directly on arm64e iDevices, if there are dependent libraries on iOS. If not, it's this tool's turn:
6+
7+
- If your iDevice is arm64, you can run them with this tool.
8+
- If your binaries are linked with macOS frameworks, you can run them with this tool and a dyld_shared_caches_arm64e from macOS.
9+
10+
You can replace **these binaries provided by me**:
11+
- A patched dyld from macOS 11.4.
12+
- A customized [Dobby](https://github.com/jmpews/Dobby) Framework.
13+
- [mimalloc.a](https://github.com/microsoft/mimalloc) built for arm64 iOS.
14+
15+
## Build options in `build.sh`
16+
17+
- enable_dobby_hook Use a custom [Dobby Framework](https://github.com/jmpews/Dobby) to optimize a (CAS + B) sequence. This obviously improve performance.
18+
19+
Requirements: Xcode 12 or later.
20+
21+
## Environment variables
22+
23+
- `RT_OUT_OF_PROCESS=[whatever]` Do not inject threads in target process.
24+
- `RT_EMULATE_TIME=[whatever]` Do not hook mach_continuous_time.
25+
- `RT_DYLD_SHARED_CACHE_DIR=[path to dyld_share_cache]` Specify the dyld_share_cache path. It defaults to "/System/macOSSupport/dyld" if exists. Otherwise use the system one.
26+
- `RT_DYLD_INSERT_LIBRARIES=[libraries to insert]` Pass this env to dyld as `DYLD_INSERT_LIBRARIES`. Default is `/System/macOSSupport/usr/lib/rt_hooker.dylib` to support in-process translating and hooking, and other necessary patches.
27+
- `RT_DYLD_ROOT_PATH=[libraries to insert]` Pass this env to dyld as `DYLD_ROOT_PATH`.
28+
- `RT_ARM64_RUNNER_PATH=[path to a binary]` Creating a process with a arm64 binary. Then map the real binary arm64e default) into this process.
29+
- `RT_FORCE_ARM64_RUNNER=[whatever]` Creating a process with a arm64 binary. Then force map the real binary into this process. (arm64e only runs in this mode.)
30+
- `RT_DYLD_PATH=[dyld path]` Dyld path, default use a builtin dyld.
31+
- `RT_DISABLE_DOBBY_HOOK=[whatever]` Disable dobby hook if the build option `enable_dobby_hook` is enabled.
32+
33+
The detail behaviors can be easly gotten in codes.
34+
35+
## Known issues
36+
37+
- NSURLSession will get a `kCFURLErrorCannotFindHost` error with macOS 11 dyld_shared_cache on iOS 13. (iOS 14 is OK.)
38+
- Metal is not available except A12z or M1 iPad due to missing binary for `/System/Library/Extensions/AGXMetalxxx` in dyld_shared_cache. (I have not tested these iPad, maybe Metal parallel computing works.)
39+
- `fork()` and `spawn()` is not work properly which means you can not use bash/zsh or other utilities depended on them from macOS. (This can be fixed by hooking.)
40+
- Some libproc-based (such as `proc_pidinfo(PROC_PIDPATHINFO)`) processes viewer will only treat `arm64_runner` as the process executable. This cannot be fixed because XNU uses the vnode of the executable when `spawn()`.
41+
- Code signing issues are dependent on your jailbreak tools.
42+
- A bad mach-o may crash this tool.
43+
44+
## Example
45+
46+
``` sh
47+
mobile@iPhone-7-Plus ~ % ./rt_spawn ./geekbench_aarch64
48+
Geekbench 5.4.2 Corporate : https://www.geekbench.com/
49+
50+
System Information
51+
Operating System macOS 14.8 (Build 18H17)
52+
Model D11AP
53+
Model ID D11AP
54+
Motherboard D11AP
55+
56+
Processor Information
57+
Name Apple processor
58+
Topology 1 Processor, 2 Cores
59+
Identifier Apple processor
60+
Base Frequency 2.33 GHz
61+
L1 Instruction Cache 64.0 KB
62+
L1 Data Cache 64.0 KB
63+
L2 Cache 3.00 MB
64+
65+
Memory Information
66+
Size 2.93 GB
67+
68+
69+
Single-Core
70+
AES-XTS 1121 1.91 GB/sec
71+
Text Compression 682 3.45 MB/sec
72+
Image Compression 744 35.2 Mpixels/sec
73+
Navigation 727 2.05 MTE/sec
74+
HTML5 724 849.8 KElements/sec
75+
SQLite 806 252.6 Krows/sec
76+
PDF Rendering 112 6.07 Mpixels/sec
77+
Text Rendering 824 262.7 KB/sec
78+
Clang 673 5.24 Klines/sec
79+
Camera 760 8.82 images/sec
80+
N-Body Physics 413 517.1 Kpairs/sec
81+
Rigid Body Physics 836 5181.6 FPS
82+
Gaussian Blur 598 32.9 Mpixels/sec
83+
Face Detection 896 6.90 images/sec
84+
Horizon Detection 990 24.4 Mpixels/sec
85+
Image Inpainting 1159 56.8 Mpixels/sec
86+
HDR 1276 17.4 Mpixels/sec
87+
Ray Tracing 934 750.1 Kpixels/sec
88+
Structure from Motion 608 5.45 Kpixels/sec
89+
Speech Recognition 545 17.4 Words/sec
90+
Machine Learning 66 2.54 images/sec
91+
92+
Multi-Core
93+
AES-XTS 1963 3.35 GB/sec
94+
Text Compression 1097 5.55 MB/sec
95+
Image Compression 1371 64.8 Mpixels/sec
96+
Navigation 1222 3.44 MTE/sec
97+
HTML5 1299 1.53 MElements/sec
98+
SQLite 1438 450.7 Krows/sec
99+
PDF Rendering 177 9.60 Mpixels/sec
100+
Text Rendering 1455 463.5 KB/sec
101+
Clang 1103 8.59 Klines/sec
102+
Camera 1340 15.5 images/sec
103+
N-Body Physics 723 904.0 Kpairs/sec
104+
Rigid Body Physics 1496 9268.8 FPS
105+
Gaussian Blur 1058 58.2 Mpixels/sec
106+
Face Detection 1623 12.5 images/sec
107+
Horizon Detection 1771 43.6 Mpixels/sec
108+
Image Inpainting 1852 90.9 Mpixels/sec
109+
HDR 2336 31.8 Mpixels/sec
110+
Ray Tracing 1721 1.38 Mpixels/sec
111+
Structure from Motion 1082 9.69 Kpixels/sec
112+
Speech Recognition 832 26.6 Words/sec
113+
Machine Learning 118 4.55 images/sec
114+
115+
Benchmark Summary
116+
Single-Core Score 634
117+
Crypto Score 1121
118+
Integer Score 601
119+
Floating Point Score 623
120+
Multi-Core Score 1095
121+
Crypto Score 1963
122+
Integer Score 1030
123+
Floating Point Score 1091
124+
125+
Upload results to the Geekbench Browser? [Y/n]
126+
```
127+
128+
## Credits
129+
- [iOS-run-macOS-executables-tools](https://github.com/zhuowei/iOS-run-macOS-executables-tools) for the idea and some implementation details.
130+
- [Dobby](https://github.com/jmpews/Dobby) for the idea of single instruction hook.

arm64.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#ifndef __ARM64_h__
2+
#define __ARM64_h__
3+
4+
#define BIT_MASK(bit_num) ((1 << ((bit_num))) - 1)
5+
6+
#define ARMv8_REG_MASK BIT_MASK(ARMv8_REG_BITS)
7+
#define ARMv8_REG_BITS 5
8+
#define ARMv8_REG_LR 30
9+
10+
#define ARMv8_RET_mask 0xfffffc1f
11+
#define ARMv8_RET_base 0xd65f0000
12+
13+
#define ARMv8_RET(...) _ARMv8_RET_IMPL(0, ##__VA_ARGS__, ARMv8_REG_LR)
14+
#define _ARMv8_RET_IMPL(ph, reg, ...) (0xd65f0000 | ((reg) << ARMv8_REG_BITS))
15+
#define ARMv8_is_RET(instr) (((instr) & ARMv8_RET_mask) == ARMv8_RET_base)
16+
17+
#define ARMv8_NOP_mask 0xffffffff
18+
#define ARMv8_NOP_base 0xd503201f
19+
#define ARMv8_NOP() (ARMv8_NOP_base)
20+
#define ARMv8_is_NOP(instr) ((instr) == ARMv8_NOP())
21+
22+
#define ARMv8_BLR_mask 0xfffffc1f
23+
#define ARMv8_BLR_base 0xd63f0000
24+
#define ARMv8_BLR(xs) (0xd63f0000 | ((xs) << ARMv8_REG_BITS))
25+
#define ARMv8_is_BLR(instr) (((instr) & ARMv8_BLR_mask) == ARMv8_BLR_base)
26+
27+
#define ARMv8_BR_mask 0xfffffc1f
28+
#define ARMv8_BR_base 0xd61f0000
29+
#define ARMv8_BR(xs) (0xd61f0000 | ((xs) << ARMv8_REG_BITS))
30+
#define ARMv8_is_BR(instr) (((instr) & ARMv8_BR_mask) == ARMv8_BR_base)
31+
32+
#define ARMv8_LDRi64_preindex_mask 0xffe00c00
33+
#define ARMv8_LDRi64_preindex_base 0xf8400c00
34+
#define ARMv8_LDRi64_preindex(xs, xd, imm12) (ARMv8_LDRi64_preindex_base | (imm12 << 12) | (xs << ARMv8_REG_BITS) | (xd))
35+
#define ARMv8_is_LDRi64_preindex(instr) (((instr) & ARMv8_LDRi64_preindex_mask) == ARMv8_LDRi64_preindex_base)
36+
37+
#define ARMv8_LDRiu64_mask 0xffc00000
38+
#define ARMv8_LDRiu64_base 0xf9400000
39+
#define ARMv8_LDRiu64(Xt, Xn_SP, imm12) (ARMv8_LDRiu64_base | ((imm12) << 10) | ((Xn_SP) << 5) | (Xt))
40+
#define ARMv8_is_LDRiu64(instr) (((instr) & ARMv8_LDRiu64_mask) == ARMv8_LDRiu64_base)
41+
42+
#define ARMv8_LDUR64_mask 0xffe00c00
43+
#define ARMv8_LDUR64_base 0xf8400000
44+
#define ARMv8_LDUR64(Xt, Xn_SP, imm9) (ARMv8_LDUR64_base | ((imm9) << 12) | ((Xn_SP) << 5) | (Xt))
45+
#define ARMv8_is_LDUR64(instr) (((instr) & ARMv8_LDUR64_mask) == ARMv8_LDUR64_base)
46+
47+
#define ARMv8_LDAR_mask 0x3ffffc00
48+
#define ARMv8_LDAR_base 0x8dffc00
49+
#define ARMv8_LDAR(size, Rn_SP, Rt) (ARMv8_LDAR_base | ((size) << 30) | ((Rn_SP) << 5) | (Rt))
50+
#define ARMv8_is_LDAR(instr) (((instr) & ARMv8_LDAR_mask) == ARMv8_LDAR_base)
51+
52+
#define ARMv8_CMP_er_mask 0x7fe0001f
53+
#define ARMv8_CMP_er_base 0x6b20001f
54+
#define ARMv8_is_CMP_er(instr) (((instr) & ARMv8_CMP_er_mask) == ARMv8_CMP_er_base)
55+
#define ARMv8_CMP_i_mask 0x7f80001f
56+
#define ARMv8_CMP_i_base 0x7100001f
57+
#define ARMv8_is_CMP_i(instr) (((instr) & ARMv8_CMP_i_mask) == ARMv8_CMP_i_base)
58+
#define ARMv8_CMP_sr_mask 0x7f20001f
59+
#define ARMv8_CMP_sr_base 0x6b00001f
60+
#define ARMv8_is_CMP_sr(instr) (((instr) & ARMv8_CMP_sr_mask) == ARMv8_CMP_sr_base)
61+
62+
#define ARMv8_is_CAS_family(instr) (((instr) & 0x3fa07c00) == 0x8a07c00)
63+
64+
#define ARMv8_is_CASP_family(instr) (((instr) & 0xbfa07c00) == 0x8207c00)
65+
66+
#define ARMv8_is_SWP_family(instr) (((instr) & 0x3f20fc00) == 0x38208000)
67+
68+
#define ARMv8_is_ldadd_family(instr) (((instr) & 0x3f20fc00) == 0x38200000)
69+
70+
#define ARMv8_is_LDSET_family(instr) (((instr) & 0x3f20fc00) == 0x38203000)
71+
72+
#define ARMv8_is_LDCLR_family(instr) (((instr) & 0x3f20fc00) == 0x38201000)
73+
74+
#define ARMv8_is_LDEOR_family(instr) (((instr) & 0x3f20fc00) == 0x38202000)
75+
76+
#define ARMv8_is_LDAPR_family(instr) (((instr) & 0x3ffffc00) == 0x38bfc000)
77+
78+
#endif //__ARM64_h__

arm64_runner.s

Whitespace-only changes.

build.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
rm -rf mach
6+
mkdir mach
7+
pushd mach
8+
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/mach_exc.defs
9+
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/task.defs
10+
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/mach_port.defs
11+
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/mach_vm.defs
12+
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/thread_act.defs
13+
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/vm_map.defs
14+
popd
15+
16+
clang -O3 -std=gnu11 -flto -target arm64-apple-ios7.0 -Wall \
17+
-isysroot "$(xcrun -sdk iphoneos --show-sdk-path)" \
18+
-o rt_spawn \
19+
littlespawn.c main.c dyldloader.c translator.c mach/mach_excServer.c -mcpu=apple-a7 -Wl,-sectcreate,__DATA,builtin_dyld,dyld
20+
strip rt_spawn
21+
ldid -Sent.xml rt_spawn
22+
echo build hooker
23+
hooker_sdk=iphoneos
24+
if [ x$hooker_sdk == xiphoneos ]
25+
then
26+
libinject=CydiaSubstrate.tbd
27+
else
28+
libinject=libsubstitute.dylib
29+
fi
30+
31+
enable_dobby_hook=true
32+
if [ x$enable_dobby_hook == xtrue ]
33+
then
34+
CFLAGS="libmimalloc.a DobbyX -lc++ -DENABLE_DOBBY_HOOK=1"
35+
else
36+
CFLAGS=""
37+
fi
38+
39+
clang -O3 -std=gnu11 -flto -march=armv8-a -target arm64-apple-ios9.0 -Wall \
40+
-isysroot "$(xcrun -sdk $hooker_sdk --show-sdk-path)" \
41+
-o rt_hooker.dylib \
42+
hooker.c translator.c mach/mach_excServer.c libSystem/syscall.s libSystem/syscall.c mach/mach_vmUser.c mach/mach_portUser.c libSystem/libc.c mach/vm_mapUser.c mach/taskUser.c mach/thread_actUser.c libSystem/mach_time_legacy.c -DIN_PROCESS=1 -shared $libinject -fno-stack-check -fno-stack-protector -D_FORTIFY_SOURCE=0 -mcpu=apple-a7 -framework IOKit $CFLAGS
43+
ldid -S rt_hooker.dylib
44+
45+
as arm64_runner.s -o arm64_runner.o -target arm64-apple-ios7.0 -isysroot "$(xcrun -sdk $hooker_sdk --show-sdk-path)"
46+
ld -o arm64_runner arm64_runner.o -syslibroot "$(xcrun -sdk $hooker_sdk --show-sdk-path)" -e __mh_execute_header -lSystem -arch arm64 -platform_version ios 7.0.0 7.0.0 -dead_strip_dylibs
47+
rm arm64_runner.o
48+
strip arm64_runner
49+
ldid -S arm64_runner

0 commit comments

Comments
 (0)