app風(fēng)靡的時代澄峰,總有一些奇葩的需求嫉沽。
為了刷量,刷排名俏竞,制作殼包绸硕,為了通過蘋果爸爸審核,想到代碼混淆胞此,垃圾代碼等策略臣咖。
作為一名程序員,怎么辦漱牵?
爬了一些文章博客夺蛇。總的來說有一下幾方面:
- 字符串加密:
- 類名方法名混淆
- 程序代碼混淆
- 加入安全SDK
除了這些外酣胀,還有很多方面可以做加固保護的,以上這些只是范范一談刁赦。制作殼包為了通過審核娶聘,還有注入
垃圾代碼
來解決和主包代碼重復(fù)率的問題。本文主要講解類名方法名混淆及垃圾代碼的問題甚脉。如有問題丸升,還請大神指點!
Objective-C的方法名混淆
混淆的方法
方法名混淆其實就是字符串替換牺氨,有2個方法可以狡耻,一個是#define,一個是利用tops猴凹。
利用#define的方法有一個好處夷狰,就是可以把混淆結(jié)果合并在一個.h中,在工程Prefix.pch的最前面#import這個.h郊霎。不導(dǎo)入也可以編譯沼头、導(dǎo)入則實現(xiàn)混淆。
單段的selector书劝,如func: 进倍,可以通過#define func 來實現(xiàn)字符串替換。
多段的selector购对,如a:b:c: 猾昆,可以通過分別#define a 、b洞斯、c 來實現(xiàn)字符串替換毡庆。
第一步 創(chuàng)建如下文件
1、工程中建立pch文件 加入以下內(nèi)容
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
//添加混淆作用的頭文件(這個文件名是腳本confuse.sh中定義的)
//#import "codeObfuscation.h"
#endif
2烙如、在工程目錄下創(chuàng)建confuse.sh文件
#!/usr/bin/env bash
TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="func.list"
HEAD_FILE="$PROJECT_DIR/$PROJECT_NAME/codeObfuscation.h"
export LC_CTYPE=C
#維護數(shù)據(jù)庫方便日后作排重
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 Demo_codeObfuscation_h
#define Demo_codeObfuscation_h' >> $HEAD_FILE
echo "http://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
3么抗、在工程目錄下創(chuàng)建fun.list文件,文件中存放需要混淆的方法名,類名亚铁,文件等等
didReceiveMemoryWarning
4蝇刀、配置項目$PROJECT_DIR/confuse.sh
5、編譯查看結(jié)果
直接build徘溢,混淆腳本會在編譯前運行吞琐,進行字符隨機替換,并且每次build的隨機字符不同然爆,如圖:
類名方法名混淆
此方法是參考下開源項目:ios-class-guard
操作步驟如下:
1站粟、 安裝工具
brew install ios-class-guard
brew install --HEAD ios-class-guard # install bleeding edge version:
ios-class-guard --v #查看版本
2、下載obfuscate_project
到工程根目錄下
curl -o obfuscate_project https://raw.githubusercontent.com/Polidea/ios-class-guard/master/contrib/obfuscate_project && chmod +x obfuscate_project
效果如果:
注意點:提交的commit信息它腳本中會移除掉曾雕,包括obfuscate_project
也會被移除
WARNING: This will wipe all your not commited changes in your repository
警告:這將會移除你未提交的更改在你的倉庫中奴烙。
問題點:
需要修改腳本中的工程名,scheme,sdk等:
3切诀、然后繼續(xù)執(zhí)行:
當你每次想混淆你的項目揩环。都應(yīng)該執(zhí)行此操作。存儲包含符號映射的json文件幅虑,以便在發(fā)生崩潰時獲取原始符號名稱丰滑。
bash obfuscate_project
打開工程,發(fā)現(xiàn)已經(jīng)生成了.h
和json
文件
4倒庵、添加.pch
文件
- Create PCH file in your project's root directory. In Xcode go to
File -> New -> File -> iOS -> Other -> PCH File
. To ensure backward compatibility iOS-Class-Guard will be looking for a file matching the *-Prefix.pch
mask, as an exampleMyProject-Prefix.pch
- At the target's
Build Settings
, inApple LLVM - Language
section, setPrefix Header
to your PCH file name. - At the target's
Build Settings
, inApple LLVM - Language
section, setPrecompile Prefix Header
toYES
.
$(SRCROOT)/MyProject/MyProject-Prefxi.pch
容易犯的錯誤:
注意是:MyProject-Prefix.pch
因為腳本中pch的名字有Prefix
每次混淆之后都會刪除腳本褒墨,清理工程『逦撸可以直接修改腳本代碼
ios-class-guard
使用命令等
ios-class-guard 0.8 (64 bit)
Usage: ios-class-guard [options] <mach-o-file>
where options are:
-F <class> specify class filter for symbols obfuscator (also protocol))
-i <symbol> ignore obfuscation of specific symbol)
--arch <arch> choose a specific architecture from a universal binary (ppc, ppc64, i386, x86_64, armv6, armv7, armv7s, arm64)
--list-arches list the arches in the file, then exit
--sdk-ios specify iOS SDK version (will look for /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS<version>.sdk
or /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS<version>.sdk)
--sdk-mac specify Mac OS X version (will look for /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX<version>.sdk
or /Developer/SDKs/MacOSX<version>.sdk)
--sdk-root specify the full SDK root path (or use --sdk-ios/--sdk-mac for a shortcut)
-X <directory> base directory for XIB, storyboards (will be searched recursively)
-P <path> path to project.pbxproj of Pods project (located inside Pods.xcodeproj)
-O <path> path to file where obfuscated symbols are written
-m <path> path to symbol file map (default value symbols.json)
-c <path> path to symbolicated crash dump
還有一些單獨對xib貌亭,storyboard,pods等單獨操作進行混淆的认臊。點擊這里
腳本源碼:有興趣可以研究下腳本源碼,這才是核心根源锄奢。
#!/bin/bash
set -e
# General build options
# WORKSPACE=YourWorkspace.xcworkspace
PROJECT=test.xcodeproj
SCHEME=test
CONFIGURATION=Release
SDK=11.3
# Additional build options
XCODEBUILD_OPTS=""
CLASS_GUARD_OPTS="-i IgnoredSymbol -F !ExcludedClass"
# In case of using Xcode >= 6 and SDK >= 8
CLASS_GUARD_OPTS_SDK="--sdk-root /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$SDK.sdk"
####################################################
# BUILD SCRIPT STARTS HERE
####################################################
# Just in case
echo "WARNING: This will wipe all your not commited changes in your repository"
echo "Press Ctrl-C to Cancel or Enter to proceed."
read
function echo_and_run() {
echo "$@"
"$@"
}
# Jump to directory where obfuscate script is located
pushd $(dirname $0)
# Symbols file path
SYMBOLS_FILE="$PWD/symbols.h"
# Clean current workspace
echo_and_run git reset --hard
echo_and_run git clean -fdx
# Just in case: wipe build/
rm -rf build/
# Automatically detect PODS
[[ -f Podfile ]] && [[ ! -f Pods/Manifest.lock ]] && pod install
[[ -f Pods/Pods.xcodeproj/project.pbxproj ]] && CLASS_GUARD_OPTS="$CLASS_GUARD_OPTS -P Pods/Pods.xcodeproj/project.pbxproj"
# Build project to fetch symbols
[[ -n "$WORKSPACE" ]] && XCODEBUILD_OPTS="$XCODEBUILD_OPTS -workspace $WORKSPACE"
[[ -n "$PROJECT" ]] && XCODEBUILD_OPTS="$XCODEBUILD_OPTS -project $PROJECT"
[[ -n "$SCHEME" ]] && XCODEBUILD_OPTS="$XCODEBUILD_OPTS -scheme $SCHEME"
[[ -n "$CONFIGURATION" ]] && XCODEBUILD_OPTS="$XCODEBUILD_OPTS -configuration $CONFIGURATION"
xcodeversion=`xcodebuild -version | grep -oE '^Xcode\s+\d+' | grep -oE '\d+'`
if ((xcodeversion > 5)) || ((SDK >= 8.0))
then
[[ -n "$SDK" ]] && XCODEBUILD_OPTS="$XCODEBUILD_OPTS -sdk iphonesimulator$SDK"
else
[[ -n "$SDK" ]] && XCODEBUILD_OPTS="$XCODEBUILD_OPTS -sdk iphoneos$SDK"
[[ -n "$SDK" ]] && CLASS_GUARD_OPTS_SDK="--sdk-ios $SDK"
fi
echo_and_run xcodebuild $XCODEBUILD_OPTS \
clean build \
-derivedDataPath build
OBJROOT=build/ \
SYMROOT=build/
# Insert SYMBOLS_FILE to all .pch found in project
echo_and_run find . -name '*-Prefix.pch' -exec sed -i .bak '1i\
'"#import \"$SYMBOLS_FILE\"
" "{}" \;
# Obfuscate project
appsNumber=0;
while read app
do
if ((appsNumber > 0))
then
echo ""
echo ""
echo "You cannot use this tool when there is more than one .app file in products. Otherwise, only the first one will be used for obfuscation."
echo ""
echo ""
exit 1
fi
((appsNumber+=1))
TARGET=$(basename "$app" .app)
echo "Obfuscating $TARGET in $app..."
echo_and_run ios-class-guard \
$CLASS_GUARD_OPTS_SDK \
$CLASS_GUARD_OPTS \
-O "$SYMBOLS_FILE" \
"$app/$TARGET"
done < <(find build/ -name '*.app')
echo ""
echo ""
echo "Congratulations! Obfuscation completed. You can now build, test and archive Your project using Xcode, Xctool or Xcodebuid..."
echo ""
echo ""
工具混淆
垃圾代碼
用于應(yīng)對蘋果對重復(fù)應(yīng)用的審核(Guideline 4.3 Design Spam)失晴,避免蘋果機審檢測概率。
主要功能
- 修改工程名
- 修改類名前綴
- 掃描工程中的代碼拘央,生成同等數(shù)量的 Category 文件涂屁,文件中及是同等方法數(shù)量的垃圾代碼。
- 修改 xxx.xcassets 文件夾中的 png 資源文件名灰伟。
- 刪除代碼中的所有注釋和空行拆又。
使用步驟如下
1、下載源碼栏账。
2帖族、用 Xcode 打開工程并配置參數(shù)。如圖
3挡爵、運行
使用二進制文件竖般,在終端中執(zhí)行 GenerateSpamCode
- spamCodeOut 生成垃圾代碼
./GenerateSpamCode \
/Users/wangzelong/Desktop/TeamCode/cardloan \
-spamCodeOut /Users/wangzelong/Desktop/appLog AppLog
注明:appLog是一個文件夾,垃圾代碼生成到的文件夾目錄茶鹃。 后面的AppLog是將要生成的垃圾代碼分類參數(shù)等可以再測試代碼中嘗試涣雕。
- deleteComments 刪除工程目錄下 .h .m .swift 文件中的注釋和空行。
./GenerateSpamCode
/Users/wangzelong/Desktop/appium
-deleteComments
坑:
1闭翩、Podfile被修改后需要手動pod install
2挣郭、如果工程項目很大。則建議導(dǎo)入一部分工程代碼去生成垃圾代碼疗韵,因為項目中很多文件包括依賴的三方庫等兑障,可能是 .m 文件中實現(xiàn)的私有類,編譯垃圾代碼可能會報錯,刪除該垃圾代碼 .h .m 文件及可旺垒。
此外提供一個壓縮圖片的輕量工具:
使用 ImageMagick 對 png 圖片做輕量壓縮彩库,及不損失圖片質(zhì)量,又可改變圖片文件 hash 值先蒋。方法:
- 安裝 ImageMagick
brew install imagemagick
- 壓縮工程目錄下所有 png 文件
find . -iname "*.png" -exec echo {} \; -exec convert {} {} \;