0%

代码混淆

为什么要使用代码混淆,下面来用一个 DEMO 简单的告诉大家如何获取 VIP

下面用一个实例来验证,没有代码混淆的程序我们可以看到什么,可以做什么?

首先我们创建一个简单的 命令行程序,EHUser里有一个 isVIP 方法判断用户是否是VIP:

2021-02-20-15104511577489

  1. 使用 class-dump 命令后工具,我们可以把程序的头文件导出来
class-dump -H ~/Downloads/HopperTest -o ~/Downloads/demo

2021-02-20-15104771683883

EHUser 的方法名一览无余

  1. 使用hopper工具,我们可以修改 isVIP 的方法逻辑
  • 查看 isVIP 方法
    2021-02-20-15104775647034
    甚至可以查看伪代码:
    2021-02-20-15104775986307

  • 这里可以把方法统一返回 YES,那么就算破解了这个isVIP方法了,添加mov rax,0x01始终返回yes

2021-02-20-15104775607304

  • 保存修改之后的程序,然后运行:
    2021-02-20-15104777215017

使用脚本混淆代码

原理:使用脚本,对项目里的方法名,进行宏替换

  1. 打开项目,选择target -> Build Phases,添加一个 Run Script
$PROJECT_DIR/gre3K/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"

export LC_CTYPE=C
# #取以.m或.h结尾的文件以+号或-号开头的行 |去掉所有+号或-号|用空格代替符号|n个空格跟着<号 替换成 <号|开头不能是IBAction|用空格split字串取第二部分|排序|去重复|删除空行|删掉以init开头的行>写进func.list
# 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 "/^gre_/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. 在项目里添加codeObfuscation.hfunc.list文件
  2. func.list 里填入需要替换的方法名,换行添加另一个
  3. 在项目里引用”codeObfuscation.h”,然后编译项目
  4. 正常情况下, 这个时候,填入的方法已经被替换成宏里,可以去codeObfuscation.h查看生成的宏

需要设置的地方

为了不影响开发测试

只在release下运行脚本,指定target运行脚本,在release下才导入宏头文件。

需要注意的问题

  • 注意:

    • 对于类方法,会出问题
    • 对象方法,某些情况下编译会报错,莫名其妙
    • 最好不要对大量使用的方法进行替换,会出现莫名其妙的问题,可能都启动不起来,编译一下就知道了
    • 不要引入到项目里,打包ipa里会存在这个文件
  • 建议:

    • 对关键方法使用
    • 对 target 进行判断,引用头文件
  • 还需要解决的问题

    1. 每次生成的宏都是随机的,这就对调试造成印象,自己查看崩溃日志都不知道是哪个方法出问题了。
      • 解决思路:使用加盐的哈希,这样自己可以通过key来配对真正的函数方法。
    2. 是否可以过审核?GRE3000貌似被查出来,发现脚本导入到项目里,会被打到ipa文件里,
    3. 每次生成的宏头文件,在git会有引起冲突的可能

链接

class dump使用方式和原理

一个数字的魔法——破解Mac上198元的Paw

破解InterfaceInspector的3种方法