美文网首页iOS开发部落利器集合i like it
iOS逆向工程(工具介绍)- 学习整理

iOS逆向工程(工具介绍)- 学习整理

作者: ForestSen | 来源:发表于2016-05-10 18:23 被阅读5116次

    继续上一篇文章的内容,工具介绍篇:


    一、class-dump

    简介:顾名思义,就是用来导出目标对象的class信息的工具,私有方法声明也能导出来。

    原理:利用 Objective-C语言的 runtime 特性,将存 在Mach-O 文件中的头文件信息提 出来,并生成对应的 .h 文件。

    使用方法:
    1,下载然后将class-dump 复制到“ /usr/bin”目录下。
    2,执行sudo chmod 777 /usr/bin/class-dump”命令赋予其执行权限。
    3,class-dump执行:

    class-dump -S -s -H /Applications/Calculator.app -o 
    /Users/zhangdasen/Desktop/test
    

    4,上面一段代码就是导出Mac下计算器app的头文件,到桌面test文件夹,并且排序,class-dump的一些参数,大家可以自己在命令行输入class-dump然后回车就有相关说明。

    使用注意
    从 AppStore 下 的 App 都是经过加密的,可执行文件被加上了一层"壳"。
    class-dump 应付不了这样的文件,此时使用 class-dump 看上去会“失效”。还得先用别的工具把壳砸开才行,这个后面会说到。

    class-dump下载地址:http://stevenygard.com/projects/class-dump


    二、Theos越狱开发工具包

    简介
    Theos:是一个越狱开发工具包,由iOS越狱界知名人士Dustin Howett(@DHowett)开发并分享到 GitHub 上。

    iOSOpenDev:是整合在 Xcode里的越狱开发工具, 熟悉Xcode 的朋友可能会对它更感兴趣。但逆向工程接触底层知识较多,很多东西无法自动化,因此推荐使用整合度并不算高的 Theos,当你手动完成一个又一个练习时,对逆向工程的理解一定会更深。

    (1) Theos的安装:
    1,设置xcode
    假设安装了3 个 Xcode,并将它们分别命名为 Xcode1.app、Xcode2.app 和 Xcode3.app, 要指定 Xcode3 为活动 Xcode,则运行如下命令 :

    sudo xcode-select -s /Applications/Xcode3.app/Contents/Developer
    

    2, Theos下载
    从 GitHub 上下 Theos, 操作如下:(在终端中执行)

    export THEOS=/opt/theos 
    sudo git clone git://github.com/DHowett/theos.git $THEOS
    

    export THEOS=/opt/theos
    这句话是设置环境变量,上面两句话指的就是git克隆theos到系统的/opt/theos目录下.

    小问题:git 克隆下来的theos由于缺少文件,在后面make packget install 会提示缺少 _Prefix/NullabilityCompat.h 等文件,需要我们去https://github.com/theos/headers 把这个头文件放到/opt/theos/include目录中就行了。(可直接克隆到目录中去)

    sudo git clone https://github.com/theos/headers /opt/theos/include
    

    不过我这边已经有一个封好的theos,下面会提到。

    3,配置ldid
    ldid 是专门用来 名 iOS 可执行文件的工具,用以在越狱 iOS 中 代 Xcode 自带的codesign。从 http://joedj.net/ldid 下 ldid,把它放在“ /opt/theos/bin/ ”下,然后用以下命令赋予它可执行权限:

    sudo chmod 777 /opt/theos/bin/ldid
    

    4,配置CydiaSubstrate
    因为Theos 的一个 bug,它无法自动生成一个有效的 libsubstrate.dylib 文件,需要手动操作。
    在 Cydia 中搜索安装“CydiaSubstrate”,然后用 iFunBox 或 scp 等方式将 iOS 上的“/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate” 到 OSX 中,将其重命名为 libsubstrate.dylib 后放到
    “ /opt/theos/vendor/lib/libsubstrate.dylib”中, 替换掉无效的文件即可。

    5,dpkg-deb
    deb 是越狱开发安装包的标准格式,dpkg-deb 是一个用于操作 deb 文件的工具,有了这个工具,Theos 才能正确地把工程打包成为 deb 文件。
    https://raw.githubusercontent.com/DHowett/dm.pl/master/dm.pldm.pl,将其重命名为 dpkg-deb 后,放到“/opt/theos/bin/”目录下,然后用以下命令赋予其可执行权限:

    sudo chmod 777 /opt/theos/bin/dpkg-deb
    

    Theos操作这些移动文件设置权限这些步骤很啰嗦。
    鉴于这些,我自己这边已经封装了一个集成好的Theos,附带一个自动下载的小脚本TheosScript.sh,不需要手动添加ldid、libsubstrate、dpkg-deb等。
    脚本下载地址:https://github.com/DaSens/Theos-Script

    进行简单演示:


    进行简单演示

    (2) Theos的用法介绍:
    1,更改工作目录
    更改工作目录至常用的 iOS 工程目录(如 “ /Users/zhangdasen/Code/”)
    注:为何要做这一步呢,因为使用Theos创建的工程,是你在哪个目录执行的nic.pl启动的,就会在创建完成后在这个目录生成创建的Theos项目。

    2,创建工程
    终端输入“/opt/theos/bin/nic.pl”,启动 NIC(New Instance Creator),下面进行简单演示:


    3,简单说明
    上面创建工程输入了一大堆东西,下面用一张图来说明:


    4,工程文件说明
    创建好工程就会生成四个文件:
    Makefile、Tweak.xm、control、iOSREProject.plist 下面进行简单说明。

    ** (1) Makefile**
    Makefile 文件指定工程用到的文件、框架、库等信息,将整个过程自动化,下图为里面内容说明。
    下图是我自己修改过后的Makefile文件。


    补充:
    1,导入 private framework
     iOSREProject_PRIVATE_FRAMEWORKS = private framework name
    

    2,链接 Mach-O 对象(Mach-O object)

     iOSREProject_LDFLAGS = -lz –lsqlite3.0 –dylib1.o
    

    (2) Tweak.xm
    用 Theos 创建 tweak 工程, 认生成的源文件是 Tweak.xm。
    如果后缀名是单独一个“ x”,说明源文件支持 Logos 和 C 语法;
    如果后缀名是“ xm ”,说明源文件支持 Logos 和 C/C++ 语法,与“ m ”和“ mm ”的区别类似。
    Tweak.xm 语法众多,在这里简单介绍一些,详细语法大家可以去看书籍。
    ● %hook
    指定需要 hook 的 class, 必须以 %end 结尾

    %hook SpringBoard 
    - (void)_menuButtonDown:(id)down {
         NSLog(@"You've pressed home button.");
         %orig; // call the original _menuButtonDown: 
    }
    %end
    

    ● %orig该指 在 %hook 内部使用,执行被 (hook)的 数的原始代码,如下:

     %hook SpringBoard 
    - (void)_menuButtonDown:(id)down {
           NSLog(@"You've pressed home button.");
           %orig; // call the original _menuButtonDown: }
    %end
    

    还可以利用 %orig 更改原始 数的参数,例如:

     %hook SBLockScreenDateViewController 
    - (void)setCustomSubtitleText:(id)arg1 withColor:(id)arg2 {
             %orig(@"iOS 8 App Reverse Engineering", arg2); }
    %end
    
    这样一来, 锁屏界面原本显示日期的地方就变成了如图的样子。

    ● %group
    该指 用于将 %hook 分组,便于代码管理及按条件初始化分组(含义 后有 细解 ),必须以 %end 结 ;一个 %group可以包含多个 %hook,所有不 于某个自定义 group 的 %hook会被隐式归类到 %group _ungrouped 中。
    用法:

    %group iOS7Hook
    %hook iOS7Class 
    - (id)iOS7Method {
         id result = %orig; 
         NSLog(@"This class & method only exist in iOS 7."); 
         return result;
     } %end 
    %end // iOS7Hook
    
    %group iOS8Hook 
    %hook iOS8Class 
    - (id)iOS8Method {
       id result = %orig; 
       NSLog(@"This class & method only exist in iOS 8."); return result;
     }
    %end
    %end // iOS8Hook
    

    ● %init
    该指令用于初始化某个 %group,必须在 %hook 或 %ctor 内调用;如果带参数,则初始化指定的 group,如果不带参数,则初始化 _ungrouped,如下:

    #ifndef kCFCoreFoundationVersionNumber_iOS_8_0 
    #define kCFCoreFoundationVersionNumber_iOS_8_0 1140.10 #endif
    %hook SpringBoard 
    - (void)applicationDidFinishLaunching:(id)application {
     %orig; 
    %init; // Equals to %init(_ungrouped)
     if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_8_0)
          %init(iOS7Hook);
     if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0)
          %init(iOS8Hook);
    }%end
    只有调用了 %init,对应的 %group 才能起作用,切 切 !
    

    ● %new
    在 %hook 内部使用,给一个现有 class 加新函数,功能与 class_addMethod 相同。它的用法如下:

    %hook SpringBoard %new 
    - (void)namespaceNewMethod {
         NSLog(@"We've added a new method to SpringBoard."); 
    }
    %end
    

    ● %ctor
    tweak的constructor,完成初始化工作;如果不显式定义,Theos会自动生成一个%ctor,并在其中调用 %init(_ungrouped)。因此,
    %hook SpringBoard - (void)reboot {
    NSLog(@"If rebooting doesn't work then I'm screwed.");
    %orig;
    }
    %end
    可以成功生效,因为 Theos 隐式定义了如下内容:%ctor

    {
        %init(_ungrouped);
    }
    

    %hook SpringBoard
    - (void)reboot{
         NSLog(@"If rebooting doesn't work then I'm screwed.");
        %orig;
    }
    %end
    

    里的 %hook无法生效,因为这里显式定义了%ctor,却没有显式调用 %init,
    %group(_ungrouped) 不起作用。
    %ctor 一般可以用来初始化 %group,以及进行 MSHookFunction 等操作,如下:

    #ifndef kCFCoreFoundationVersionNumber_iOS_8_0 
    #define kCFCoreFoundationVersionNumber_iOS_8_0 1140.10 #endif
    %ctor{
    %init;
    if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_8_0)
       %init(iOS7Hook);
    if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) 
       %init(iOS8Hook);
    MSHookFunction((void *)&AudioServicesPlaySystemSound, (void *)&replaced_AudioServicesPlaySystemSound, (void **)&original_AudioServicesPlaySystemSound);
    }
    

    注意,%ctor 不需要以 %end 结 。

    ● %c
    该指 的作用等同于 objc_getClass 或 NSClassFromString,即动态获 一个类的定义,在 %hook 或 %ctor 内使用。

    (3) control文件
    control文件 录了deb包管理系统所需的基本信息,会被打包进deb包里。
    iOSREProject 里 control 文件的内容如下:


    control 文件中可以自定义的字段还有很多,但上面这些信息就已经足够了。更全面的
    说明可以参阅 debian 的官方网站(http://www.debian.org/doc/debian-policy/ch-controlfields.html)

    (3)iOSREProject.plist文件
    简单来说就是里面描述了tweak 的作用范围,也就是需要作用的APP的bundle identifier。
    也就是在创建项目的时候填写的这个地方:

    待续。。。。。。


    下个文章继续更新内容 ---- 手动HOOK一个自己的APP,和剩余越狱开发工具简单介绍。

    由于本书笔者还没看完呢,所以更新会比较慢,或者有段时间不更新,再次说明,整理这些内容只是为了自己方便查阅笔记,顺便分享给大家,没有它意,希望大家支持原版书籍。

    iOS逆向知识,千变万化,无穷无尽,需要学习的太多了,国内文章知识还是比较少,逆向的书籍也是比较少,逆向开发方面的进步也需要我们国人也要努力。

    参考书籍: <iOS应用逆向工程-第2版> 沙梓社 吴航 * 著
    感谢作者。

    相关文章

      网友评论

      • 谈Xx:class-dump我复制到usr/bin目录下不行,命令行也不行,该怎么做呢
        e7bb0060a85c:应该是放在usr/local/bin路径下面吧
        谈Xx:@品味_生活 权限问题, 搜到了
        ForestSen:@谈Xx 怎么个不行吧,报错,还是?
      • panv587:楼主,在iOS9.3.2系统下, 好多工具已经不能使用了。
        ForestSen:@EMTF僧人 9.3.2 没进行后期更新与测试,回头会整理下,或者大家先去逆向论坛,或者谷歌,百度搜下
      • e1d494fc09cd:sudo git clone git://github.com/DHowett/theos.git $THEOS 少了一个空格
        ForestSen:@一朵西兰花 多谢提醒
      • Orochello:楼主真是有心了,我有个疑问,这个在swift中还适用么
        ForestSen:@duoluock2014 class-dump 似乎目前还不能导出头文件,应该之后等普及后作者更新了不过hook 和ida 应该是可以的。 如果不确定,自己也可以测试下
      • 清無:好高端,没怎么懂。。。
        ForestSen:@菲拉兔 慢慢学习就行了,都是从零开始的
      • Fintecher:写得非常好。
      • Cuffy:mark
      • hrscy:请问怎样把class-dump 复制到“ /usr/bin”目录下呢?我出现这个错误Operation not permitted,请问怎么解决呢
        ForestSen:@ForestSen sudo
        hrscy:@品味_生活 好的,谢谢啦😄
        ForestSen:@hrscy 权限不够,还有 你可以不放到/usr/bin 这个目录下 也行的, 如果非要放,那就设置下权限 任何人都允许就行了!
      • 万年场保安:请问破壳用的什么?后面没提到呢
        dbb6461b6353:@保安保安 安卓更简单,jdx一步搞定了.自己搜索一下.
        万年场保安:请问大神还对android的砸壳有研究不。我发现好多技术都过时了
        ForestSen:@保安保安 用dumpdecrypted给App手动砸壳,后续,我会在后面文章提到,感兴趣,也可以自己先去自己了解下。

      本文标题:iOS逆向工程(工具介绍)- 学习整理

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