iOS逆向工程-0x01-工具篇-Cycript
对于初开始学习iOS逆向工程的人来说,实现一个tweak
可以算是入门逆向工程了。
当然了,可能你现在还不知道tweak
是什么。简单来说,你可以把一个tweak当作某一个app的一个插件(类似于浏览器广告屏蔽插件)。在app运行的时候,tweak会hook住某个函数,然后在hook的函数里面,你可以插入你的代码。
比如用户在登陆微信账号的时候,tweak可以hook住登录函数,dump出用户的账号密码
那问题来了,我们要如何知道哪个函数是账号登录函数咧?这就涉及到我们如何去分析一个iOS app
分析 iOS app 的两种方法
-
运行时分析
- GDB/LLDB
- Cycript
- Logify
- weak_classdump
- InspectiveC
-
可执行代码分析
- dumpdecrpted
- class_dump,class_dump_z,classdump_dyld
- Disassemblers
- IDA
- Hopper
- otool
- strings
- nm
先不要被这么多的工具多吓到,我们一样一样来。相比对汇编代码的分析,动态分析要简单,容易上手很多,对新手而言,也更加容易获取到乐趣。所以我们先从最好玩的Cycript开始。
###Cycript
Cycript最重要的特性是,它可以hook住 iOS/macosx 上面正在运行的进程,并通过终端使用objective_c或javascript语法去打印和修改该应用的运行时信息。我们可以把它当作一个可以debug没有源代码程序的工具。
以下是 Cycript 的用途:
- 能够hook正在运行的进程,并打印相关信息,如 appdelegate,rootViewController
- 对程序中的类,可以获取到它用过的方法名称
- 可以获取到类的实例变量名称,以及打印出实例变量的值,当然也可以修改实例变量的值
- 能够执行 method swizzling, 替换某个指定的函数
- 可以在运行时调用其他方法
安装 cycript
首先利用 Cydia 下载 mobilesubstrate
adv-mds
;从官网上面下载最新的包,并通过 scp
把文件拷贝到 iOS 设备上去,利用 dpkg
进行安装:
dpkg -i cycript cycript_0.9.102-1_iphoneos-arm.deb
安装完成之后,执行 cycript 看是否工作:
用Cycript进行实时修改
本文将使用支付宝来进行测试。
-
让支付宝钱包在前台运行,并找出它的进程id,然后用 cycript -p hook 进程
chengpeide-iPhone:~ root# ps aux | grep AlipayWallet mobile 629 0.0 9.3 815836 47792 ?? Ss 9:45PM 0:34.79 /var/mobile/Containers/Bundle/Application/FB2E1466-0D87-4FF9-9616-BD4269D61BCF/AlipayWallet.app/AlipayWallet root 678 0.0 0.1 536256 412 s000 U+ 9:49PM 0:00.01 grep AlipayWallet -rwxr-xr-x 1 root admin 906 Jan 12 2015 cycript chengpeide-iPhone:/cp/Cycript_0.9.502 root# cycript -p 629 cy# var app = [UIApplication sharedApplication] #"<DFApplication: 0x14df44d0>" cy# app.delegate #"<DFClientDelegate: 0x14ed2d40>" cy# app.keyWindow.rootViewController #"<DFNavigationController: 0x15ac9a00>" cy# var nav = new Instance(0x15ac9a00) #"<DFNavigationController: 0x15ac9a00>" cy# nav.topViewController.childViewControllers @[#"<HPHomeWidgetGroup: 0x160a03d0>",#"<O2OIndexViewController: 0x15ad6600>",#"<APContactRecentViewController: 0x15afb600>",#"<WWAssetsViewController: 0x160a9da0>"] cy# var assetsViewController = new Instance(0x160a9da0) #"<WWAssetsViewController: 0x160a9da0>" cy# [assetsViewController.view subviews] @[#"<UIView: 0x162d8000; frame = (0 0; 0 0); layer = <CALayer: 0x162c85d0>>",#"<UITableView: 0x15433800; frame = (0 0; 320 519); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x1623d1f0>; layer = <CALayer: 0x162c3b10>; contentOffset: {0, -64}; contentSize: {320, 800}>"] cy# var tableView = new Instance (0x15433800) #"<UITableView: 0x15433800; frame = (0 0; 320 519); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x1623d1f0>; layer = <CALayer: 0x162c3b10>; contentOffset: {0, -42}; contentSize: {320, 800}>" cy# tableView.backgroundColor = [UIColor redColor] #"UIDeviceRGBColorSpace 1 0 0 1" [tableView visibleCells] @[#"<HeadInfoCell: 0x16160a40; baseClass = UITableViewCell; frame = (0 220; 320 80); autoresize = W; layer = <CALayer: 0x16160e80>>",#"<DoubleInfoCell: 0x1569e800; baseClass = UITableViewCell; frame = (0 300; 320 80); autoresize = W; layer = <CALayer: 0x16486e80>>",#"<DoubleInfoCell: 0x15452e00; baseClass = UITableViewCell; frame = (0 380; 320 80); autoresize = W; layer = <CALayer: 0x16491a50>>"] cy# var headCell = new Instance (0x16160a40) #"<HeadInfoCell: 0x16160a40; baseClass = UITableViewCell; frame = (0 220; 320 80); autoresize = W; layer = <CALayer: 0x16160e80>>" cy# headCell.backgroundColor = [UIColor redColor] #"UIDeviceRGBColorSpace 1 0 0 1" cy# headCell.contentView.backgroundColor = [UIColor redColor] #"UIDeviceRGBColorSpace 1 0 0 1"
我们可以看到,界面上 tableViewCell 的背景颜色变成了红色。
以上操作的思路大致就是, appdelegate => keyWindow => rootViewController => viewControllers => view
当然你也可以骗骗自己,把余额这个label的text改成巨款,过过眼瘾
cy# [tableView subviews]
@[#"<UIRefreshControl: 0x16482c90; frame = (0 0; 320 60); hidden = YES; autoresize = W; layer = <CALayer: 0x16256370>>",#"<UITableViewWrapperView: 0x1624cce0; frame = (0 0; 320 519); gestureRecognizers = <NSArray: 0x16098960>; layer = <CALayer: 0x14e12cf0>; contentOffset: {0, 0}; contentSize: {320, 519}>",#"<UIView: 0x16216d10; frame = (0 780; 320 20); layer = <CALayer: 0x162562c0>>",#"<WHAccountHeaderView: 0x16217c10; frame = (0 0; 320 180); layer = <CALayer: 0x1637edd0>>",#"<UIView: 0x17635b80; frame = (0 180; 320 40); autoresize = W; layer = <CALayer: 0x1620d670>>",#"<UIImageView: 0x161f4740; frame = (0 452.5; 320 2.5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x161f47c0>>"]
cy# var header = new Instance(0x16217c10)
#"<WHAccountHeaderView: 0x16217c10; frame = (0 0; 320 180); layer = <CALayer: 0x1637edd0>>"
cy# [header subviews]
@[#"<UIView: 0x161c6530; frame = (0 0; 320 117); layer = <CALayer: 0x1638a780>>",#"<UIView: 0x16142d70; frame = (0 117.5; 106.667 62.5); layer = <CALayer: 0x161f6350>>",#"<UIView: 0x16142de0; frame = (106.667 117.5; 106.667 62.5); layer = <CALayer: 0x16109ed0>>",#"<UIView: 0x1610a4b0; frame = (213.333 117.5; 106.667 62.5); layer = <CALayer: 0x163771b0>>",#"<UILabel: 0x161082c0; frame = (122 28; 76 41); text = '0.00'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x14f73520>>",#"<UIImageView: 0x1610a520; frame = (246 42; 9 13); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x161025c0>>",#"<UIImageView: 0x161692b0; frame = (56.5 83; 13 13); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x16169330>>",#"<UILabel: 0x16169380; frame = (74.5 83; 189 13); text = '\xe7\x82\xb9\xe6\xad\xa4\xe5\xbc\x80\xe5\x90\xaf\xe8\xb4\xa6\xe6\x88\xb7\xe5\xae\x89\xe5\x85\xa8\xe9\x99\xa9\xef\xbc\x8c\xe4\xba\xab100\xe4\xb8\x87\xe4\xbf\x9d\xe9\x9a\x9c'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x16169230>>",#"<UILabel: 0x16169570; frame = (36.8333 154.25; 33 12); text = '\xe9\x93\xb6\xe8\xa1\x8c\xe5\x8d\xa1'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x16169630>>",#"<UILabel: 0x16169810; frame = (48.3333 131.25; 10 17); text = '2'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x161698d0>>",#"<UIImageView: 0x16169ab0; frame = (42.3333 127.25; 22 22); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x16169b30>>",#"<UILabel: 0x16381200; frame = (149 154.25; 22 12); text = '\xe4\xbd\x99\xe9\xa2\x9d'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x16381160>>",#"<UILabel: 0x16380280; frame = (144 131.25; 32 17); text = '0.00'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x16380340>>",#"<UILabel: 0x16380520; frame = (255.667 154.25; 22 12); text = '\xe5\x8d\xa1\xe5\x8c\x85'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x163805e0>>",#"<UILabel: 0x1638d640; frame = (261.667 131.25; 10 17); text = '0'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1638d700>>",#"<UIView: 0x16151570; frame = (0 117; 320 0.5); layer = <CALayer: 0x161515e0>>",#"<UIView: 0x16151670; frame = (0 179.5; 320 0.5); layer = <CALayer: 0x161516e0>>"]
cy# var label2= new Instance(0x161082c0)
#"<UILabel: 0x161082c0; frame = (122 28; 76 41); text = '0.00'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x14f73520>>"
cy# label2.text=@"10000000000000"
@"10000000000000"
很好玩,也很有用的工具,cycript。当然cycript还有一些高级用法,后面会介绍。