What is special about roothide environments?
Roothide is a type of jailbreak distinct from rootful and rootless.
Differences from rootful/rootless
Unlike traditional jailbreaks, in roothide the "jailbreak root (jbroot)" and the "system root (rootfs)" are separate.
jbroot
is mounted inside rootfs
at a random path, and rootfs
is also bind-mounted back at jbroot/rootfs/
.
System root (rootfs)
In roothide, the system root is the iOS root directory. It is unmodified and contains no extra paths.
Jailbreak root (jbroot)
In roothide, jbroot
is mounted under rootfs
at a random path,
usually something like /var/containers/Bundle/Application/.jbroot-XXXXXXXXXXXXXXXX/
(X are random).
Use the jbroot
function to convert a normal path to its jbroot path.
For example, to access /var/mobile/Media/1.txt
inside jbroot, use jbroot("/var/mobile/Media/1.txt")
.
In a script, f = io.open(jbroot("/var/mobile/Media/1.txt"), "r")
will actually open:
/var/containers/Bundle/Application/.jbroot-XXXXXXXXXXXXXXXX/var/mobile/Media/1.txt
Shell environment
As mentioned, jbroot is mounted at a random path inside rootfs.
But in shell environments (e.g., deb install scripts), you cannot know where jbroot is mounted inside rootfs.
Therefore, roothide sets the shell runtime root to jbroot
.
That is, /Applications/XXTExplorer.app
in a deb will be installed to:
/var/containers/Bundle/Application/.jbroot-XXXXXXXXXXXXXXXX/Applications/XXTExplorer.app
This ensures jailbroken packages do not pollute the system root.
However, it introduces a problem when using os.execute
or io.popen
in XXTouch scripts,
since they execute via bash/zsh. For example, calling os.execute("/usr/bin/hidutil list")
will actually run:
/var/containers/Bundle/Application/.jbroot-XXXXXXXXXXXXXXXX/usr/bin/hidutil list
This prevents direct access to rootfs paths from shell.
To solve this, roothide bind-mounts the system root back to jbroot/rootfs/
.
Thus, os.execute("/rootfs/usr/bin/hidutil list")
will actually run:
/usr/bin/hidutil list
File and directory mirrors
Certain files/directories inside jbroot
are symlinked to the original rootfs
:
Path inside jbroot |
---|
/dev |
/private/preboot |
/var/containers |
/var/mobile/Containers |
/usr/share/misc/trace.codes |
/usr/share/zoneinfo |
/etc/hosts.equiv |
/etc/hosts |
/var/run/utmpx |
/var/db/timezone |
/System/Library/CoreServices/SystemVersion.plist |
In addition, XXTouch’s script root /var/mobile/Media/1ferver
in jbroot is also symlinked into rootfs.
These paths are accessible from both jbroot and rootfs.
Reference
XXTouch in Bootstrap environments
No auto-start
On devices using Bootstrap-Roothide semi-jailbreak, after rebooting and re-activating Bootstrap, XXTouch daemon does not auto-start. Open the XXTouch app; it will auto-exit and display "Starting XXTouch Daemon...". Within 20 seconds the daemon should be running.
No SpringBoard injection
If Bootstrap is used without enabling SpringBoard injection via Serotonin, UI-related script features are unavailable.
dialog
and webview
that create top-level UI will be affected.
alerthelper
cannot handle system alerts.
Use XXTouch to remove potentially detectable files in Bootstrap-Roothide
local noexecute = require('no_os_execute')
function remove_sys_app_caches(name)
noexecute.rm_rf('/var/root/Library/WebKit/'..name)
noexecute.rm_rf('/var/root/Library/Caches/'..name)
noexecute.rm_rf('/var/root/Library/HTTPStorages/'..name)
noexecute.rm_rf('/var/root/Library/SplashBoard/Snapshots/'..name)
noexecute.rm_rf('/var/root/Library/Saved Application State/'..name..'.savedState')
noexecute.rm_rf('/var/root/Library/Preferences/'..name..'.plist')
noexecute.rm_rf('/var/root/Library/WebKit/'..name)
noexecute.rm_rf('/var/mobile/Library/Caches/'..name)
noexecute.rm_rf('/var/mobile/Library/HTTPStorages/'..name)
noexecute.rm_rf('/var/mobile/Library/SplashBoard/Snapshots/'..name)
noexecute.rm_rf('/var/mobile/Library/Saved Application State/'..name..'.savedState')
noexecute.rm_rf('/var/mobile/Library/Preferences/'..name..'.plist')
end
remove_sys_app_caches('com.opa334.Dopamine')
remove_sys_app_caches('org.coolstar.SileoStore')
remove_sys_app_caches('ws.hbang.Terminal')
remove_sys_app_caches('pisshill.usprebooter')
remove_sys_app_caches('com.samiiau.loader')
remove_sys_app_caches('kr.xsf1re.vnodebypass')
remove_sys_app_caches('com.serena.Antoine')
remove_sys_app_caches('wiki.qaq.TrollFools')
remove_sys_app_caches('com.tigisoftware.Filza')
remove_sys_app_caches('com.tigisoftware.Filza000')
remove_sys_app_caches('com.tigisoftware.ADManager')
remove_sys_app_caches('com.ichitaso.otadisablerts')
remove_sys_app_caches('chaoge.ChargeLimiter')
noexecute.rm_rf('/private/var/mobile/Library/Filza')
noexecute.rm_rf('/private/var/mobile/.ssh')
noexecute.rm_rf('/private/var/root/.ssh')
noexecute.rm_rf('/private/var/mobile/offsets.txt')
noexecute.rm_rf('/private/var/mobile/offsets.txt')
noexecute.rm_rf('/private/var/mobile/Serotonin.jp2')
noexecute.rm_rf('/private/var/mobile/Documents/kfund_offsets.plist')
noexecute.rm_rf('/private/var/iomfb_bics_daemon')
Why do these files exist? Although roothide installs jailbreak apps under random jbroot paths, it does not confine their runtime to those paths. So after running, caches or other files may still be written to the corresponding locations in rootfs.
Apps may also detect the SSH port. If necessary, disable SSH in Bootstrap settings to avoid detection.