iOS 逆向开发的点点滴滴

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 中执行


    iOS 逆向开发的点点滴滴_第1张图片
  1. 生成block_symbol.json文件


    iOS 逆向开发的点点滴滴_第2张图片
  1. 在终端控制台输入命令生成 Mach-O 文件


    iOS 逆向开发的点点滴滴_第3张图片

LLDB
bt查看函数调用栈

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

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



1. ssh

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


    iOS 逆向开发的点点滴滴_第4张图片
// 在完美越狱的手机下
ssh 用户名@IP地址
ssh [email protected] 通过具体IP地址是 wifi 连接
登录之后输入密码,默认密码为 alpine

//删除服务器对应的公钥
ssh-keygen -R 服务器 IP 地址

iOS下有两个用户 root 最高权限的用户和 mobile 用户
exit ;退出
文件的读写权限只有 root 才可以操作
ifunbox
// 在 root 下修改密码
passwd ;再输入两次新密码之后修改成功}

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

openSSH
openSSH 其中一种软件

iOS 逆向开发的点点滴滴_第5张图片
中间人攻击

中间人攻击

预防中间人攻击最有效的方法就是验证公钥是不是服务器的
如果是公开的 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 中可以添加函数,会依附在某个进程里面,进程退出之后就失效


  • 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


      iOS 逆向开发的点点滴滴_第7张图片
    • 3.输入11,选择创建 tweak,并依此输入Project Name、Package Name、uthor/Maintainer Name、MobileSubstrate Bundle filter等信息,最后得到文件wechatpwdtweak(Package Name工程名是自己定义的)


      iOS 逆向开发的点点滴滴_第8张图片
    • 4.修改工程下的内容


      iOS 逆向开发的点点滴滴_第9张图片
    • 5.修改完之后就在终端下执行:make ;编译一下


      iOS 逆向开发的点点滴滴_第10张图片
    • 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


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

      • PP助手源:http://apt.25pp.com
      • 威锋源:http://apt.so
    • 安装插件

      • 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 逆向开发的点点滴滴)