Cycript入門 〜アプリをハックしてデバッグしてみよう〜


## はじめに

この記事は、
僕が主宰する __『スマートデバイス向けアプリのマネタイズ研究と実践開発』ゼミ__の
活動記録です。

### ゼミについて
株式会社サイバーエージェント アドテク本部 アドテクスタジオ内の活動です。
詳しくは、[ゼミ『スマートデバイス向けアプリのマネタイズ研究と実践開発』まとめ](http://qiita.com/toguri/items/cdb4da726e16f3e4541b)をご参照ください。

## 用意するもの
- ジェイルブレイク済みのiOS端末
- Cydiaがインストールされている
 
下記のドキュメントはCydiaを前提としています。

## 目的

[Cycript](http://www.cycript.org/)は、既存のアプリにコードを突っ込むことができるので、リリース後のアプリに対してもデバックに使えるかなと思っています。
このツールは、Objective-CとJavaScriptのハイブリッドのツールらしく、ターミナルにObjective-Cのコードを入力するだけでそのアプリ内で実行することができるらしい。

### 目標

参加者全員が __適当なアプリのボタンやラベルの内容を外から変更する__ を達成する

## Cycript入門
以下の操作について、ジェイルブレイク前提であり、自己責任でお願いします。

### 参考になったサイト

- Cycript公式
http://www.cycript.org/

- Realmのサイトを参考に進める
https://realm.io/jp/news/conrad-kramer-reverse-engineering-ios-apps-lyft/

- Cycript Tricks
http://iphonedevwiki.net/index.php/Cycript_Tricks


### 主なオペレーション
- Cydiaを使う
 - Cycriptをインストールする
 - OpenSSHをインストールする
- iPhoneにMacからSSHでログインする
- Cycriptでアプリを操作する
 - Process Injection
 - アプリの画面構成をハックする
 - ボタンの色やテキストをハックする
 - ボタンイベントをハックする

### Cydiaを使う

CycriptやOpenSSHをインストールするのに使用します。僕の脱獄方法の場合です。
![IMG_0001.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/6fa3c3e5-437c-6a07-e91b-e032475d8ea9.png "IMG_0001.PNG")


#### Cycriptをインストールする

今回のお題でもあるこいつをインスールします。
![IMG_0016.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/662d1479-528e-7c89-5c6d-e808f36ef0f2.png "IMG_0016.PNG")

#### OpenSSHをインストールする

ついでにOpenSSHもインスールします。
![IMG_0004.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/3b71199d-c367-3f03-a6ad-0745f19723c6.png "IMG_0004.PNG")

### iPhoneにSSHでログインする

自分のMacのターミナルから、iPhoneのIPアドレスを指定してsshログインします。初期パスワードは、`alpine` です。

```
$ ssh root@[IPアドレス]
root@IPアドレス password:[alpine]
root#
```

### Cycriptでアプリを操作する

操作したいアプリのプロセスをチェックし、cycriptで指定して起動する。
下記では、`UBER` を題材にすすめます。

__重要__ 下記作業前にUBERをインストール＆起動しておきます。
<br/>

起動直後の画面はこんな感じ。
![IMG_0011.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/0faf4c89-4496-39cc-c249-388ef2bfc1c3.png "IMG_0011.PNG")

#### Process Injection

`cycript -p`を使って、プロセスにアタッチします。

```
root# ps aux | grep UberClient
mobile 1660 0.0 4.4 815456 90912 ?? Us 6:49PM 0:02.64 /var/containers/Bundle/Application/E3330-CBE5-40AC-8365-66E075C6C04C/UberClient.app/UberClient
root# cycript -p 1660
cy#
```

#### アプリの画面構成をハックする

```
cy# UIApp.keyWindow.recursiveDescription()
@"....現在表示中の画面構成を再帰的に表示されます、結果はキャプチャのみで"
```

ダーッとでます
![スクリーンショット 2016-09-20 23.17.40.png](https://qiita-image-store.s3.amazonaws.com/0/4107/7804df87-1aa0-c99a-46e8-e4acbd2f909b.png "スクリーンショット 2016-09-20 23.17.40.png")

#### 中央の UBER 画像をハックする

こんな感じで、オブジェクトを取得するには、画面構成からIDを探してインスタンスを生成したります。

```
cy# var imageView = new Instance(0x151101f30);
cy# var droidUrl = [NSURL URLWithString:@"https://andropp.jp/webapp/wp-content/uploads/2014/11/android-wallpaper5_2560x1600_1.jpg"];
cy# var droidData = [NSData dataWithContentsOfURL:droidUrl];
cy# var droidImage = [UIImage imageWithData:droidData];
cy# imageView.image = droidImage;
```
<br/>

UBERアイコン画像が消えて、droidくんになってもーたｗ

![IMG_0012.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/45548732-c36e-f1fd-156d-f0060c7a28da.png "IMG_0012.PNG")


#### 登録ボタンをハックする

```
var signupButton = new Instance(0x14fe47730);
[signupButton setTitle:@"hogeeee" forState:UIControlStateNormal];
```

<br/>
と入力すると `登録` という文字が....
![IMG_0013.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/74153d81-6f2a-d716-a9a8-927931675356.png "IMG_0013.PNG")
....`hogeeee` になってるｗ

ちなみに、登録ボタンを端末に触らずに押しちゃうには....

```
cy# [signupButton sendActionsForControlEvents:UIControlEventTouchUpInside];
```

これで、起動！
![IMG_0016.PNG](https://qiita-image-store.s3.amazonaws.com/0/4107/b1d033d3-8ea6-240a-a0ba-57c261928d9e.png "IMG_0016.PNG")

## まとめ
iOS端末をジェイルブレイクしないといけないので、少し敷居が高い。
Cycriptを使ったハックは、既存アプリの研究を目的とした活用に向いてそう。
また、アプリ側にバックドアを意識した仕掛けを用意しておけば、強力なデバッグができそう（そんな仕掛け、怖くてアレだけど）。