• [iOS]代码混淆


    混淆有几点注意:

    不能混淆系统方法

    不能混淆init开头的等初始化方法

    混淆属性时需要额外注意set方法

    如果xib、 storyboard中用到了混淆的内容,需要手动修正。

    可以考虑把需要混淆的符号都加上前缀,跟系统自带的符号进行区分。

    混淆有风险,有可能会被App Store以2.1大礼包拒掉,需要说明用途。

    Swift项目代码混淆

    1. 新建confuse.sh文件

    终端cd到项目,新建文件。

    $ cd /Users/gamin/Desktop/hdj-ios
    $ touch confuse.sh

    2. 编辑指令文件

    打开confuse.sh文件,写入以下文本。这里指令设置的是去项目中混淆前缀为“HD”的属性和方法。

    #要混淆前缀
    CONFUSE_PREFIX="HD"

    1. # 格式:"\033[字背景颜色; 字体颜色m 将要设置的字符串 \033[0m"
    2. # 字体颜色: 30 --- 37
    3. # 30: 黑
    4. # 31: 红
    5. # 32: 绿
    6. # 33: 黄
    7. # 34: 蓝色
    8. # 35: 紫色
    9. # 36: 深绿
    10. # 37: 白色
    11. # 字体背景颜色: 40 --- 47
    12. # 40: 黑
    13. # 41: 深红
    14. # 42: 绿
    15. # 43: 黄色
    16. # 44: 蓝色
    17. # 45: 紫色
    18. # 46: 深绿
    19. # 47: 白色
    20. # 字体加亮颜色: 90 --- 97
    21. # 90: 黑
    22. # 91: 红
    23. # 92: 绿
    24. # 93: 黄
    25. # 94: 蓝色
    26. # 95: 紫色
    27. # 96: 深绿
    28. # 97: 白色
    29. # 背景加亮颜色范围: 100 --- 107
    30. # 100: 黑
    31. # 101: 深红
    32. # 102: 绿
    33. # 103: 黄色
    34. # 104: 蓝色
    35. # 105: 紫色
    36. # 106: 深绿
    37. # 107: 白色
    38. # \33[0m 关闭所有属性
    39. # \33[1m 设置高亮度
    40. # \33[4m 下划线
    41. # \33[5m 闪烁
    42. # \33[7m 反显
    43. # \33[8m 消隐
    44. # \33[30m -- \33[37m 设置前景色
    45. # \33[40m -- \33[47m 设置背景色
    46. # \33[nA 光标上移n行
    47. # \33[nB 光标下移n行
    48. # \33[nC 光标右移n行
    49. # \33[nD 光标左移n行
    50. # \33[y;xH设置光标位置
    51. # \33[2J 清屏
    52. # \33[K 清除从光标到行尾的内容
    53. # \33[s 保存光标位置
    54. # \33[u 恢复光标位置
    55. # \33[?25l 隐藏光标
    56. # \33[?25h 显示光标
    57. # \x1b[2J\x1b[$;1H $表示行位
    58. # 参数选项
    59. options() {
    60. echo "\033[0;31m"
    61. echo "参数: [-u, -c]"
    62. echo " -u 清理混淆回到未混淆的时候"
    63. echo " -c 去混淆 备份 混淆"
    64. echo "\033[0m"
    65. }
    66. # 配置info
    67. info() {
    68. local green="\033[1;32m"
    69. local normal="\033[0m"
    70. echo "[${green}info${normal}] $1"
    71. }
    72. #要混淆前缀
    73. CONFUSE_PREFIX="HD"
    74. #混淆标记文件
    75. CONFUSE_FLAG=".confuseFlag"
    76. #恢复回混淆前文件
    77. BACKUP_FILE=".backup.log"
    78. #象征文件
    79. SYMBOL_FILE=".symbol.log"
    80. # 混淆文件
    81. CONFUSE_FILE=".confuse.log"
    82. #删除存在的文件
    83. removeIfExist(){
    84. if [ -f $1 ]; then
    85. rm $1
    86. fi
    87. }
    88. # 备份文件
    89. backupFile() {
    90. file=$1
    91. # 在原文件名前加个. (点符合)用作备份名
    92. fileName=${file##*/}
    93. backupPath=${file/$fileName/.$fileName$BACKUP_EXTENSION}
    94. echo "backup $file to $backupPath"
    95. if [ ! -f $backupPath ]; then
    96. cp $file $backupPath
    97. echo $backupPath >>$BACKUP_FILE
    98. fi
    99. }
    100. SOURCE_ARRAY=("*.swift"
    101. "*.m"
    102. "*.h"
    103. "*.c"
    104. "*.cpp")
    105. BACKUP_EXTENSION=".bak"
    106. # 随机生成字符串
    107. randomString() {
    108. openssl rand -base64 64 | tr -cd 'a-zA-Z' | head -c 16
    109. }
    110. # 获取符号随机字符串
    111. randomStringWithSymbol() {
    112. grep -w $1 $SYMBOL_FILE -h | cut -d \ -f 2
    113. }
    114. if [ -z "$PROJECT_NAME" ]; then
    115. CONFUSE_DIR="."
    116. else
    117. CONFUSE_DIR="${SRCROOT}/${PROJECT_NAME}"
    118. fi
    119. main() {
    120. case $1 in
    121. "-u")
    122. echo "清理混淆回到未混淆的时候"
    123. unconfuse
    124. ;;
    125. "-c")
    126. echo "去混淆 备份 混淆"
    127. safeConfuse
    128. ;;
    129. *)
    130. echo "请添加您要选择的参数选项"
    131. options
    132. ;;
    133. esac
    134. }
    135. # 清理,去混淆
    136. unconfuse() {
    137. info "混淆清理中..."
    138. if [ -f $CONFUSE_FLAG ]; then
    139. #恢复混淆的函数名所在Source文件bak内容
    140. cat $BACKUP_FILE | while read backup; do
    141. backupName=${backup##*/}
    142. fileName=`echo $backupName | cut -d "." -f2,3`
    143. filePath=${backup/$backupName/$fileName}
    144. echo "recover $backup to $filePath"
    145. cp $backup $filePath
    146. rm $backup
    147. done
    148. # 删除修改记录
    149. removeIfExist $SYMBOL_FILE
    150. removeIfExist $CONFUSE_FILE
    151. removeIfExist $BACKUP_FILE
    152. removeIfExist $CONFUSE_FLAG
    153. else
    154. echo "没有混淆!!!"
    155. fi
    156. info "混淆清理完成"
    157. }
    158. #检查上次是否未完成
    159. precheck() {
    160. # 创建一个隐藏文件,标记混淆编译状态
    161. # 由于编译过程中可能被中断,因此混淆后的代码可能未恢复,在开始备份前先做判断
    162. unconfuse
    163. touch $CONFUSE_FLAG
    164. }
    165. # 备份所有source文件
    166. backupAllSource() {
    167. info "备份所有Swift文件"
    168. NAMES="-name \"${SOURCE_ARRAY[0]}\""
    169. I=1
    170. while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do
    171. NAMES+=" -or -name \"${SOURCE_ARRAY[$i]}\""
    172. let I++
    173. done
    174. removeIfExist $BACKUP_FILE
    175. touch $BACKUP_FILE
    176. eval "find $CONFUSE_DIR $NAMES" | while read file; do
    177. backupFile $file
    178. done
    179. }
    180. # 真正开始混淆工作
    181. confuseOnly() {
    182. info "开始混淆中..."
    183. # 获取要混淆的函数名和变量名
    184. INCLUDES="--include=\"${SOURCE_ARRAY[0]}\""
    185. I=1
    186. while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do
    187. INCLUDES+=" --include=\"${SOURCE_ARRAY[$i]}\""
    188. let I++
    189. done
    190. eval "grep $CONFUSE_PREFIX -r $CONFUSE_DIR $INCLUDES -n" >$CONFUSE_FILE
    191. # 绑定随机字符串
    192. removeIfExist $SYMBOL_FILE
    193. touch $SYMBOL_FILE
    194. cat $CONFUSE_FILE | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort | uniq | while read line; do
    195. echo $line" `randomString`" >>$SYMBOL_FILE
    196. done
    197. #读取备份文件记录
    198. cat $CONFUSE_FILE | while read line; do
    199. # 截取行号
    200. lineNum=`echo $line | sed 's/.*:\([0-9]*\):.*/\1/g'`
    201. # 截取文件路径
    202. path=${line%%:*}
    203. echo $line | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort -r | while read -ra symbol; do
    204. # 根据名称获取绑定的随机字符串
    205. random=`randomStringWithSymbol $symbol`
    206. sed -i "" "${lineNum}s/$symbol/$random/g" $path
    207. echo " $symbol => $random"
    208. done
    209. done
    210. info "混淆完成"
    211. }
    212. # 去混淆,备份,混淆
    213. safeConfuse() {
    214. precheck
    215. backupAllSource
    216. confuseOnly
    217. }
    218. main $@

    3. 修改指令文件的权限

    终端cd到项目,修改文件权限

    $ cd /Users/gamin/Desktop/hdj-ios
    $ chmod 755 confuse.sh

    4. 去混淆

    终端执行.sh脚本。-u 清理混淆回到未混淆的时候,-c 去混淆 备份 混淆。

     

     5. 不足之处

    脚本有一些bug,无法完美匹配混淆,会有漏网之鱼。另外,无法混淆目录中的文件名称,需要花大量时间去人工排错。

    OC项目代码混淆

    1. 新建confuse.shfunc.list文件

    终端cd到项目,新建文件。

    $ cd /Users/gamin/Desktop/hdj-ios
    $ touch confuse.sh
    $ touch func.list

    2. 编辑指令文件

    打开confuse.sh文件,写入以下文本。

    1. #!/usr/bin/env bash
    2. TABLENAME=symbols
    3. SYMBOL_DB_FILE="symbols"
    4. STRING_SYMBOL_FILE="func.list"
    5. HEAD_FILE="$PROJECT_DIR/$PROJECT_NAME/codeObfuscation.h"
    6. export LC_CTYPE=C
    7. #维护数据库方便日后作排重
    8. createTable()
    9. {
    10. echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
    11. }
    12. insertValue()
    13. {
    14. echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
    15. }
    16. query()
    17. {
    18. echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE
    19. }
    20. ramdomString()
    21. {
    22. openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
    23. }
    24. rm -f $SYMBOL_DB_FILE
    25. rm -f $HEAD_FILE
    26. createTable
    27. touch $HEAD_FILE
    28. echo '#ifndef Demo_codeObfuscation_h
    29. #define Demo_codeObfuscation_h' >> $HEAD_FILE
    30. echo "//confuse string at `date`" >> $HEAD_FILE
    31. cat "$STRING_SYMBOL_FILE" | while read -ra line; do
    32. if [[ ! -z "$line" ]]; then
    33. ramdom=`ramdomString`
    34. echo $line $ramdom
    35. insertValue $line $ramdom
    36. echo "#define $line $ramdom" >> $HEAD_FILE
    37. fi
    38. done
    39. echo "#endif" >> $HEAD_FILE
    40. sqlite3 $SYMBOL_DB_FILE .dump

    3. 修改指令文件的权限 

    终端cd到项目,修改文件权限。

    $ cd /Users/gamin/Desktop/hdj-ios
    $ chmod 755 confuse.sh

    4. 将文件导入项目根目录

     5. 配置RunScript

    到TARGETS -> Build Phases点击“+”新建Run Script

    在Run Script输入文本

    $PROJECT_DIR/confuse.sh

    6. 创建和配置pch文件

    新建PrefixHeader.pch文件

     Build Settings中配置Prefix Header,并将Precompile Prefix Header设置为YES。

    $(SRCROOT)/hdjlm/PrefixHeader.pch

    打开pch文件,引入codeObfuscation.h文件。

    #import "codeObfuscation.h"

    7. 添加需要混淆的方法

    打开func.list文件,在文件内输入需要进行混淆的属性名称和方法名称。

    sourceImgView
    resultImagView
    colorAtPixel
    testAction
    testOneAction
    gaminName
    SelectColorViewController
    GGTest

    8. 运行项目

    混淆成功后,代码中对应的字符串会改变颜色,点击Jump to Definition会跳转到codeObfuscation.h文件。

     

     9. 使用class-dump分析Mach-O文件

    项目被逆向时,被混淆的类名和方法名变成了混乱的字符串。

  • 相关阅读:
    抽象轻松的java——简单的购物车系统
    编译和运行一个ARM64内核
    【ACWing】3531. 哈夫曼树
    物联网开发笔记(52)- 使用Micropython开发ESP32开发板之多线程
    STATA
    Discuz论坛网站搭建教程,从0开始学会搭建网站
    ORB(Oriented FAST and Rotated BRIEF)
    Postgresql中ParamListInfoData的作用
    [汇编语言王爽]笔记2--p18-p22
    【ICASSP 2023】ST-MVDNET++论文阅读分析与总结
  • 原文地址:https://blog.csdn.net/u012881779/article/details/128026227