背景:
最近做APP备案,需要对项目做一系列对优化改进,其中就包括了代码混淆,顾名思义,混淆是为了代码安全,是为了增加逆向破解的难度与复杂度。
目前市面上,免费和付费都有,一些公司对APP加固已经做成了产业,形成了一整套的解决方案,不过收费也是杠杠的,我也联系了其中一家,收费大概是【一年】【单APP】价格是2W(多APP价格可以再商量,应该会便宜点吧),当然这是他们号称的整个加固策略解决方案的价格。
说明:
不过呢,因为一些原因,我就暂时从开源的一些免费方案寻找解决处理,而且我们目前只是针对代码混淆安全性上的需求,所以就有了本篇文章。
进行了一些调研之后,我发现其实很多项目的早期混淆,大多是基于念茜大大的思路做的延伸扩展,基本思路为下:
写一个脚本,将项目中的一些敏感方法名集中写在一个名叫func.list的文件中,逐一#define成随机字符
原文地址:https://blog.csdn.net/yiyaaixuexi/article/details/29201699 有兴趣可以看一下
用这种方式,需要新建两个文件,一个混淆脚本,一个fun函数列表,用于添加你所需要混淆的方法,然后在Build Phases里添加执行Run Script
因为她这篇文章写的比较早,后面也有很多朋友对此基础上,做了一些优化更新,基本网上也都能搜到,甚至有些朋友直接做成了mac工具,直接拖动项目路径,配置一下前缀等关键词,就能一键混淆。
比如:iOS_NQConfuseTool ,不过这个工具填的参数比较多,出了问题就容易不响应了,囧,可以了解下,不是特别推荐
正文:
其实最开始我想象中的方案,是不用通过前缀来判别的,因为我想,对老项目太不友好了,还得针对类名、方法名一大堆慢慢加前缀什么的,工作量太大了,因此,我就在想,有没有更好的只能混淆方案呢?
结果是还真被我找到了,就是我的理解力不够,最终还是没能实现,且听我说完。
这个工具就是:swiftshield
在发现这个工具时,我就在想,太好了,这个牛逼啊,功能强大,使用简单
不过我按照他的描述配置后,发现没起作用,在终端运行后,会提示我swiftshield没找到,目前暂还没找到解决方案,因此有搞定的朋友千万记得给我留个言,在线等。。。
不过即使生活qj了你,你还得过日子啊,此路不通,换条路继续,只不过路没这么好走罢了
我重新找到了一个方案,虽然不是智能一键混淆,但操作起来还是相对比较便捷的
思路:也是通过脚本实现前缀识别替换。
这个方案操作起来大概分以下几个步骤:
1、创建一个空 confuseAndBuild.sh文件,拖动到项目根目录(名字自己取)
2、将下面的脚本拷贝进去,注意:脚本的前缀是需要配置的,改成你自己的就行,脚本默认是"hunxiao_"
这是脚本!!!
#!/bin/bash # confuseAndBuild.sh # ConfuseSwift # # ⚠️声明 # 1. 请将该脚本放在Xcode的Project工程的根目录。 # 2. 当前版本未配置完整Xcode环境变量,仅支持混淆功能,不支持framework编译,若需编译请用Xcode运行该脚本。 # ⚠️教程 # https://www.jianshu.com/p/be751f780d94 # 直接在终端cd到confuseAndBuild.sh上一层目录,然后运行./confuseAndBuild.sh -c 即可 if [ -z "$PROJECT_NAME" ]; then CONFUSE_DIR="." else CONFUSE_DIR="${SRCROOT}/${PROJECT_NAME}" fi # ⚠️自己配置自己的前缀 CONFUSE_PREFIX="hunxiao_" BACKUP_FILE=".backup.log" SYMBOL_FILE=".symbol.log" CONFUSE_FILE=".confuse.log" CONFUSE_FLAG=".confuseFlag" SOURCE_ARRAY=( "*.swift" "*.m" "*.h" "*.c" "*.cpp") BACKUP_EXTENSION=".bak" # 格式:echo -e "\033[背景色;前景色m 打印的字符串 \033[0m" # 颜色:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。 # 示例:echo -e “\033[30m 我是黑色字 \033[0m” # 参考:https://www.cnblogs.com/xiansong1005/p/7221316.html # https://www.cnblogs.com/lr-ting/archive/2013/02/28/2936792.html info() { local green="\033[1;32m" local normal="\033[0m" echo -e "[${green}info${normal}] $1" } error() { local red="\033[1;31m" local normal="\033[0m" echo -e "[${red}error${normal}] $1" } # 生成随机字符串 16字 randomString() { openssl rand -base64 64 | tr -cd \'a-zA-Z\' | head -c 16 } # 获取符号的随机字符串 $1是符号名 randomStringWithSymbol() { grep -w $1 $SYMBOL_FILE -h | cut -d \ -f 2 } removeIfExist() { if [ -f $1 ]; then rm $1 fi } # 备份文件 $1:file full path backupFile() { file=$1 # 在原文件名前加个.(点符合)用作备份名 fileName=${file##*/} backupPath=${file/$fileName/.$fileName$BACKUP_EXTENSION} echo "backup $file to $backupPath" if [ ! -f $backupPath ]; then cp $file $backupPath echo $backupPath >>$BACKUP_FILE fi } # 方案1. 精确备份:用关键字遍历会修改到的source文件,再将其备份 -- 消耗性能 # 方案2. 整体备份:备份所有source文件 -- 消耗存储空间 # 根据需要,为简单起见,这里选用方案2 backupAllSource() { info "backup all swift files" NAMES="-name \"${SOURCE_ARRAY[0]}\"" i=1 while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do NAMES+=" -or -name \"${SOURCE_ARRAY[$i]}\"" let i++ done # echo $NAMES removeIfExist $BACKUP_FILE touch $BACKUP_FILE eval "find $CONFUSE_DIR $NAMES" | while read file; do backupFile $file done } # 混淆工作, ⚠️该函数不会自动备份,要备份请调用safeConfuse函数 confuseOnly() { info "confuse start..." # 获取要混淆的函数名和变量名 INCLUDES="--include=\"${SOURCE_ARRAY[0]}\"" i=1 while [ $i -lt ${#SOURCE_ARRAY[@]} ]; do INCLUDES+=" --include=\"${SOURCE_ARRAY[$i]}\"" let i++ done eval "grep $CONFUSE_PREFIX -r $CONFUSE_DIR $INCLUDES -n" >$CONFUSE_FILE # cat $CONFUSE_FILE # 绑定随机字符串 removeIfExist $SYMBOL_FILE touch $SYMBOL_FILE cat $CONFUSE_FILE | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*" -o | sort | uniq | while read line; do echo $line" `randomString`" >>$SYMBOL_FILE done # cat $SYMBOL_FILE # 读取备份文件记录 # 在这里没使用遍历批量替换,怕文件太多的时候影响性能 cat $CONFUSE_FILE | while read line; do # echo "> $line" # 截取行号 lineNum=`echo $line | sed \'s/.*:\([0-9]*\):.*/\1/g\'` # 截取文件路径 path=${line%%:*} # 一行可能有多个要替换的子串,要循环遍历完 # 这里之所以要用`sort -r`倒序是因为有个bug:如有字符串"jjyy abc hello abcde", 现在要替换"abc"为"123"(abcde保持不变),也就是传说中的‘全匹配替换’, # 但不知为何在macOS下单词边界表达式不起作用:\<abc\> 或者 \babc\b都不起作用,Linux下这个正则表达式是没问题的。 # 倒序之后有长串优先替换长串,防止短串把长串部分替换掉。但依然存在bug:若是长串不需要替换,则短串替换是依然会将长串部分替换
请发表评论