脚本混淆代码

1、逆向&破解:

  • 通过 dumpdecrypted 给 APP 砸壳;
  • 通过 class-dump 查看 .h文件里的函数;
  • 通过 Hopper、IDA Pro 等工具反编译后分析业务代码;
  • 通过 Reveal 在运行时调试和修改 iOS应用的 UI;

2、混淆代码

类名、方法名、变量名等会暴露APP的很多关键信息,攻击者通过 class-dump 得到头文件后,可以根据提取到的这些字符串,快速找到相关逻辑的处理函数,从而进行分析破解。所以,代码混淆很有必要性。混淆的主旨思想是:

  • 在开发阶段保留清晰可读的代码;
  • 在编译打包后的代码中,把一些敏感字符串变为为无意义的符号;
  • 增加攻击者阅读代码的难度以及根据字符串静态搜索的难度;

当然,手动替换工程中所有的类名、方法名、变量名,这肯定会是很大的一个工作量。所以,我们可以智能一点,使用脚本来帮我们做。通过脚本,扫描工程目录下所有.h & .m 文件,并对其中的敏感内容做替换。另外,可以配合 #define 别名的方式,增加破译难度。

3、混淆的实现:

3.1.在工程的根目录下,新建两个文件:

1
2
3
cd Desktop/CodeMix  //工程根目录
touch Confusion.sh //脚本
touch ToBeConfused.list //存放所有需要替换的敏感字

Confusion.sh,一个 shell 脚本文件,用来自动寻找工程目录下.h与.m文件中的所有敏感字,将它们替换为无意义的字符并定义成宏。

ToBeConfused.list, 用来保存所有需要替换的敏感字,其后缀格式无所谓,比如.text也可以。shell 脚本会从此文件中逐行取字符并把它替换为无意义的字符。

3.2.MapOfConfusion.h

在工程根目录下,新建 MapOfConfusion.h 文件。此文件与上面两个文件在同一目录下。作用是在混淆代码时,把自动生成的字符串定义成宏,存放在此文件中。

3.3.设置脚本

编辑 Confusion.sh 文件,输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/env bash

TABLENAME=symbols

SYMBOL_DB_FILE="symbols"

#ToBeConfused.list 路径
STRING_SYMBOL_FILE="$PROJECT_DIR/ToBeConfused.list"

#项目文件路径
CONFUSE_FILE="$SRCROOT"

#MapOfConfusion.h 路径
HEAD_FILE="$PROJECT_DIR/MapOfConfusion.h"

export LC_CTYPE=C

#取以.m或.h结尾的文件以+号或-号开头的行
#|去掉所有+号或-号|用空格代替符号|n个空格跟着<号 替换成 <号
#|开头不能是IBAction|用空格split字串取第二部分|排序|去重复|删除空行
#|删掉以init开头的行>写进ToBeConfused.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 "/^xMix_/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 MapOfConfusion_h
#define MapOfConfusion_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

上面的脚本会从工程根目录($SRCROOT)下的所有.m和.h文件中,自动找出以“xMix_”开头的待混淆函数名,写入 ToBeConfused.list 文件中。然后再从 ToBeConfused.list 中逐行提取函数名进行宏定义,宏定义使用随机字符串。然后写到 MapOfConfusion.h 文件中。

编辑完成后保存,然后执行下面命令,把 Confusion.sh 设置成可执行文件。

1
chmod +x Confusion.sh

3.4.添加 Run Script

工程 Targets-》build phases-》New Run script Phase,设置.sh文件路径:

1
$PROJECT_DIR/Confusion.sh

3.5.添加 PCH 文件

工程根目录下,新建 PrefixHeader.pch 文件,并导入 MapOfConfusion.h:

1
2
3
4
5
6
#ifndef PrefixHeader_pch
#define PrefixHeader_pch

#import "MapOfConfusion.h"

#endif /* PrefixHeader_pch */

工程 Targets-》build Settings 中搜索Prefix Header,设置好 pch 路径:

1
$PROJECT_DIR/PrefixHeader.pch

3.6.添加以xMix_开头的测试代码:

1
2
3
4
5
6
7
8
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

- (void)xMix_Function1;
- (void)xMix_Function2WithName:(NSString *)param1 xMix_Gender:(int)param2;

@end

3.7.build & class-dump

build 之后,打开 MapOfConfusion.h 文件,可以看到以xMix_开头的方法名都已被宏定义为一个随机字符串。

1
2
3
4
5
6
7
#ifndef MapOfConfusion_h
#define MapOfConfusion
//confuse string at Fri Dec 29 21:15:24 CST 2017
#define xMix_Function1 vKfXvdhupKXlBptl
#define xMix_Function2WithName xRDhGWmotGCNvgqp
#endif

打包之后,得到 ipa 文件,使用 class-dump 工具反编译出 ViewController.h 文件即可查看混淆之后的代码。(略)


相关参考:

#©念茜


脚本混淆代码
https://davidlii.cn/2019/03/25/confusion.html
作者
Davidli
发布于
2019年3月25日
许可协议