iOS安全/程式碼混淆

weixin_34253539發表於2017-12-20

APP 一般經常做的網路引數加密解密,加密方法有base64、MD5、AES、RSA、DES等加密方法、這些加密一般都是給資料進行加密、防止資料外漏。但是今天我要介紹的是防範反彙編風險,防止咋們APP的程式碼讓別人反編譯,不過Apple還算安全反編譯過來也只能看到.h檔案。不過為了安全起見我們還是將程式碼進行混淆,這樣比較安全些。

一、先介紹下反編譯工具 class-dump 的使用
class-dump 的安裝這裡就先不介紹了、可以參考網上資料。class-dump的使用很簡單(預設你已經安裝class-dump),現將ipa字尾改為zip:

2021171-f027eda32a863c6e.png
螢幕快照 2017-12-19 16.11.40.png
2021171-dda2909e84db3f4d.png
51DF8F1A-DA17-47C6-A0AD-E55ACFE29202.png
2021171-726ac89cfe541a4d.png
7E47CACC-2A7D-481D-B50C-B19F010746DB.png
2021171-fec4f6349cd0209a.png
EDE1D3A5-5893-4644-988C-18AF455E70C3.png

這裡的ipa包不可以是AppStore上下載的、因為AppStore上下載的ipa包、Apple是又經過加密的、需要自己破殼,想知道怎麼給AppStore下載的ipa進行破殼,看iOS應用逆向工程。
將zip解壓、得到app二進位制檔案,下面就使用class-dump將app進行反編譯:開啟Terminal:輸入命令 class-dump -H app二進位制檔案路徑 -o 反編譯後.h檔案的存放路徑

2021171-9a81d445f0df6354.png
97087D05-DA9C-450B-8522-E361EF61C035.png

回車後就得到了反編譯的.h檔案

2021171-420838b10a2378a3.png
3AF106BD-50B9-42C5-A1BA-DE0A0F9CAFA1.png

class-dump 功能很強大,只是在終端輸入一行命令,就可以反編譯app的二進位制檔案,得到所有.h 檔案。以下就是為了防止反編譯,通過分下.h檔案,對咋們的app進行一些操作(外掛就是這麼來的),所以要將我們.h檔案中的程式碼進行混淆,即使反編譯得到.h檔案,也很難分析。

二、將程式碼進行混淆

1.在專案根目錄下新建confuse.sh 和 gbFunc.list 檔案

說明:
confuse.sh 檔案在編譯過程中會執行gbFunc.list 用於自動混淆程式碼時,存放過濾出來需要混淆的方法名

touch confuse.sh
touch gbFunc.list

2021171-806418cf6970e613.png
4FB867FF-E1C9-4C25-95C1-5476C609F618.png

2.新建PFConfuse.h

說明:

GBConfuse.h 是在自動混淆程式碼時,將會把自動生成的字串定義成巨集,存放在此檔案,也便於檢視。

2021171-024912d64bf3f35a.png
D714AA6F-B08E-4E30-A40F-A4C611660CB6.png

注意:需要把.h檔案移到專案檔案外,因為放專案檔案中,到時被反編譯過來,還是能得到GBConfuse.h裡面的東西的,就能通過比對,得到方法。(後面用class-dump反編譯過來就明白了...)

2021171-1dcfeefea0667332.png
940FC2F1-1058-4DDA-A011-369C827623D1.png

3.在confuse.sh中新增如下程式碼、(先看下效果、程式碼在下面)


2021171-5d5ca0d311702a73.png
E06A974A-B8EF-41EB-9563-2164A9CA26CD.png

2021171-71f4d4a2b963a321.png
48E68609-8BF7-4CD0-A3FA-38AABB43C326.png

2021171-82ec3fb97e67f11f.png
AE50DA1D-09B8-4123-9ACB-4EDB15EDC095.png

下面是要複製程式碼:

!/usr/bin/env bash

TABLENAME=symbols

SYMBOL_DB_FILE="symbols"

func.list路徑

STRING_SYMBOL_FILE="$PROJECT_DIR/GBFunc.list"

專案檔案路徑

CONFUSE_FILE="$PROJECT_DIR/SafetyTest"

Confuse.h路徑

HEAD_FILE="$PROJECT_DIR/PFConfuse.h"

export LC_CTYPE=C

取以.m或.h結尾的檔案以+號或-號開頭的行 |去掉所有+號或-號|用空格代替符號|n個空格跟著<號 替換成 <號|開頭不能是IBAction|用空格split字串取第二部分|排序|去重複|刪除空行|刪掉以init開頭的行>寫進func.list

grep -h -r -I "^[-+]" $CONFUSE_FILE --include '.[mh]' |sed "s/[+-]//g"|sed "s/[();,: ^/{]/ /g"|sed "s/[ ]</</"| sed "/^[ ]IBAction/d"|awk '{split($0,b," "); print b[2]; }'| sort|uniq |sed "/^$/d"|sed -n "/^PFSAFE_/p" >$STRING_SYMBOL_FILE

維護資料庫方便日後作排重,以下程式碼來自念茜的微博

