Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
SongXiaoXi committed May 10, 2022
0 parents commit d1720ec
Show file tree
Hide file tree
Showing 17 changed files with 3,700 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
arm64_runner
mach/
dyld
*.a
*.dylib
rt_spawn
DobbyX
dobby.h
13 changes: 13 additions & 0 deletions CydiaSubstrate.tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
archs: [ armv7, armv7s, arm64, arm64e, i386, x86_64 ]
platform: ios
install-name: /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate
current-version: 0.0.0
compatibility-version: 0.0.0
exports:
- archs: [ armv7, armv7s, arm64, arm64e, i386, x86_64 ]
symbols: [ _MSCloseImage, _MSDebug, _MSFindAddress, _MSFindSymbol,
_MSGetImageByName, _MSHookClassPair, _MSHookFunction,
_MSHookMemory, _MSHookMessageEx, _MSImageAddress,
_MSMapImage ]
...
130 changes: 130 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Reductant Translator
**Translate and patch arm64e binaries or macOS arm64 binaries to run on an arm64 iPhones at runtime.**

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.
You can run these utilities directly on arm64e iDevices, if there are dependent libraries on iOS. If not, it's this tool's turn:

- If your iDevice is arm64, you can run them with this tool.
- If your binaries are linked with macOS frameworks, you can run them with this tool and a dyld_shared_caches_arm64e from macOS.

