iOS命令行工具开发

2022-10-18  本文已影响0人  可惜你不是我的双子座

一、命令行工具的本质

二、权限问题

root# TestCL
-sh: /usr/bin/TestCL: Permission denied

赋值权限

root# chmod +x /usr/bin/TestCL

三、MachO识别

3.1、区别Mach-O文件格式

xnu源码中可以看出
magic number,魔数,用来标识文件类型

FAT文件
#define FAT_MAGIC   0xcafebabe
#define FAT_CIGAM   0xbebafeca  /* NXSwapLong(FAT_MAGIC) */

struct fat_header {
    uint32_t    magic;      /* FAT_MAGIC */
    uint32_t    nfat_arch;  /* number of structs that follow */
};
非64bit架构文件
/*
 * The 32-bit mach header appears at the very beginning of the object file for
 * 32-bit architectures.
 */
struct mach_header {
    uint32_t    magic;      /* mach magic number identifier */
    cpu_type_t  cputype;    /* cpu specifier */
    cpu_subtype_t   cpusubtype; /* machine specifier */
    uint32_t    filetype;   /* type of file */
    uint32_t    ncmds;      /* number of load commands */
    uint32_t    sizeofcmds; /* the size of all the load commands */
    uint32_t    flags;      /* flags */
};

/* Constant for the magic field of the mach_header (32-bit architectures) */
#define MH_MAGIC    0xfeedface  /* the mach magic number */
#define MH_CIGAM    0xcefaedfe  /* NXSwapInt(MH_MAGIC) */
64bit架构文件
/*
 * The 64-bit mach header appears at the very beginning of object files for
 * 64-bit architectures.
 */
struct mach_header_64 {
    uint32_t    magic;      /* mach magic number identifier */
    cpu_type_t  cputype;    /* cpu specifier */
    cpu_subtype_t   cpusubtype; /* machine specifier */
    uint32_t    filetype;   /* type of file */
    uint32_t    ncmds;      /* number of load commands */
    uint32_t    sizeofcmds; /* the size of all the load commands */
    uint32_t    flags;      /* flags */
    uint32_t    reserved;   /* reserved */
};

/* Constant for the magic field of the mach_header_64 (64-bit architectures) */
#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */
#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */

四、命令行工具添加参数

// argc : 参数的个数
// argv : 存放参数的数组
// argv[0] : 是当前可执行文件的路径
int main(int argc, char * argv[]) {
    @autoreleasepool {
}
}

五、编写命令行工具

#import <UIKit/UIKit.h>
#import <mach-o/fat.h>
#import <mach-o/loader.h>

// argc : 参数的个数
// argv : 存放参数的数组
// argv[0] : 是当前可执行文件的路径
int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        if (argc == 1) {
            printf("-l 查看Mach-O信息\n");
            return 0;
        }
        
        if (strcmp(argv[1], "-l") != 0) {
            printf("-l 查看Mach-O信息\n");
            return 0;
        }
        
        NSString *appPath = @"/var/containers/Bundle/Application/C531D4C7-BE48-4689-9820-B25164C7D9B9/DingTalk.app/DingTalk";
        NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:appPath];
        
        int length = sizeof(uint32_t);
        
        //读取最前面的4个字节(magic number,魔数,用来标识文件类型)
        NSData *magicData = [handle readDataOfLength:length];
        
        // 魔数,用来标识文件类型
        uint32_t magicNumber;
        [magicData getBytes:&magicNumber length:length];
        
        if (magicNumber == FAT_CIGAM || magicNumber == FAT_MAGIC) {
            // 大小端
            printf("FAT文件\n");
        } else if (magicNumber == MH_MAGIC || magicNumber == MH_CIGAM) {
            printf("非64bit架构文件\n");
        } else if (magicNumber == MH_MAGIC_64 || magicNumber == MH_CIGAM_64) {
            printf("64bit架构文件\n");
        } else {
            printf("读取失败\n");
        }
        
        printf("magicNumber = 0x%x\n", magicNumber);
        
        [handle closeFile];
        return 0;
    }
}

六、命令行工具添加权限

6.1、利用ldid添加权限

wenjian % ldid
usage: ldid -S[entitlements.xml] <binary>
   ldid -e MobileSafari
   ldid -S cat
   ldid -Stfp.xml gdb

6.2、获取SpringBoard权限

SpringBoard路径:/System/Library/CoreServices/SpringBoard.app/SpringBoard

wenjian % ldid -e SpringBoard > SpringBoard.entitlements

6.3、添加SpringBoard权限到命令行工具

wenjian % ldid -SSpringBoard.entitlements TestCL

七、运行结果

root# TestCL
-l 查看Mach-O信息
root# TestCL -l
64bit架构文件
magicNumber = 0xfeedfacf
上一篇下一篇

猜你喜欢

热点阅读