Skip to content
Linux shell for iOS
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app Release build 52 to testflight May 12, 2019
emu Add coredump function for calling in the debugger May 12, 2019
fastlane Release build 52 to testflight May 12, 2019
fs Fix some compiler warnings May 12, 2019
iSH.xcodeproj Release build 52 to testflight May 12, 2019
jit Name default debug channel "verbose" May 12, 2019
kernel remove status argument from halt_system (#384) May 16, 2019
platform Implement /proc/meminfo Jan 6, 2019
subprojects Remove gdbm Nov 30, 2018
tests Implement bt[csr] for x86_64 Jan 13, 2019
tools Fix some compiler warnings May 12, 2019
util Implement fcntl file locks Feb 3, 2019
vdso VDSO related fixes for ptraceomatic May 12, 2019
.editorconfig apply 4 space to everything, utf-8 May 14, 2019
.gitignore Update to GDBM 1.18 Sep 30, 2018
.lvimrc Replace exrc with lvimrc Nov 16, 2017
.travis.yml Use an older version of meson on macOS Mar 18, 2019
CHANGELOG.md Update changelog Feb 12, 2019
ISSUE_TEMPLATE.md
LICENSE Use GPL, not LGPL Oct 11, 2018
LICENSE.IOS Add license terms to allow App Store distribution Nov 10, 2018
README.md Make it easy to change the bundle ID May 11, 2019
debug.h Name default debug channel "verbose" May 12, 2019
ish-gdb.gdb Ignore SIGPIPE in gdb Sep 30, 2018
main.c Add flags option to mount May 2, 2019
meson.build Stub reboot(2) Apr 8, 2019
meson_options.txt Merge branch 'jit' Aug 13, 2018
misc.h Mark unused function arguments Jan 6, 2019
xX_main_Xx.h Make the session automatically restart May 5, 2019
xcode-meson.sh Use an older version of meson on macOS Mar 18, 2019

README.md

iSH

Build Status goto counter fuck counter

A project to get a Linux shell running on iOS, using usermode x86 emulation and syscall translation.

For the current status of the project, check the issues tab, and the commit logs.

You can join the Testflight beta now. There's also a Discord server.

Hacking

You'll need these things to build the project:

  • Python 3
  • Ninja
  • Yarn (only when building for iOS)
  • Meson (pip install meson)
  • Clang and LLD (on mac, brew install llvm, on linux, sudo apt install clang lld or sudo pacman -S clang lld or whatever)
  • sqlite3 (this is so common it may already be installed on linux and is definitely already installed on mac. if not, do something like sudo apt install libsqlite3-dev)

Build for iOS

Open the project in Xcode and click Run. If you're not me, first open the project build settings and change the Product Bundle Identifier to something unique. There are scripts that should do everything else automatically. If you run into any problems, open an issue and I'll try to help.

Build command line tool for testing

To set up your environment, cd to the project and run meson build to create a build directory in build. Then cd to the build directory and run ninja.

To set up a self-contained Alpine linux filesystem, download the Alpine minirootfs tarball for i386 from the Alpine website and run the tools/fakefsify.py script. Specify the minirootfs tarball as the first argument and the name of the output directory as the second argument. Then you can run things inside the Alpine filesystem with ./ish -f alpine /bin/login -f root, assuming the output directory is called alpine.

You can replace ish with tools/ptraceomatic to run the program in a real process and single step and compare the registers at each step. I use it for debugging. Requires 64-bit Linux 4.11 or later.

A note on the JIT

Possibly the most interesting thing I wrote as part of iSH is the JIT. It's not actually a JIT since it doesn't target machine code. Instead it generates an array of pointers to functions called gadgets, and each gadget ends with a tailcall to the next function; like the threaded code technique used by some Forth interpreters. The result is a speedup of roughly 3-5x compared to pure emulation.

Unfortunately, I made the decision to write nearly all of the gadgets in assembly language. This was probably a good decision with regards to performance (though I'll never know for sure), but a horrible decision with regards to readability, maintainability, and my sanity. The amount of bullshit I've had to put up with from the compiler/assembler/linker is insane. It's like there's a demon in there that makes sure my code is sufficiently deformed, and if not, makes up stupid reasons why it shouldn't compile. In order to stay sane while writing this code, I've had to ignore best practices in code structure and naming. You'll find macros and variables with such descriptive names as ss and s and a. Assembler macros nested beyond belief. And to top it off, there are almost no comments.

So a warning: Long-term exposure to this code may cause loss of sanity, nightmares about GAS macros and linker errors, or any number of other debilitating side effects. This code is known to the State of California to cause cancer, birth defects, and reproductive harm.

You can’t perform that action at this time.