You can replace **these binaries provided by me**:
- A patched dyld from macOS 11.4.
- A customized [Dobby](https://github.com/jmpews/Dobby) Framework.
- [mimalloc.a](https://github.com/microsoft/mimalloc) built for arm64 iOS.

## Build options in `build.sh`

- enable_dobby_hook Use a custom [Dobby Framework](https://github.com/jmpews/Dobby) to optimize a (CAS + B) sequence. This obviously improve performance.

Requirements: Xcode 12 or later.

## Environment variables

- `RT_OUT_OF_PROCESS=[whatever]` Do not inject threads in target process.
- `RT_EMULATE_TIME=[whatever]` Do not hook mach_continuous_time.
- `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.
- `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.
- `RT_DYLD_ROOT_PATH=[libraries to insert]` Pass this env to dyld as `DYLD_ROOT_PATH`.
- `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.
- `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.)
- `RT_DYLD_PATH=[dyld path]` Dyld path, default use a builtin dyld.
- `RT_DISABLE_DOBBY_HOOK=[whatever]` Disable dobby hook if the build option `enable_dobby_hook` is enabled.

The detail behaviors can be easly gotten in codes.

## Known issues

- NSURLSession will get a `kCFURLErrorCannotFindHost` error with macOS 11 dyld_shared_cache on iOS 13. (iOS 14 is OK.)
- 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.)
- `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.)
- 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()`.
- Code signing issues are dependent on your jailbreak tools.
- A bad mach-o may crash this tool.

## Example

``` sh
mobile@iPhone-7-Plus ~ % ./rt_spawn ./geekbench_aarch64
Geekbench 5.4.2 Corporate : https://www.geekbench.com/

System Information
Operating System macOS 14.8 (Build 18H17)
Model D11AP
Model ID D11AP
Motherboard D11AP

Processor Information
Name Apple processor
Topology 1 Processor, 2 Cores
Identifier Apple processor
Base Frequency 2.33 GHz
L1 Instruction Cache 64.0 KB
L1 Data Cache 64.0 KB
L2 Cache 3.00 MB

Memory Information
Size 2.93 GB


Single-Core
AES-XTS 1121 1.91 GB/sec
Text Compression 682 3.45 MB/sec
Image Compression 744 35.2 Mpixels/sec
Navigation 727 2.05 MTE/sec
HTML5 724 849.8 KElements/sec
SQLite 806 252.6 Krows/sec
PDF Rendering 112 6.07 Mpixels/sec
Text Rendering 824 262.7 KB/sec
Clang 673 5.24 Klines/sec
Camera 760 8.82 images/sec
N-Body Physics 413 517.1 Kpairs/sec
Rigid Body Physics 836 5181.6 FPS
Gaussian Blur 598 32.9 Mpixels/sec
Face Detection 896 6.90 images/sec
Horizon Detection 990 24.4 Mpixels/sec
Image Inpainting 1159 56.8 Mpixels/sec
HDR 1276 17.4 Mpixels/sec
Ray Tracing 934 750.1 Kpixels/sec
Structure from Motion 608 5.45 Kpixels/sec
Speech Recognition 545 17.4 Words/sec
Machine Learning 66 2.54 images/sec

Multi-Core
AES-XTS 1963 3.35 GB/sec
Text Compression 1097 5.55 MB/sec
Image Compression 1371 64.8 Mpixels/sec
Navigation 1222 3.44 MTE/sec
HTML5 1299 1.53 MElements/sec
SQLite 1438 450.7 Krows/sec
PDF Rendering 177 9.60 Mpixels/sec
Text Rendering 1455 463.5 KB/sec
Clang 1103 8.59 Klines/sec
Camera 1340 15.5 images/sec
N-Body Physics 723 904.0 Kpairs/sec
Rigid Body Physics 1496 9268.8 FPS
Gaussian Blur 1058 58.2 Mpixels/sec
Face Detection 1623 12.5 images/sec
Horizon Detection 1771 43.6 Mpixels/sec
Image Inpainting 1852 90.9 Mpixels/sec
HDR 2336 31.8 Mpixels/sec
Ray Tracing 1721 1.38 Mpixels/sec
Structure from Motion 1082 9.69 Kpixels/sec
Speech Recognition 832 26.6 Words/sec
Machine Learning 118 4.55 images/sec

Benchmark Summary
Single-Core Score 634
Crypto Score 1121
Integer Score 601
Floating Point Score 623
Multi-Core Score 1095
Crypto Score 1963
Integer Score 1030
Floating Point Score 1091

Upload results to the Geekbench Browser? [Y/n]
```

## Credits
- [iOS-run-macOS-executables-tools](https://github.com/zhuowei/iOS-run-macOS-executables-tools) for the idea and some implementation details.
- [Dobby](https://github.com/jmpews/Dobby) for the idea of single instruction hook.
78 changes: 78 additions & 0 deletions arm64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef __ARM64_h__
#define __ARM64_h__

#define BIT_MASK(bit_num) ((1 << ((bit_num))) - 1)

#define ARMv8_REG_MASK BIT_MASK(ARMv8_REG_BITS)
#define ARMv8_REG_BITS 5
#define ARMv8_REG_LR 30

#define ARMv8_RET_mask 0xfffffc1f
#define ARMv8_RET_base 0xd65f0000

#define ARMv8_RET(...) _ARMv8_RET_IMPL(0, ##__VA_ARGS__, ARMv8_REG_LR)
#define _ARMv8_RET_IMPL(ph, reg, ...) (0xd65f0000 | ((reg) << ARMv8_REG_BITS))
#define ARMv8_is_RET(instr) (((instr) & ARMv8_RET_mask) == ARMv8_RET_base)

#define ARMv8_NOP_mask 0xffffffff
#define ARMv8_NOP_base 0xd503201f
#define ARMv8_NOP() (ARMv8_NOP_base)
#define ARMv8_is_NOP(instr) ((instr) == ARMv8_NOP())

#define ARMv8_BLR_mask 0xfffffc1f
#define ARMv8_BLR_base 0xd63f0000
#define ARMv8_BLR(xs) (0xd63f0000 | ((xs) << ARMv8_REG_BITS))
#define ARMv8_is_BLR(instr) (((instr) & ARMv8_BLR_mask) == ARMv8_BLR_base)

#define ARMv8_BR_mask 0xfffffc1f
#define ARMv8_BR_base 0xd61f0000
#define ARMv8_BR(xs) (0xd61f0000 | ((xs) << ARMv8_REG_BITS))
#define ARMv8_is_BR(instr) (((instr) & ARMv8_BR_mask) == ARMv8_BR_base)

#define ARMv8_LDRi64_preindex_mask 0xffe00c00
#define ARMv8_LDRi64_preindex_base 0xf8400c00
#define ARMv8_LDRi64_preindex(xs, xd, imm12) (ARMv8_LDRi64_preindex_base | (imm12 << 12) | (xs << ARMv8_REG_BITS) | (xd))
#define ARMv8_is_LDRi64_preindex(instr) (((instr) & ARMv8_LDRi64_preindex_mask) == ARMv8_LDRi64_preindex_base)

#define ARMv8_LDRiu64_mask 0xffc00000
#define ARMv8_LDRiu64_base 0xf9400000
#define ARMv8_LDRiu64(Xt, Xn_SP, imm12) (ARMv8_LDRiu64_base | ((imm12) << 10) | ((Xn_SP) << 5) | (Xt))
#define ARMv8_is_LDRiu64(instr) (((instr) & ARMv8_LDRiu64_mask) == ARMv8_LDRiu64_base)

#define ARMv8_LDUR64_mask 0xffe00c00
#define ARMv8_LDUR64_base 0xf8400000
#define ARMv8_LDUR64(Xt, Xn_SP, imm9) (ARMv8_LDUR64_base | ((imm9) << 12) | ((Xn_SP) << 5) | (Xt))
#define ARMv8_is_LDUR64(instr) (((instr) & ARMv8_LDUR64_mask) == ARMv8_LDUR64_base)

#define ARMv8_LDAR_mask 0x3ffffc00
#define ARMv8_LDAR_base 0x8dffc00
#define ARMv8_LDAR(size, Rn_SP, Rt) (ARMv8_LDAR_base | ((size) << 30) | ((Rn_SP) << 5) | (Rt))
#define ARMv8_is_LDAR(instr) (((instr) & ARMv8_LDAR_mask) == ARMv8_LDAR_base)

#define ARMv8_CMP_er_mask 0x7fe0001f
#define ARMv8_CMP_er_base 0x6b20001f
#define ARMv8_is_CMP_er(instr) (((instr) & ARMv8_CMP_er_mask) == ARMv8_CMP_er_base)
#define ARMv8_CMP_i_mask 0x7f80001f
#define ARMv8_CMP_i_base 0x7100001f
#define ARMv8_is_CMP_i(instr) (((instr) & ARMv8_CMP_i_mask) == ARMv8_CMP_i_base)
#define ARMv8_CMP_sr_mask 0x7f20001f
#define ARMv8_CMP_sr_base 0x6b00001f
#define ARMv8_is_CMP_sr(instr) (((instr) & ARMv8_CMP_sr_mask) == ARMv8_CMP_sr_base)

#define ARMv8_is_CAS_family(instr) (((instr) & 0x3fa07c00) == 0x8a07c00)

#define ARMv8_is_CASP_family(instr) (((instr) & 0xbfa07c00) == 0x8207c00)

#define ARMv8_is_SWP_family(instr) (((instr) & 0x3f20fc00) == 0x38208000)

#define ARMv8_is_ldadd_family(instr) (((instr) & 0x3f20fc00) == 0x38200000)

#define ARMv8_is_LDSET_family(instr) (((instr) & 0x3f20fc00) == 0x38203000)

#define ARMv8_is_LDCLR_family(instr) (((instr) & 0x3f20fc00) == 0x38201000)

#define ARMv8_is_LDEOR_family(instr) (((instr) & 0x3f20fc00) == 0x38202000)

#define ARMv8_is_LDAPR_family(instr) (((instr) & 0x3ffffc00) == 0x38bfc000)

#endif //__ARM64_h__
Empty file added arm64_runner.s
Empty file.
49 changes: 49 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

set -e

rm -rf mach
mkdir mach
pushd mach
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/mach_exc.defs
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/task.defs
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/mach_port.defs
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/mach_vm.defs
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/thread_act.defs
mig -arch arm64 -DXNU_KERNEL_PRIVATE $(xcrun -sdk macosx --show-sdk-path)/usr/include/mach/vm_map.defs
popd

clang -O3 -std=gnu11 -flto -target arm64-apple-ios7.0 -Wall \
-isysroot "$(xcrun -sdk iphoneos --show-sdk-path)" \
-o rt_spawn \
littlespawn.c main.c dyldloader.c translator.c mach/mach_excServer.c -mcpu=apple-a7 -Wl,-sectcreate,__DATA,builtin_dyld,dyld
strip rt_spawn
ldid -Sent.xml rt_spawn
echo build hooker
hooker_sdk=iphoneos
if [ x$hooker_sdk == xiphoneos ]
then
libinject=CydiaSubstrate.tbd
else
libinject=libsubstitute.dylib
fi

enable_dobby_hook=true
if [ x$enable_dobby_hook == xtrue ]
then
CFLAGS="libmimalloc.a DobbyX -lc++ -DENABLE_DOBBY_HOOK=1"
else
CFLAGS=""
fi

clang -O3 -std=gnu11 -flto -march=armv8-a -target arm64-apple-ios9.0 -Wall \
-isysroot "$(xcrun -sdk $hooker_sdk --show-sdk-path)" \
-o rt_hooker.dylib \
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
ldid -S rt_hooker.dylib

as arm64_runner.s -o arm64_runner.o -target arm64-apple-ios7.0 -isysroot "$(xcrun -sdk $hooker_sdk --show-sdk-path)"
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
rm arm64_runner.o
strip arm64_runner
ldid -S arm64_runner
Loading

0 comments on commit d1720ec

Please sign in to comment.