美文网首页
iOS 逆向开发的点点滴滴

iOS 逆向开发的点点滴滴

作者: 7c205247047d | 来源:发表于2018-06-20 11:55 被阅读0次

    Cycript

    • 找到当前界面上的所有对象
    cy# UIApp.keyWindow.recursiveDescription.toString
    

    通过控件的 nextResponder 查找视图控制器

    • 打印当前控制器下的所有控制器
    cy# [UIApp.keyWindow.rootViewController _printHierarchy].toString()
    

    hook 脚本根据头文件生一个 xm 文件,hook 所有头文件的方法

    • 第一种方法

    路径:opt/theos/bin/logify.pl
    logify.pl 头文件路径 > ./hookHeader.xm
    生成之后拖入工程编译之后生成mm 文件,在拖入动态库中

    • 第二种方法

    在工程 Config/MethodTraceConfig.plist 文件下修改
    ENABLE_METHODTRACE --》 YES
    TARGET_CLASS_LIST 下添加要 hook 的文件头名称


    • 配置环境变量

    配置环境变量是使用如下命令:
    vim ~./bash_profile
    在OSX下,我们用如下命令打开环境变量配置文件:
    open ~/.bash_profile
    最后,别忘了编译下
    source .bash_profile


    • 查看函数调用栈

    恢复符号表
    在终端控制器 restore-symbol 文件路径下执行 make restore-symbol
    生成可执行文件restore-symbol
    在通过restore-symbol可执行文件把项目可执行文件恢复符号表
    ./restore-symbol wechat_arm64 -o wechat_symbol(恢复符号表之后新的执行文件)

    要恢复符号表必须是单一架构的 mach-O文件
    查看支持架构 lipo -info wechat
    拆分架构 lipo wechat -thin arm64 - output wechat_arm64


    • 恢复 block 符号表
    1. 使用此脚本 ida_search_block.py,在 ida 中执行


    1. 生成block_symbol.json文件


    1. 在终端控制台输入命令生成 Mach-O 文件



    LLDB
    bt查看函数调用栈

    • 之所以能够 LLDB 动态调试,是因为有 debugSever 在程序中启动,如果不让它启动就会伞退,起到反调试的作用。

    • 导出执行文件的头文件
    class-dump -H 执行文件名 -o 导出的路径
    



    1. ssh

    • Apple File Conduit "2" 安装插件,可以在 mac 获取 root 权限目录
    • AppSync Unified 安装插件,可以绕过一些验证(签名机制),手机越狱之后的验证机制就被破坏了。
    • OpenSSH 安装插件,主要作用通过 openSSH 能连接(登录)手机,能够访问手机的所有东西


    // 在完美越狱的手机下
    ssh 用户名@IP地址
    ssh root@192.168.21.111 通过具体IP地址是 wifi 连接
    登录之后输入密码,默认密码为 alpine
    
    //删除服务器对应的公钥
    ssh-keygen -R 服务器 IP 地址
    
    iOS下有两个用户 root 最高权限的用户和 mobile 用户
    exit ;退出
    文件的读写权限只有 root 才可以操作
    ifunbox
    // 在 root 下修改密码
    passwd ;再输入两次新密码之后修改成功}
    

    ssh
    ssh 是一种网络协议,用于计算机之间的加密登录

    openSSH
    openSSH 其中一种软件

    中间人攻击

    中间人攻击

    预防中间人攻击最有效的方法就是验证公钥是不是服务器的
    如果是公开的 SSH 服务器,一般会将公钥的哈希值会公布在网站上的

    ssh 使用公钥登录
    除了使用密码登录,也可以免密登录
    所谓的公钥登录,原理:
    1.mac 电脑将自己的公钥发给远程的手机
    2.手机随机的生成一段字符串,发给 mac 电脑
    3.Mac 电脑利用私钥加密字符串
    4.手机利用公钥解密字符串,如果能对得上,就成功了
    如果还要输入密码的,设置文件的权限 chmod 755

    //非完美越狱的 ssh 连接
    ssh root@localhost -p 2222
    //文件拷贝
    scp -P 2222 123.text root@localhost:~/

    App瘦身
    1.先拆执行文件
    lipo xx -thin arm64 -output xx_arm64
    2.打包 ipa 包
    zip -ry xx.ipa Payload


    2.cycript

    • 在手机终端下无法输入中文的解决:导入 .inputrc文件到越狱手机的 root 路径中
    //.inputrc 文件包含内容
    set convert-meta off
    set output-meta on
    set meta-flag on
    set input-meta on
    
    • 要使用 vim 就要在越狱手机上安装Vi IMproved 插件

    • 安装 adv-cmds 插件一定要安装,是一个命令行工具包,可以使用终端指令

    • 安装 Cycript 插件,可以使用 cycript

    • 在登录手机终端下,输入:

    ps -A //查看所有进程
    ps -A | grep XX //过滤进程
    
    • 连接某个进程的方法
    //第一种连接方式,根据进程名称
    cycript -p WeChat
    //第二种连接方式,根据进程ID
    cycript -p 2365
    
    //退出连接:control + D
    

    在 cycript 中可以添加函数,会依附在某个进程里面,进程退出之后就失效


    WX20180607-113016@2x.png
    • cy文件
      1.把 cy 文件放入手机路径/usr/lib/cycript0.9中
      2.在终端输入@import xx(cy文件名)
    //cy文件内容
    rootvc = function() {
        return UIApp.keyWindow.rootViewController;
    };
    
    keyWindow = function() {
        return UIApp.keyWindow;
    };
    
    APPID = [[NSBundle mainBundle] bundleIdentifier];
    
    currentvc = function() {
        var tempcurrentvc;
        var temprootvc = UIApp.keyWindow.rootViewController;
        var next = YES;
        while(next) {
            if ([temprootvc presentedViewController]) {
                temprootvc = [temprootvc presentedViewController];
            }
            if ([temprootvc isKindOfClass:[UITabBarController class]]) {
                temprootvc = [temprootvc selectedViewController];
            } else if ([temprootvc isKindOfClass:[UINavigationController class]]){
                temprootvc = [temprootvc topViewController];
            }  else {
                next = NO;
                tempcurrentvc = temprootvc;
            }
        }
        return tempcurrentvc;
    };
    

    • 砸壳:加密的 app 是无法 class-dump,class-dump 可以导出头文件

    静态的方法:Clutch
    1.下载 Clutch-2.0.4,拷贝到手机root@localhost:/usr/bin 目录下
    2.mv Clutch-2.0.4 Clutch //重命名
    3.执行权限 chmod +x Clutch
    4.Clutch -i ;查询加密的 APP(没有砸壳的)
    5.Clutch -d 使用序列号或者 bundleID
    6.得到砸壳后的 ipa 文件,拷贝出来
    7.在 Mac 终端下验证查看执行文件信息是否加密,otool -l xxx | grep crypt

    动态的方法:dumpdecrypted
    1.下载dumpdecrypted(https://github.com/stefanesser/dumpdecrypted),解压之后,执行在当前目录下终端执行 make
    2.得到一个dumpdecrypted.dylib文件,拷贝到手机:
    scp -P 2222 dumpdecrypted.dylib root@localhost:~/
    3.依附到某个进程插入动态库dumpdecrypted.dylib,
    DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib 进程的路径(ps -A 可以查看进程路径)
    4.到当前目录下得到 xxx.decrypted的新文件

    • dumpdecrypted砸壳出现的问题一:



      解决方案:

    ## 列出可签名证书
    security find-identity -v -p codesigning
    ## 为dumpecrypted.dylib签名
    codesign --force --verify --verbose --sign "iPhone Developer: xxx xxxx (xxxxxxxxxx)" dumpdecrypted.dylib
    

    然后重新上传dumpdecrypted.dylib到手机,再重新砸壳


    • 写插件

    • Homebrew
    // 安装 Homebrew
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    

    常用的方式
    brew install ldid 安装
    brew uninstall ldid 卸载
    brew search ldid 搜索
    brew upgrade ldid 更新
    brew list 查看列表
    brew update 更新 Homebrew

    • Theos

    // 安装 Theos
    https://github.com/theos/theos/wiki/Installation
    
    • 创建插件过程:
      • 1.在Mac 桌面上创建一个 theosdemo 文件目录,在此目录下进入终端

      • 2.输入 nic.pl


      • 3.输入11,选择创建 tweak,并依此输入Project Name、Package Name、uthor/Maintainer Name、MobileSubstrate Bundle filter等信息,最后得到文件wechatpwdtweak(Package Name工程名是自己定义的)


      • 4.修改工程下的内容


      • 5.修改完之后就在终端下执行:make ;编译一下


      • 6.在执行打包指令:make package


      • 7.make install:安装插件到手机,就完成了


    关于Theos的坑!!!!
    1.不要在中文目录下编译工程.否则报错!
    2.packageName(包名称),全部小写!!!
    
    **打包的问题:make package
    Error:  IO::Compress::lzma
    解决方案两种:
    
    1.安装xz
    $ brew install xz
    $ sudo cpan IO::Compress::Lzma
    
    2. 改变压缩方式
    2.1修改dm.pl 文件
    vim $THEOS/$THEOS/vendor/dm.pl/dm.pl
    #use IO::Compress::Lzma;
    #use IO::Compress::Xz;
    2.2修改deb.mk 文件
    vim $THEOS/makefiles/package/deb.mk
    修改为:
     _THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= gzip
    
    **编译的问题:make 
    Error: You do Not an SDK
    需要指定Xcode . 安装过MonkeyDev 
    
    clean 清除缓存!
    

    • 文件拷贝:

    1.电脑拷贝到手机
    scp -P 2222 xxx root@localhost:~/

    2.手机拷贝到电脑
    scp -P 2222 root@localhost:~/xxx ~/Desktop

    查看执行文件架构
    file xxx


    • 越狱手机之后添加源和插件
      • 添加源

      • 安装插件

        • Apple File Conduit "2" 插件:可以在 mac 获取 root 权限目录
        • AppSync Unified 插件:可以绕过一些验证(签名机制),手机越狱之后的验证机制就被破坏了。
        • OpenSSH 插件:主要作用通过 OpenSSH 能连接(登录)手机,能够访问手机的所有东西
        • Cycript 插件

    LLDB 调试

    Xcode: LLDB
    手机: APP、debugserver
    LLDB->debugserver->APP

    cd /Developer/usr/bin
    
    • debugserver 连接 APP
      • debugserver *:端口号 -a 进程
        • *:端口号。使用手机的某个端口提供服务
        • -a 进程:连接的 APP(进程 ID,进程名称--MachO 文件名称)
    ./debugserver *:12346 -a WeChat
    
    

    iOS 攻防策略

    动态库能够被加载,而且调用:
    如果一个应用的二进制被修改了注定要重签名!
    dyld (应用可执行文件)调用:
    插入到某个进程:DYLD_INSERT_LIBRARIES

    • 攻击
        1. OC 方法:Method Swizzling
        1. 系统 C 函数:fishhook,系统库函数是有符号的,绑定符号
        1. Tweak 写插件的方式安装在越狱手机上,通过DYLD_INSERT_LIBRARIES 方式注入动态库到 APP 中
        1. 攻克用 RESTRICT 段防护的 APP,利用二进制修改器破坏防护
        1. 攻克 ptrace:使用 fishhook
        1. 攻克 sysctl :使用 fishhook
    • 防护
        1. 基本防护, fishhook
        1. Tweak 使用 DYLD_INSERT_LIBRARIES 进攻,就用 RESTRICT 段防护:
          • 在 target—》Build Settings-》Other Linker Flags添加 -Wl,sectcreate,__RESTRICT,__restrict,/dev/null
        1. 以防二进制修改器破坏防护,使用 dyld 源码再进行防护
        1. ptrace防护--反调试:拒绝进程的附加
        1. 通过 framework 防护调试
        1. sysctl 检测进程是否被调试
        1. 代码混淆,通过 .pch 文件
        1. 字符串加密
        1. 隐藏函数名称
        1. 使用汇编进行系统调用
        1. 重签名防护

    防护主要手段
    1.重签名防护;
    2.ptrace 防护(用汇编)
    3.反 hook 防护(动态库提前)
    4.混淆关键代码

    ptrace (process trace 进程跟踪)

    此函数提供了一个进程监听控制另一个进程,并且可以检测被控制进程的内存和寄存器里面的数据!它可以用来实现断点调试和系统调用跟踪,debugserver 就是用的它。
    iOS 中没有提供相关的头。

    sysctl 函数:

    //sysctl 防护
    int name[4];//里面放字节码,查询信息
    name[0] = CTL_KERN;//内核查看
    name[1] = KERN_PROC;//查询进程
    name[2] = KERN_PROC_PID;//传递的参数是进程的 ID(PID)
    name[3] = getpid();//PID 的值
    
    struct kinfo_proc info;//接受进程查询结果信息的结构体
    size_t info_size = sizeof(info);//结构体的大小
    
    int error = sysctl(name, sizeof(name)/sizeof(*name),  &info, &info_size, 0, 0);
    assert(error == 0);//0就是没有错误,其他就是错误码
    
    return ((info.kp_proc.p_flag & P_TRACED) != 0);
    
    

    闪退的可能是防护使用:

    1. exit();
    2. ptrace;

    相关文章

      网友评论

          本文标题:iOS 逆向开发的点点滴滴

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