iOS 代码混淆

·  阅读 5029

前情

由于等保2.0中对未做代码混淆的危险评定为中级(爱加密本身提供代码混淆业务),而第三方的加固方案往往是需要收费的。

360免费版本需要enable bitcode设置为YES,有可能和一些第三方库冲突,因此决定自己来做代码混淆的事情。
代码混淆即对app进行代码混淆加固,提高逆向难度。

需要注意:苹果现在不允许进行代码混淆,过多的混淆会无法过审

原理

代码编译阶段,将符号(方法名、属性名等)替换成随机字符串。
我的做法是利用 #define methodName randomString 来实现方法名替换,因为在编译阶段,randomString 会被直接替换进methodName。

自定义脚本进行混淆

  1. 我们需要增加三个文件

  • func.list用于存放我们要替换的方法名
  • codeObfuscation.h中存放着宏定义
  • confuse.sh是关键,存放着程序编译时执行的脚本
  1. 在Build Phases中增加Run Script
$PROJECT_DIR/confuse.sh
复制代码
  1. 在confuse.sh中增加如下代码段,注意各种路径需要修改
#!/usr/bin/env bash
 
TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="$PROJECT_DIR/func.list"
HEAD_FILE="$PROJECT_DIR/codeObfuscation.h"
####这里是全局混淆要查找的内容路径,不需要全局混淆的时候要注释掉
CONFUSE_FILE="$PROJECT_DIR/ProjectName"
export LC_CTYPE=C
####这里是全局混淆要查找的条件,不需要全局混淆的时候要注释掉
#取以.m或.h结尾的文件以+号或-号开头的行 |去掉所有+号或-号|用空格代替符号|n个空格跟着<号 替换成 <号|开头不能是IBAction|用空格split字串取第二部分|排序|去重复|删除空行|删掉以init开头的行>写进func.list
## |sed -n "/^sk_/p" 是特定问方法名的开头,不需要的话可以删掉
#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 "/^IS_/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 Demo_codeObfuscation_h
#define Demo_codeObfuscation_h' >> $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
复制代码
  1. func.list中存放着将要混淆的方法名
funcA
funcB
funcC
复制代码
  1. codeobfuscation.h本身是一个空的头文件,当我们编译完成后,这个文件中就有了各种宏定义,例如:

获取符号名

有很多种方法可以获取符号名,这里提供一种思路:
通过 hook UIViewController 的 viewDidLoad: 方法,并增加如下代码:

NSLog(@"%@",[NSArray getPropertiesFromClass:[self class]]);
NSLog(@"%@",[NSArray getMethodsFromClass:[self class]]);
复制代码

注意点

  1. 去重
  2. 混淆后不要上架app store
  3. 无法对静态库进行混淆
  4. 不能对系统方法,属性等进行混淆

自动代码混淆

如果我们全部手动进行混淆,也是一种方法,但是会比较麻烦。

自动方法混淆需要提前将我们要混淆的方法,属性等增加前缀,例如"kx",然后对.sh脚本进行一些修改,即可完成自动代码混淆。

上文 .sh 文件中,将 grep 的那行注释放开,即可进行自动混淆。

其中

sed -n "/^kx_/p"
复制代码

这行是对以“zd”开头的方法或属性进行混淆。

缺点

如果我们写代码的时候没有提前给方法或属性增加前缀,则无法进行自动方法混淆。

这个时候我们可以通过半自动的方式,对一系列的方法进行自动混淆后,再手动增加一些方法或属性来达到我们的目的。

写在后面

代码混淆现在做的人已经比较少了,其中还有部分公司做这个是为了提高等保2.0的评分,所以这里提供一些方案,具体的操作要根据实际情况来看。

文中如有错误,欢迎指出。

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改