美文网首页
iOS命令行工具开发

iOS命令行工具开发

作者: 可惜你不是我的双子座 | 来源:发表于2022-10-18 15:48 被阅读0次

    一、命令行工具的本质

    • 可执行文件
    • APP内部的可执行文件差不多

    二、权限问题

    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
    

    相关文章

      网友评论

          本文标题:iOS命令行工具开发

          本文链接:https://www.haomeiwen.com/subject/jwvjzrtx.html