createTable()
{
echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE

}

insertValue()

{
echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE

}

query()

{

echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE

}

ramdomString()

{

openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
}

rm -f $SYMBOL_DB_FILE

rm -f $HEAD_FILE

createTable

touch $HEAD_FILE

這裡也要做修改

echo '#ifndef PFConfuse_h

define CodeConfuse' >> $HEAD_FILE

echo "//confuse string at date" >> $HEAD_FILE

cat "$STRING_SYMBOL_FILE" | while read -ra line; do

if [[ ! -z "$line" ]]; then

ramdom=ramdomString

echo $line $ramdom

insertValue $line $ramdom

echo "#define $line $ramdom" >> $HEAD_FILE

fi

done

echo "#endif" >> $HEAD_FILE

sqlite3 $SYMBOL_DB_FILE .dump

需要修改的程式碼在於檔案路徑:

2021171-40d7cc2487ed942d.png
83B95390-DB79-4D48-988E-EE3809B5CA1C.png
2021171-105758f935d4c24e.png
2743BBF1-615D-4D9C-888C-26A4989F81BC.png

4.新增 Run Script

2021171-7ffd9235e39b5bea.png
螢幕快照 2017-12-19 17.27.51.png
2021171-929edba9e2927d71.png
螢幕快照 2017-12-19 17.29.10.png

5.新增 PCH 檔案


2021171-c04858a70618216d.png
EF1595F9-8343-4C84-ABE7-C09AFB92D6E4.png
2021171-0ff966a8cec1995e.png
7EE419AF-E74F-4673-AA8A-FF739CD38F3E.png

引用.h檔案

2021171-a997514bfc7f9c29.png
90029585-213D-49F0-BE92-AE0B6FBAFD45.png

6.新增以 "PFSAFE_"為字首的方法(以PFSAFE_為字首的方法就是要混淆程式碼的方法)

2021171-13f43d1bb7dfdf59.png
A4FFA574-1491-49E2-A1A6-843CB8D44B21.png

7.進行測試

執行報錯如下:
原因是.sh檔案沒有許可權,所以需要去開啟許可權。

2021171-3b2c186a4f528c30.png
39A47956-00DB-4289-A688-C8C3CDA79752.png

解決方法:執行終端,在confuse.sh檔案目錄下,執行命令:

chmod 755 confuse.sh

2021171-6a8d0dfcd9817e82.png
CB77D889-C66C-4F81-9D0C-7A1A9F7852E6.png

再執行專案即可成功執行

現不進行混淆程式碼,打包一個.ipa包進行測試


2021171-d029894ea29a6285.png
6D9BD6D6-1994-4FEC-B8E6-4EB9EC367A34.png
2021171-b67cf00c78d701ed.png
428EE5B5-10E8-4BB4-A44E-11689F986A06.png

使用class-dump(以上步驟"一",介紹內容):看看咋們反編譯後得到的檔案

2021171-fb4e4db8aa7b6484.png
613EE025-CBFD-46F0-9348-6E6FC8A15EB5.png

再看看ViewController.h檔案:


2021171-3cfbcf19ba1121b0.png
DC73ABD0-4871-4A16-9B1D-1F99958D0938.png

自己寫的方法通過反編譯完全暴露、別人就可以通過判斷這些方法幹什麼用的,再將app注入自己寫的dylib動態庫,對app乾點別的事情,這也是外掛的實現原理。

再將混淆過的程式碼,打包一個.ipa進行測試:


2021171-de565c15ecbad6a0.png
9519365B-2B18-4B46-AA94-087D9DC74F27.png
2021171-f8128a86b4dd2d55.png
2FAD71F0-6F87-4243-B955-D7196B5EEB26.png
2021171-6bcfe0edb1aa2e8a.png
F3D2D5D0-BED7-4FAB-BC97-AFD1EE9E8BE9.png

同上,使用 class-dump 將 app 二進位制檔案進行反編譯:


2021171-9c382e340a0c1685.png
AADC793D-8FCE-48CB-9E4E-7D5E00370657.png
2021171-efee08210877aea4.png
2C8F402D-7339-4B2C-93E6-9CCAC65BC3FD.png
2021171-309b68bb95a4319e.png
66059500-31E9-4ACD-9562-1A53B39B2AC2.png

總結:通過.sh 指令碼檔案,將個別方法以隨機生成字串的形式,將方法混淆,以至於反編譯後無法判斷該方法的作用,而達到 APP 更安全。

特別注意(以上、"二"中的2步):將 PFConfuse.h 移動到專案外,別放到專案中,因為放到專案中,到時候被反編譯也可得到,那就通過對比 PFConfuse.h 中的內容,判斷出方法。

三、參考文章
1、 iOS開發/App安全/程式碼自動混淆筆記
2、 iOS自動程式碼混淆
3、 念茜/Objective-C程式碼混淆
3、 class-dump最新安裝方法

如對iOS應用逆向工程感興趣,可以參考以下文章:
1、一步一步實現iOS微信自動搶紅包(非越獄)
2、iOS 逆向 - 微信 helloWorld

相關文章