《iOS底层原理文章汇总》
上一篇文章iOS-逆向23-Theos介绍了Theos以及DebugServer,本文介绍越狱调试。
1.iOS9的越狱机器添加雷锋源https://apt.abcydia.com,安装AFC2 iOS8-9,能通过iFunbox进入系统根目录
2.debugserver的权限问题
I.从手机里面的dubugserver中导出debugserver.entitlements
ldid -e > debugserver debugserver.entitlements
entitlements中若没有task_for_pid-allow和get-task-allow,则进行添加,值设置为1
添加后使debugserver生效,ldid -Sdebugserver.entitlements debugserver
拷贝到手机/usr/bin中,解决权限问题
3.class-dump存在于Monkey中
which class-dump
/opt/MonkeyDev/bin/class-dump
I.打开正版微信,dump.py 微信,dump出正版微信的ipa包
II.新建Monkey工程Demo,将微信.ipa包拖入TargeApp目录下,Build Setting中设置为YES
III.运行工程,会自动dump出头文件,不能有中文路径,否则dump不成功
4.开发命令行工具
I.新建工程,在main函数中写入自己的代码,argc表示参数有几个,argv数组表示存放传入的参数,默认是一个
int main(int argc, char * argv[]) {
printf("此时参数有%d\n\n\n",argc);
if(argv[0]){printf("0:%s\n",argv[0]);}
if(argv[1]){printf("1:%s\n",argv[1]);}
if(argv[2]){printf("2:%s\n",argv[2]);}
if(argv[3]){printf("3:%s\n",argv[3]);}
printf("这是一个命令行工具!!\n\n\n");
return 0;
}
II.编译后将可执行文件赋值到越狱手机根目录中
scp -P 12345 CLOUDCMD root@localhost:~/
5.砸过壳和未砸过壳的可执行文件的区别
查看上文砸过壳的WeChat可执行文件的加密值0
对比未砸过壳的WeChat可执行文件的加密值1,在越狱设备中拷贝出为砸过壳的微信.ipa,通过ps -A|grep WeChat
查看包所在的路径,拷贝出WeChat可执行文件到Mac目录scp -P 12345 root@localhost:/var/containers/Bundle/Application/33FA49F6-3D93-4696-B4B3-C5FC3C7C4AA4/WeChat.app/WeChat ./
WeChat在手机中的路径
/var/containers/Bundle/Application/33FA49F6-3D93-4696-B4B3-C5FC3C7C4AA4/WeChat.app/WeChat
通过MachO文件修改cript的值为0,只是Crypt ID的值变为0了,但MachO文件还没有砸壳,通过otool -l WeChat|grep crypt
能看到Crypt的值的变化
执行
class-dump WeChat -o headers/
,dump头文件乱码,表明仅仅是Crypt ID标记值改了下,并没有真正砸壳
6.LLDB手动(正版AppStore下载微信)砸壳
I.通过Debug server附加进程,找到运行的WeChat所在的pid
ps -A|grep WeChat
,到越狱iPhone设备的debugserver所在的目录进行监听连接./debugserver localhost:12346 -a 13668
iPhone:/Developer/usr/bin root# ps -A|grep WeChat
12966 ?? 13:46.99 /var/containers/Bundle/Application/FE9E1DE7-AC16-4EBF-B06C-E493E96AB2CD/WeChatDemo.app/WeChat
13668 ?? 0:04.41 /var/containers/Bundle/Application/33FA49F6-3D93-4696-B4B3-C5FC3C7C4AA4/WeChat.app/WeChat
13824 ttys000 0:00.03 grep WeChat
iPhone:/Developer/usr/bin root# debugserver localhost:12346 -a 13668
-sh: debugserver: command not found
iPhone:/Developer/usr/bin root# ./debugserver localhost:12346 -a 13668
debugserver-@(#)PROGRAM:debugserver PROJECT:debugserver-360.0.26.14
for arm64.
Attaching to process 13668...
Listening to port 12346 for a connection from localhost...
Waiting for debugger instructions for process 13668.
在lldb中进行连接process connect connect://localhost:12346
附加上后,屏幕静止,执行c(continue)后,屏幕能动,若执行exit,则必定会杀掉WeChat,有什么方式不杀掉WeChat呢,直接Cmd+w关闭窗口就好了
Cloud@Mac ~/Documents/iOS/iOS逆向班/024--越狱调试/未砸过壳的可执行文件 lldb
(lldb) process connect connect://localhost:12346
Process 13668 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00000001860f0bc4 libsystem_kernel.dylib` mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
-> 0x1860f0bc4 <+8>: ret
libsystem_kernel.dylib'mach_msg_overwrite_trap: 0x1860f0bc8 <+0>: mov x16, #-0x20
0x1860f0bcc <+4>: svc #0x80
0x1860f0bd0 <+8>: ret
libsystem_kernel.dylib'semaphore_signal_trap: 0x1860f0bd4 <+0>: mov x16, #-0x21
0x1860f0bd8 <+4>: svc #0x80
0x1860f0bdc <+8>: ret
libsystem_kernel.dylib'semaphore_signal_all_trap: 0x1860f0be0 <+0>: mov x16, #-0x22
Target 0: (WeChat) stopped.
(lldb)
II.通过Xcode进行附加
通过image list拿到MachO首地址[ 0] 280CB04C-9E91-3BC3-8A90-3E24FC80247D 0x0000000104224000
拷贝出未加密的WeChat.bin文件,大小是加密部分数据的大小,从MachO文件首地址+offset16384开始拷贝,再将生成的WeChat.bin文件拷贝到和未砸壳的WeChat可执行文件同级目录下
memory read --force --outfile ~/Desktop/WeChatDump/WeChat.bin --binary --count 187842560 0x0000000104224000+16384
从内存中拷贝出的数据覆盖掉未砸壳MachO文件中的数据,seek表示从16384个字节开始,bs表示一次写入一个字节,conv指定参数传输notrunc不截断输出,写入187842560,原始WeChatMachO文件后面部分保留,if是输入的文件,of输出文件dd seek=16384 bs=1 conv=notrunc if=./WeChat.bin of=WeChat
一个字节一个字节写入,过程会比较缓慢
复制成功后,需要修改cryptid为0,class-dump是否能成功dump出头文件
成功dump出头文件,表明手动砸壳成功
7.修改系统行为,比如修改SpringBoard中的图标起泡值
1.Reveal 无法找到系统的SpringBoard排除掉
2.Cycript,先对SpringBoard进行砸壳,拷贝出SpringBoard可执行MachO文件,dump出头文件
iPhone:~ root# ps -A |grep SpringBoard
487 ?? 37:54.15 /System/Library/CoreServices/SpringBoard.app/SpringBoard
14698 ttys000 0:00.02 grep SpringBoard
scp -P 12345 root@localhost:/System/Library/CoreServices/SpringBoard.app/SpringBoard ./
no such identity: /Users/cloud/.ssh/id_ed25519: No such file or directory
root@localhost's password:
SpringBoard 100% 10MB 12.9MB/s 00:00
otool -l SpringBoard | grep crypt
class-dump -H SpringBoard -o ./headers
寻找BadgeView关键字,根据地址值设置hidden属性,控制气泡值
定位类:SBIconParallaxBadgeView: 0x10758b0b
iPhone:~ root# ps -A |grep SpringBoard
487 ?? 37:54.15 /System/Library/CoreServices/SpringBoard.app/SpringBoard
14698 ttys000 0:00.02 grep SpringBoard
iPhone:~ root# cycript -p SpringBoard
cy# @import com.cloud.hank
{}
cy# HKCurrentVC()
#""
cy# #0x105b67a70.view.recursiveDescription().toString()
写插件,干掉类的初始化方法init,使SBIconParallaxBadgeView对象不存在
✘ Cloud@Mac ~/Documents/iOS/iOS逆向班/024--越狱调试/自己的代码 nic.pl
NIC 2.0 - New Instance Creator
------------------------------
[1.] iphone/activator_event
[2.] iphone/activator_listener
[3.] iphone/application_modern
[4.] iphone/application_swift
[5.] iphone/cydget
[6.] iphone/flipswitch_switch
[7.] iphone/framework
[8.] iphone/library
[9.] iphone/notification_center_widget
[10.] iphone/notification_center_widget-7up
[11.] iphone/preference_bundle_modern
[12.] iphone/theme
[13.] iphone/tool
[14.] iphone/tool_swift
[15.] iphone/tweak
[16.] iphone/tweak_with_simple_preferences
[17.] iphone/xpc_service
Choose a Template (required): 15
Project Name (required): badgeView
Package Name [com.yourcompany.badgeview]: com.cloud.badgeview
Author/Maintainer Name [Cloud]:
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]:
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]:
Instantiating iphone/tweak in badgeview/...
Done.
经常用的两项在.zshrc文件中配置为环境变量,source ~/.zshrc,配置环境变量后,Makefile文件中就不用写了
%hook SBIconParallaxBadgeView
-(id)init{
return nil;
}
%end
路径中不能有中文,拷贝到桌面,本地Mac端口12345和远程iPhone端口22号进行映射,make,make package;make install,SpringBoard自动重启,桌面AppStore右上角的图标消失
3.LLDB,通过Xcode附加SpingBoard,但View Debug失败,待续。。。换iOS9.0也许能成功。。。
8.使用Monkey开发Tweak
1.新建工程,确定要Hook应用的bundle identifier
2.编写hook代码,配置Monkey变量,开启端口12345号映射
MonkeyDevDeviceIP localhost
MonkeyDevDevicePassword alpine
MonkeyDevDevicePort 12345
MonkeyDevkillProcessOnInstall SpringBoard
3.Code Signing Identity改为iOS Developer
遇到报错,删除/opt/theos/vendor/lib/CydiaSubstrate.framework/CydiaSubstrate.tbd文件中的archs后面的两项i386, x86_64
ld: building for iOS, but linking in .tbd file (/opt/theos/vendor/lib/CydiaSubstrate.framework/CydiaSubstrate.tbd) built for iOS Simulator, file '/opt/theos/vendor/lib/CydiaSubstrate.framework/CydiaSubstrate.tbd' for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
遇到报错
Failed to locate sshpass. Is sshpass installed?
使用Sublime Text新建sshpass.rb文件内容如下,执行
brew install sshpass.rb
,安装成功,运行成功
require 'formula'
class Sshpass < Formula
url 'http://sourceforge.net/projects/sshpass/files/sshpass/1.06/sshpass-1.06.tar.gz'
homepage 'http://sourceforge.net/projects/sshpass'
sha256 'c6324fcee608b99a58f9870157dfa754837f8c48be3df0f5e2f3accf145dee60'
def install
system "./configure", "--disable-debug", "--disable-dependency-tracking",
"--prefix=#{prefix}"
system "make install"
end
def test
system "sshpass"
end
end
可在.zshrc文件中配置为全局变量
9.Theos原理
I.make后生成arm64和armv7两种类型可执行二进制文件badgeView.dylib,作为动态库,动态库要进行注入,之前是第一种是通过yololib修改LoadCommand字段,让dyld加载动态库,对原始的App的MachO文件进行了改动,污染了MachO文件,第二种注入是通过dylidInsertLibraries这个环境变量,插入一堆动态库
II.Tweak的动态注入原理:LoadCommands没有改变,make package打包后生成packge文件夹,打包一次会生成一个版本的.deb文件,类似于ipa包,通过Cydia进行下发安装的插件
III.执行make install时,走Cydia拷贝进行安装了,那么安装到哪里去了呢?安装进去之后变为了动态库badgeView.dylib,在iPhone的/Library/MobileSubstrate/DynamicLibraries路径下
badgeView.plist中指明需要依附于哪一个进程的Bundle identifier
badgeView.dylib到底是插入的还是注入的呢?
如果是插入的MachO文件的LoadCommands中一定会出现badgeView.dylib路径,拷贝出SpringBoard的MachO文件看scp -P 12345 root@localhost:/System/Library/CoreServices/SpringBoard.app/SpringBoard ./
通过MachO查看LoadCommands,发现找不到badgeView.dylib,由此排除法得知,badgeView.dylib加载通过修改了DYLD_INSERT_LIBRARIES变量进行插入的。