07-4-iOS逆向之自定义命令行工具

需求

做一个自定命令行, 能够打印Mach-O文件的架构

1. main 函数处理

1.1 通过Xcode创建一个Single View App 项目

int main(int argc, char * argv[]) {
    @autoreleasepool {
//        printf("%s\n", argv[0]);
        
        // 查看参数个数
        if (argc == 1) {
            printf("-l 查看 Mach-O 信息\n");
            return 0;
        }
        
        // 比较参数的值
        if (strcmp(argv[1], "-l") != 0) {
            printf("-l 查看 Mach-O 信息\n");
            return 0;
        }
        
        // Mach-O路径
        NSString *machOPath = @"/private/var/containers/Bundle/Application/2036E1A7-46E6-4205-BD0A-9A305598315A/Fission.app/Fission";
        
        // 1. 创建文件句柄
        // 文件句柄是一个字节一个字节地读取, 不需要把整个文件都加载到内存中, 节省内存
        NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:machOPath];
        NSLog(@"%@", handle);
    
        // 2. 处理文件内容
        // ...
        
        // 3. 关闭文件
        [handle closeFile];
        
        return 0;
    }
}

1.2 编译命令行

  • 选择真机设备编译
    在这里插入图片描述
  • 运行环境选择release
    在这里插入图片描述

1.3 编译, 找到命令行

在这里插入图片描述

1.4 测试命令行

  • 将可执行文件 TestCL 导入手机路径/usr/bin/
  • 注意 : 如果存在 TestCL 文件, 1. 先删除 2. 再导入, 不要直接拖进去替换
    在这里插入图片描述
  • 直接使用会报权限问题
    在这里插入图片描述
    • 给文件添加执行权限
    chmod +x /usr/bin/TestCL
    
  • 测试成功
    在这里插入图片描述

2. 读取魔数(magic number)

2.1 magic number: 魔数, 用来标识架构类型

2.2 查看可执行文件的魔数

  • 通过MachOView查看在这里插入图片描述

3. 通过内核源码比对魔数的值

  • 内核源码传送门

  • 下载最新的就可以了

  • 文件路径: xnu-xxx -> EXTERNAL_HEADERS -> mach-o -> fat.h 和 loader.h
    在这里插入图片描述
    在这里插入图片描述

  • 为啥有两个值? 大小端问题

  • 魔数对应代码

// 字节长度
/**
	按照posix标准,一般整形对应的*_t类型为:
	1字节     uint8_t
	2字节     uint16_t
	4字节     uint32_t
	8字节     uint64_t
  */
int length = sizeof(uint32_t);

// 读出最前面的4个字节(magic number)
NSData *magicData = [handle readDataOfLength:length];

// magic number : 魔数, 用来标识架构类型
uint32_t magicNumber;
[magicData getBytes:&magicNumber length:length];

// 输出架构类型
if (magicNumber == FAT_CIGAM || magicNumber == FAT_MAGIC) {
    printf("FAT文件\n");
} else if (magicNumber == MH_CIGAM_64 || magicNumber == MH_MAGIC_64) {
    printf("arm_64文件\n");
} else if (magicNumber == MH_MAGIC || magicNumber == MH_CIGAM) {
    printf("非arm_64文件\n");
} else {
    printf("读取失败\n");
}

4. 给TestCL文件添加SpringBoard权限

4.1 权限相关的问题

  • 为啥添加SpringBoard的权限,因为它的权限非常高, 可以任意访问其他App的文档路径
  • SpringBoard的路径:
    在这里插入图片描述
  • 苹果的权限文件大多以 .entitlements 结尾
.entitlements == .xml == .plist文件

4.2 导出Mach-O文件的权限

// -e : export 导出
// >  : 覆盖
// >> : 追加
ldid -e 可执行文件 > 可执行文件.entitlements

4.3 给可执行文件重新签上权限

// 注意: -S和可执行文件的权限文件要紧跟着,没有空格
ldid -S可执行文件权限文件 可执行文件

5. 报错总结

5.1 Bad CPU type in executable

  • 没有选择真机编译
    在这里插入图片描述

5.2 Killed: 9

  • 原因1 : 没有选择发布版本(release), 而选择了测试版本(debug)
  • 原因2 : 将TestCL文件导入手机时, 直接拖进去替换了原来的TestCL文件在这里插入图片描述

5.3 -sh: /usr/bin/ TestCL: Permission denied

  • 没有执行权限, 添加即可
chmod +x /usr/bin/TestCL

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值