美文网首页iOS 开发每天分享优质文章
iOS逆向-day7:iOS 命令行工具开发

iOS逆向-day7:iOS 命令行工具开发

作者: IIronMan | 来源:发表于2020-07-07 10:48 被阅读0次
    类似Clutch命令行工具的开发
    一、命令行工具的创建 和 main函数的处理
    • 1.1、我们利用 Xcode创建一个命令行工具,取名:JKCommandLine,我们利用Xcode 的iOS环境创建的目的是:让Xcode 帮我们配置好各种环境,比如:签名、一些权限 等等


      命令行项目的创建
      命令行项目的创建
    • 1.2、删除无用的文件

      删除无用的文件
      提示:main 函数里面我们返回了:return 0; 就是不需要界面的意思
    • 1.3、Command + B 获取可执行文件


      可执行文件
    • 1.4、一般我们要的是发布版本的可执行文件,我们可以修改


      release环境的配置
    • 1.5、我们把可执行文件拖到 用户手机目录下的 Device/usr/bin

      增加 命令行工具的可执行权限,我们李恩杰设备后可以执行如下命令

      chmod +x /usr/bin/JKCommandLine
      

      命令行工具的使用

      JKCommandLine
      
      命令行工具的使用g
    二、命令行功能分析
    • 2.1、功能分析,我们要获取一个 app 的架构 和 是否加壳,主要是根据头文件的前四个字节


    • 2.2、具体的代码实现

      #import <UIKit/UIKit.h>
      #import <mach-o/fat.h>
      #import <mach-o/loader.h>
      
      int main(int argc, char * argv[]) {
          @autoreleasepool {
              printf("JKCommandLine-------");
        
              NSString *appPath = @"/private/var/mobile/Containers/Bundle/Application/4BB74232-94B6-4465-87E7-AFE4F6E5C91D/WebToon.app/WebToon";
              NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:appPath];
        
              int length = sizeof(uint32_t);
              // 读取最前面额 4 个字节 (magic number, 魔数,用来标识文件类型)
              NSData *magicData = [handle readDataOfLength:length];
        
              // 魔数,用来标识文件类型
              uint32_t magicNumber;
              // 把 magicData 4个字节的数据放到 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("读取失败");
               }
        
               printf("----0x%x\n", magicNumber);
        
               // 关闭文件处理器
               [handle closeFile];
        
               // return 0:就是需要界面的意思
               return 0;
        
          }
      }
      
      • 提示:上面的代码在读取的时候会失败,如下,这是因为缺少权限的原因,后面在 给可执文件增加权限
    三、读取用户输入的参数
    • 3.1、在 main 函数里面会获取到参数

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

      第一个参数是固定的, argv [0] 是当前可执行文件的路径;当有参数的时候是从第二个参数开始的

    • 3.2、参数的设置
      一般来说,我们会在参数的前面会加一个 -,比如:我们常用的 Clutch,查看所有的 加壳的应用:Clutch -i

      那么我们也设置两个参数:-i-s

      #import <UIKit/UIKit.h>
      #import <mach-o/fat.h>
      #import <mach-o/loader.h>
      
      /// main函数
      /// @param argc 参数个数
      /// @param argv 存放参数的数组
      ///  argv [0] 是当前可执行文件的路径
      int main(int argc, char * argv[]) {
          @autoreleasepool {
        
             if (argc == 1) {
                 printf("-l 查看Macho 信息\n -s 查看Macho 信息\n");
                 return 0;
             }
             // 找不到对用的参数
             if (strcmp(argv[1], "-l") != 0 || strcmp(argv[1], "-s") != 0) {
                 printf("-l 查看Macho 信息\n -s 查看Macho 信息\n");
                 return 0;
             }
      
             // return 0:就是需要界面的意思
             return 0;
        
          }
      }
      
    四、给 Mach-0 文件增加 entitlements (权限)
    • 4.1、查看可执行文件的权限,这里我们使用的 ldid,当然也可以使用 codesign,下面我们以 JKCommandLine 为例,我们导出 JKCommandLine 权限,如下

      cd 进入 JKCommandLine 可执行文件的路径
      // 导出 JKCommandLine 可执行文件的权限
      ldid -e JKCommandLine > JKCommandLine.entitlements
      

      语法:导出权限:ldid -e 可执行文件名字 >> 可执行该文件的名字.entitlements,代表的意思是:将 可执行文件的权限导入到 可执行该文件的名字.entitlements 文件里面去

      查看可执行文件的权限
      我们可以看到 JKCommandLine的权限很少
      • 提示:一个 > 代表覆盖,两个 >> 代表追加到文件的尾部
      • 权限:entitlements == plist == xml
    • 4.2、我们可以看到普通的一个 可执行文件全新啊很低,那么如何增加可执行文件的权限呢?我们可以获取 SpringBoard 的权限,然后再赋给我们的可执行文件的权限

      • 获取 SpringBoard 可执行文件,在路径:Device/System/Library/CoreServices/SpringBoard.app
      • 获取 SpringBoard 权限

        cd 进入 SpringBoard 可执行文件的路径
        // 导出 SpringBoard 可执行文件的权限
        ldid -e SpringBoard > SpringBoard.entitlements 
        
        获取 SpringBoard 权限
      • 将 SpringBoard 的权限 签给 其他的可执行文件,比如签给 JKCommandLine ,如下,我们把 SpringBoard.entitlements 放到 JKCommandLine目录下

        cd 进入 JKCommandLine 可执行文件的路径
        ldid -SSpringBoard.entitlements JKCommandLine
        

        语法:重新签回权限:ldid -S可执行该文件的名字.entitlements 可执行该文件的名字,这里的签名仅仅是签权限
    • 4.3、测试 JKCommandLine 文件的,我们可以看到我们有了读取其他app的权限

    五、命令行工具的总结
    • 5.1、命令行工具的本质
      本质:可执行文件,跟app内部的可执行文件差不多

    • 5.2、测试一下其他app的可执行文件,比如爱奇艺

    六、拓展: MJAppTools

    源码地址:https://github.com/CoderMJLee/MJAppTools

    • 6.1、下载源码后,执行以下两种的任意一种方式


    • 6.2、复制编译后的生成的文件 MJAppTools 到 越狱手机的 iFunBox 的 usr/bin 目录下

    • 6.3、复制 MJAppTools 到 越狱手机的 iFunBox 的 usr/bin 目录下

    • 6.4、让 MJAppTools 具有执行的权利,终端链接越狱手机后,执行 chmod +x /usr/bin/MJAppTools

    • 6.5、MJAppTools 的使用


    • 6.6、JKAppTools 后面可以跟上图的命令,如 : -l <regex> 列出用户安装的应用

      JKAppTools -l
      

    相关文章

      网友评论

        本文标题:iOS逆向-day7:iOS 命令行工具开发

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