Run an App as root on iOS

Hi everyone, what’s up!

After the writing of “Run a daemon (as root) on iOS”, some of you were asking about how to write an App with root privilege. So here comes the tutorial. Our target today is an App with root privileges. When you press a button, iOS reboots.

Part I Basic theory

1. App ownership

Please take a look at tutorial one if you have no idea what’s ownership. After reading that, you know all Apps under /Applications/ are owned by root:wheel.

Note, chown root:wheel is done by Theos’ fauxsu, which is necessary in this post and also explained in tutorial one!

2. User identifier

According to wikipedia and this page, we know that the owner of a file is different from the owner of a process, the latter of which is often referred to as user identifier.

So to run the App as root, we need to change the real user id or effective user id of the app to 0, you can think of them as parallel to “su root” and “sudo”.

Let’s take a look at the default user ids of an App.

3. setuid permission

According to this doc

When set-user identification (setuid) permission is set on an executable file, a process that runs this file is granted access based on the owner of the file (usually root), rather than the user who is running the executable file.

which provides a way to modify the user ids of a process. This is the key feature we’re making use of, soon you’ll see what we can do with it.

Part II Composing

First creat a new App with Theos.

FunMaker-MBP:Code snakeninny$
NIC 2.0 - New Instance Creator
  [1.] iphone/activator_event
  [2.] iphone/application_modern
  [3.] iphone/cydget
  [4.] iphone/flipswitch_switch
  [5.] iphone/framework
  [6.] iphone/ios7_notification_center_widget
  [7.] iphone/library
  [8.] iphone/notification_center_widget
  [9.] iphone/preference_bundle_modern
  [10.] iphone/tool
  [11.] iphone/tweak
  [12.] iphone/xpc_service
Choose a Template (required): 2
Project Name (required): iOSREbooter 
Package Name [com.yourcompany.iosrebooter]: com.naken.iosrebooter
Author/Maintainer Name [snakeninny]: snakeninny
[iphone/application_modern] Class name prefix (two or more characters) [XX]: RB
Instantiating iphone/application_modern in iosrebooter/...

Then modify the contents of RBRootViewController.m

- (void)addButtonTapped:(id)sender {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
	NSLog(@"iOSRE: %d, %d, %d", getuid(), geteuid(), system("reboot"));
#pragma GCC diagnostic pop	
	[_objects insertObject:[NSDate date] atIndex:0];
	[self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:0] ] withRowAnimation:UITableViewRowAnimationAutomatic];

Compile and install this App on your device. Launch iOSREbooter, hit the + button on the top right corner, and take a look at the output in syslog:

Sep 26 15:56:25 FunMaker-SE iOSREbooter[795] <Warning>: iOSRE: 501, 501, 256

Ok, the real user id and effective user id of process iOSREbooter are both 501, i.e. mobile, and reboot failed for sure. So how do we reset the user ids of this process? Yes, it’s setuid permission/bit, and all we need is a makefile feature, like this:

	$(ECHO_NOTHING)chmod +s $(THEOS_STAGING_DIR)/Applications/$(ECHO_END)

With this 2 lines of script, Theos will automatically set the setuid bit of our executable binary /Applications/

With setuid bit, we can call setuid() or seteuid() inside iOSREbooter to modify real/effective user ids. Let’s use setuid() this time:

Note, most of the time you only need to seteuid rather than setuid (Think about su root vs. sudo, but we don’t have sudo on iOS BTW)!

#import "RBAppDelegate.h"

