iOS 获取root权限

首先感谢 https://www.diffit.cn/2019/10/09/RunAppAsRootForXcode/ 作者 帮助我解决了困扰我很久的root权限问题 就有一点entitlements签名有点困惑 文件位置不是很清晰 本篇文章只是注明entitlements的文件位置

同时拓展了在root权限下获取UDID之类的api

本文demo,欢迎star

注意事项

  • 测试环境
  • macOS: 10.14.6
  • iPhoneOS: iOS11.0、iOS12.0、
  • iPhone机型:两个iPhone6
  • 越狱工具:unc0ver3.6.2
  • 没有测试:iOS13和iOS10,也许可以。
  • 关于链接
    • 阅读本文前,请首先阅读 RunAppAsRootForTheos理论部分
    • 此文使用Xcode新建的App,如果使用Theos新建的App,请转入RunAppAsRootForTheos
  • 实现目标:点击按钮执行killall -9 SpringBoard,注销SpringBoard

App代码

  • 本案例中使用Xcode新建的项目名称叫RootApp
  • 在Xcode中找到main.m,添加setuid(0),设置uid
#import "RARootViewController.h"
#import 

#import 
extern CFTypeRef MGCopyAnswer(CFStringRef);
@interface RARootViewController ()

@end
@implementation RARootViewController {
    NSMutableArray *_objects;
}

- (void)loadView {
    [super loadView];

    _objects = [NSMutableArray array];

    self.title = @"Root View Controller";
    self.navigationItem.leftBarButtonItem = self.editButtonItem;
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addButtonTapped:)];
}
int spawn(const char* executable, ...) {
    int     ret;
    pid_t   pid;
    va_list args;
    va_start(args, executable);
    ret = posix_spawn(&pid, executable, NULL, NULL, (char* const *)args, NULL);
    if (ret == 0) waitpid(pid, NULL, 0);
    return ret;
}

- (void)addButtonTapped:(id)sender {
    [_objects insertObject:[NSDate date] atIndex:0];
    [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:0] ] withRowAnimation:UITableViewRowAnimationAutomatic];

     NSDictionary *dic = [self getDeviceInfo];
     NSLog(@"HardwareID %@",dic);
    
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Info" message:dic.description delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
     [alert show];
    // NSLog(@"RootAppTest: %d, %d, %d", getuid(), geteuid(), spawn("/usr/bin/killall","/usr/bin/killall", "-9", "SpringBoard", NULL));
    
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    id alertbutton = [alertView buttonTitleAtIndex:buttonIndex];
    if (buttonIndex == 1) {
        NSLog(@"RootAppTest: %d, %d, %d", getuid(), geteuid(), spawn("/usr/bin/killall","/usr/bin/killall", "-9", "SpringBoard", NULL));
    }
   
}
#pragma mark - Table View Data Source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _objects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NSDate *date = _objects[indexPath.row];
    cell.textLabel.text = date.description;
    return cell;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    [_objects removeObjectAtIndex:indexPath.row];
    [tableView deleteRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic];
}

#pragma mark - Table View Delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}



//获取udid



/**
*
*/
- (NSDictionary*)getDeviceInfo{
   
    NSString *strUDID = [self getUDID];
    NSString *strSN = [self getSerialNumber];
    
    NSString *strWifiAddress = [self getWifiAddress];
    NSString *strBlueAddress = [self getBluetoothAddress];
    
    if (strUDID == nil) {
        strUDID = @" ";
    }
    
    if (strSN == nil) {
        strSN = @" ";
    }
    
    if (strWifiAddress == nil) {
        strWifiAddress = @" ";
    }
    
    if (strBlueAddress == nil) {
        strBlueAddress = @" ";
    }
    
    NSLog(@"RootAppTest: getuid——%d, geteuid——%d", getuid(), geteuid());
    
    NSMutableDictionary *dictDeviceInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                           strUDID,@"UDID",
                                           strSN,@"SerialNumber",
                                           strWifiAddress,@"WifiAddress",
                                           strBlueAddress,@"BlueAddress",
                                           [NSString stringWithFormat:@"%d",getuid()],@"getuid()",
                                           [NSString stringWithFormat:@"%d",geteuid()],@"geteuid()",
                                           nil];
    return dictDeviceInfo;
}

-(NSString*)getUDID{
    
    NSString *str = @"UniqueDeviceID";
    CFStringRef result = MGCopyAnswer((__bridge CFStringRef)str);
    
    return (__bridge NSString *)(result);
}

-(NSString*)getSerialNumber{
    
    NSString *str = @"SerialNumber";
    CFStringRef result = MGCopyAnswer((__bridge CFStringRef)str);
    
    return (__bridge NSString *)(result);
}

-(NSString*) getIMEI{
    
    NSString *str = @"InternationalMobileEquipmentIdentity";
    CFStringRef result = MGCopyAnswer((__bridge CFStringRef)str);
    
    
    return (__bridge NSString *)(result);
}

-(NSString*) getWifiAddress{
    
    NSString *str = @"WifiAddress";
    CFStringRef result = MGCopyAnswer((__bridge CFStringRef)str);
    
    
    return (__bridge NSString *)(result);
}

-(NSString*) getBluetoothAddress{
    
    NSString *str = @"BluetoothAddress";
    CFStringRef result = MGCopyAnswer((__bridge CFStringRef)str);
    
    return (__bridge NSString *)(result);
}


@end

  • 代码写完后,进行编译,编译完成后把RootApp.app放入iPhone上的/Applications里面

运行App

  • SSH登录iPhone,执行以下命令,要不然看不到App图标
~ root# uicache

  • 更改二进制文件权限,要不然App不能启动
~ root# chmod 755 /Applications/RootApp.app/RootApp
  • 至此App可以成功打开

设置euid

~ root# chmod u+s /Applications/RootApp.app/RootApp
  • 执行killall -9 SpringBoard,然后重新打开App,点击按钮,这个时候打印出来uid和euid为0
  • 虽然uid和euid为0但是不能注销SpringBoard,因为需要可执行文件签权

可执行文件签权

  • 新建RootApp.entitlements文件,内容为




    com.apple.private.security.no-container
    
    com.apple.private.skip-library-validation
    
    platform-application
    


  • 将RootApp.entitlements放到app文件内
ldid -SRootApp.entitlements RootApp
  • 如下图


    image.png

你可能感兴趣的:(iOS 获取root权限)