真实可用的 swift代码混淆
问:知道必须要给代码混淆是什么感受?- Hardcoded encryption key - IOS
谢邀:
就 地铁老头看微信 + 黑人问号脸
关键还就给一天都不到的时间。。。。
这天研究了:
PPiOS-Rename——只能oc不能swift
Swiftshield—— 老是卡在GoogleMap的第三方库不能混淆 -i 忽略也不好使
太崩溃了
以下方法【转】自 : https://www.cnblogs.com/yajunLi/p/12172489.html 感恩的心❤~
这里备份下 希望可以让更多需要的兄die们看到
喜欢或者有帮助,请点个赞再走吧,么么哒
虽然不是智能一键混淆,但操作起来还是相对比较便捷的
思路:也是通过脚本实现前缀识别替换。
这个方案操作起来大概分以下几个步骤:
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="."elseCONFUSE_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.htmlinfo() {
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 -base6464| tr -cd'a-zA-Z'| head -c16}
# 获取符号的随机字符串 $1是符号名
randomStringWithSymbol() {
grep -w $1$SYMBOL_FILE -h | cut -d \ -f2}
removeIfExist() {if[ -f $1 ]; then
rm $1fi
}
# 备份文件 $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=1while[ $i -lt ${#SOURCE_ARRAY[@]} ];doNAMES+=" -or -name \"${SOURCE_ARRAY[$i]}\""let i++done
# echo $NAMES
removeIfExist $BACKUP_FILE
touch $BACKUP_FILE
eval "find $CONFUSE_DIR $NAMES"|whileread file;dobackupFile $file
done
}
# 混淆工作, ⚠️该函数不会自动备份,要备份请调用safeConfuse函数
confuseOnly() {
info "confuse start..."# 获取要混淆的函数名和变量名
INCLUDES="--include=\"${SOURCE_ARRAY[0]}\""i=1while[ $i -lt ${#SOURCE_ARRAY[@]} ];doINCLUDES+=" --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 |whileread line;doecho $line" `randomString`">>$SYMBOL_FILE
done
# cat $SYMBOL_FILE
# 读取备份文件记录
# 在这里没使用遍历批量替换,怕文件太多的时候影响性能
cat $CONFUSE_FILE |whileread 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下单词边界表达式不起作用:\ 或者 \babc\b都不起作用,Linux下这个正则表达式是没问题的。
# 倒序之后有长串优先替换长串,防止短串把长串部分替换掉。但依然存在bug:若是长串不需要替换,则短串替换是依然会将长串部分替换😂
# 因此依然还需要寻找macOS下单词边界/全匹配 的正则表达式
echo $line | egrep -w $CONFUSE_PREFIX"[0-9a-zA-Z_]*"-o | sort -r |whileread -ra symbol;do# 根据名称获取绑定的随机字符串
random=`randomStringWithSymbol $symbol`
# echo "$path $lineNum $symbol $random"# 随机字符串替换
# -i:表示直接在原文件替换,"":表示不要备份
sed -i"""${lineNum}s/$symbol/$random/g" $path
echo " $symbol => $random"done
done
info "confuse done"}
# 编译工作,生成通用framework
buildAll() {
info "build start..."if[ -z"$PROJECT_NAME" ]; then
echo -e"\033[1;31mERROR:当前版本未配置完整Xcode环境变量,仅支持混淆功能,不支持framework编译,若需编译请用Xcode运行该脚本\033[0m"returnfi
# 要build的target名
TARGET_NAME=${PROJECT_NAME}
UNIVERSAL_OUTPUT_DIR="${SRCROOT}/Framework/"# 创建输出目录,并删除之前的framework文件
mkdir -p"${UNIVERSAL_OUTPUT_DIR}"rm -rf"${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework"#分别编译模拟器和真机的Framework
xcodebuild -target"${TARGET_NAME}"ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} ARCHS="armv7 armv7s arm64"-sdk iphoneos BUILD_DIR="${BUILD_DIR}"BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target"${TARGET_NAME}"ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} ARCHS="i386 x86_64"-sdk iphonesimulator BUILD_DIR="${BUILD_DIR}"BUILD_ROOT="${BUILD_ROOT}" clean build
#拷贝framework到univer目录
cp -R"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework""${UNIVERSAL_OUTPUT_DIR}"# 合并swiftmodule到univer目录
cp -R"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/""${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule"#合并framework,输出最终的framework到build目录
lipo -create -output"${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/${TARGET_NAME}""${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}""${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"#删除编译之后生成的无关的配置文件
dir_path="${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}.framework/"forfileinls $dir_path;doif[[ ${file} =~".xcconfig" ]]; then
rm -f"${dir_path}/${file}"fi
done
#判断build文件夹是否存在,存在则删除if[ -d"${SRCROOT}/build" ]; then
rm -rf"${SRCROOT}/build"fi
#rm -rf"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator""${BUILD_DIR}/${CONFIGURATION}-iphoneos"#打开合并后的文件夹
open "${UNIVERSAL_OUTPUT_DIR}"info "build done"}
# 清理工作,去混淆
unconfuse() {
info "clean start..."if[ -f $CONFUSE_FLAG ]; then
# 恢复混淆的函数名所在source文件的bak内容
cat $BACKUP_FILE |whileread backup;dobackupName=${backup##*/}
fileName=`echo $backupName | cut -d"."-f2,3`
filePath=${backup/$backupName/$fileName}
echo "recover $backup to $filePath"cp $backup $filePath
rm $backup
done
# 删除修改记录
removeIfExist $SYMBOL_FILE
removeIfExist $CONFUSE_FILE
removeIfExist $BACKUP_FILE
removeIfExist $CONFUSE_FLAGelseecho "Not confuse yet!"fi
info "clean done"}
# 检查是否上次未完成
precheck() {
# 创建一个隐藏文件,仅标记混淆编译的状态
# 由于编译过程有可能被中断,因此混淆后的代码可能未恢复,在开始备份前先做判断
unconfuse
touch $CONFUSE_FLAG
}
# 去混淆->备份->混淆
safeConfuse() {
precheck
backupAllSource
confuseOnly
}
# 去混淆->备份->混淆
# 编译
# 去混淆
safeConfuseAndBuild() {
info "preparing confuse and build..."safeConfuse
buildAll
unconfuse
info "all done"}
usage() {
echo -e"\033[1;31musage: ./confuseAndBuild.sh [-u|c|b|a]"echo -e" -u"echo -e" unconfuse: 清理工作,去混淆"echo -e" -c"echo -e" safeConfuse: 去混淆->备份->混淆"echo -e" -b"echo -e" buildAll: 编译生成通用framework"echo -e" -a"echo -e" safeConfuseAndBuild: 去混淆->备份->混淆->编译->去混淆"echo -e"EXAMPLE:"echo -e" ./confuseAndBuild.sh -u\033[0m"}
main() {
echo "参数个数:$# 参数值:$1"case$1in"-u" )
unconfuse
;;"-c" )
safeConfuse
;;"-b" )
buildAll
;;"-a" )
safeConfuseAndBuild
;;* )
usage
;;
esac
}
main $@
3、在项目里,把你认为的一些类名、方法名等添加前缀
4、打开终端,cd到confuseAndBuild.sh上一层目录,然后运行./confuseAndBuild.sh -c 即可
执行完上述4步后,查看项目,会发现有前缀的方法、类等,都已变成混淆后的字符,然后直接打包发布即可。
这里注意一点:执行完脚本之后,项目里的函数方法等就会变成混淆后的内容,会大大影响阅读醒,因此建议在发布时,执行一下脚本,先别提交,待打包好后,撤回混淆就行了
喜欢或者有帮助,请点个赞再走吧,么么哒