int main(int argc, char *argv[]) {
	@autoreleasepool {
		return UIApplicationMain(argc, argv, nil, NSStringFromClass(RBAppDelegate.class));

And our Makefile looks like this:

export THEOS_DEVICE_IP = localhost
export THEOS_DEVICE_PORT = 2222
export ARCHS = armv7 arm64
export TARGET = iphone:clang:latest:8.0

include $(THEOS)/makefiles/

iOSREbooter_FILES = main.m RBAppDelegate.m RBRootViewController.m
iOSREbooter_FRAMEWORKS = UIKit CoreGraphics

include $(THEOS_MAKE_PATH)/

	$(ECHO_NOTHING)chmod +s $(THEOS_STAGING_DIR)/Applications/$(ECHO_END)

	install.exec "su mobile -c uicache"
	install.exec "killall \"iOSREbooter\"" || true

Compile and relaunch the app, you’ll find it crash at start. Why? The reason is that backboardd is running as mobile, it can’t launch a root process, so iOSREbooter got killed. How do we deal with this situation?

If you have ever looked close at or, you’ll know they run as root. What they do is making backboardd run a bash script, and the bash script launches the real root App, which bypasses iOS’ check. A simple bash script would be like this:

root=$(dirname "$0")
exec "${root}"/iOSREbooter

The only thing you need to do for customization is changing iOSREbooter to your App’s name. Easy huh?

One last thing, we tell backboardd to run this bash script instead of our executable. You may already guessed how: Change the value of key “CFBundleExecutable” in Info.plist to our bash script, like (“bash” is our bash script):

CFBundleExecutable = "bash";

The ultimate project tree looks like this:

Compile and run. Boom! Our iPhone reboots when you hit the + button.

Part III Conclusion

User identifications are rather complicated on iOS/OSX. I strongly suggest you read some documents about uids before making your App run as root, or it could cause unexpected problems. Have fun, but the risk is on your own.


12 个赞


1 个赞

我的工程是在 xcode 下建立的; 不能像您这样找到 makefile。

1.修改 main();setuid(0);
2.修改info.plist : bash
3.增加 bash; for profiling.



  1. App内调用setuid(0);
  2. 给App的可执行程序赋予setuid权限;
  3. 把Info.plist的可执行文件换成一个bash script,然后用bash script启动这个App的可执行文件
2 个赞

我在这个过程中,遇到了的困难主要就是:(已解决)“app 闪退”。 正如您所讲,应该是权限问题。
我参考了stackoverflow :

闪退的原因一般是因为SpringBoard无法启动具有root权限的App,因为SpringBoard仅有mobile权限。所以借助bash script可以绕开这个限制

我修改了文件权限 bash为0775 可执行文件为 6775 重启后 可以打开App 但是运行reboot的时候 仍旧提示没有权限问题 501, 501, 256



我按照楼主写的这个 rootapp 安装后,通过cydia 卸载。 重启手机后,不知道为啥: /Applications 目录全部被删掉了~~,所有的系统应用都没有了。但是之前安装游戏都还在。估计因为不是通过cydia安装的原因。
1.最重要的! 跪求恢复方法~~ 现在手机可以接电话,和短信,但是找不到 电话,信息,邮件,设置等等系统应用。。

当然了,楼主的demo 肯定没问题的,其他同学参考时候,不需要担心code 有问题~~

1 个赞


我是通过 mobileterminal 修改成功的。

我做了一个测试,当然了,前提是: 1.在xcode下写的测试代码
2.并且没有按照楼主所说的修改 makefile 文件(chmod )。。。
bash 和 rootapp必须要在 ios 中的 terminal 中修改权限,才可以启动app。
写好的app安装后,不可能让用户去点击修改权限~~,应该有什么脚本之类的修改权限,(我对脚本不了解,汗~),不知道bash中是否可以增加修改属性的代码呢?不过,好像也有问题,即使bash可以修改另外一个执行文件的权限为:chmod 6775 rootapp。 可是谁来修改bash的权限呢?》好像两个的权限都必须改。


1 个赞



  1. bash文件,必须由一个执行文件修改而来,具体方法可以是 复制一份RootApp 使用Hex Fiend 打开可执行文件,删干净里面的东西
root=$(dirname "$0")
exec "${root}"/RootApp

2.打包好的DEB安装进了/Applications/下面,实际上 里面的文件并不具备 root:wheel 这两个属性,你点开,还是会闪退

chmod +x xxx

2. 帖子里其实已经提到了,


backboardd[66] : Unable to obtain a task name port right for pid 416: (os/kern) failure (5)

给Makefile的after-stage加入一行chown完成文件所属设置。(这之后需要使用root用户来make && make package && make install)

$(ECHO_NOTHING)chmod +s $(THEOS_STAGING_DIR)/Applications/$(ECHO_END)
$(ECHO_NOTHING)chown root:wheel $(THEOS_STAGING_DIR)/Applications/$(ECHO_END)

-rw-r–r-- 1 mobile staff 423 Oct 15 02:00 Info.plist
-rwsr-sr-x 1 root wheel 14112 Oct 15 01:57 RootApp*
-rwxr-xr-x 1 mobile staff 55 Oct 14 01:32*


  1. mach-o文件具有s标记,
  2. mach-o文件属于root组,
  3. mach-o文件中调用setuid(0)
  4. 修改Info.plist 让backboardd先调用bash脚本,在脚本里再启动mach-o文件