iOS开发-代码混淆

iOS表面上看来是比android安全的多的,在网络上针对android的加密保护也比iOS多得多,但是这并不意味着iOS就是很安全的,如果在正常的设备上还好,但是在越狱的设备上,我们的代码信息就会暴露的一干二净,不仅可以被别人看到我们的方法是如何调用的,就连我们那些写的很垃圾的代码也会被人看的一清二楚,想想就是很丢人的事情,我这个菜鸡对iOS安全了解的也并不是很多,这篇文章也就仅根据念茜女神的博客对iOS中的代码混淆做一些初步的处理,如果你是稍微知道一点点iOS安全的东西,这时候就可以cmd+w拜拜了。

好了,开始正文。

class-dump

This is a command-line utility for examining the Objective-C runtime information stored in Mach-O files. It generates declarations for the classes, categories and protocols. This is the same information provided by using ‘otool -ov’, but presented as normal Objective-C declarations, so it is much more compact and readable.

以上是class-dump的简介,他可以利用OC的runtime属性,把存储在mach-O文件中的@interface和@protocol信息提取出来,并生成对应的.h文件。说白了他就是可以把你的代码中.h头文件里的所有方法和参数挖掘出来,那他具体要怎么样来使用呢?

下载安装包

  • 1.首先是下载地址,我下载的是3.5.dmg的版本。

  • 2.然后打开终端输入:open /usr/local/bin

  • 3.然后把dmg文件中的class-dump文件复制到刚刚打开的文件夹中。

  • 4.然后修改权限在终端输入:sudo chmod 777 /usr/local/bin/class-dump

到此为止就完成了class-dump的安装,具体的使用方法可以使用class-dump --help查看。

使用方法

首先我们要获取到我们要解析的.app文件,这里需要注意一点,直接从App Store下载下来的应用是没办法解析的,因为苹果对他们进行了一层加密,需要砸壳之后才能解析。

这里我们就直接用Demo中打包出来的ipa进行示例。

  • 1.首先修改ipa文件的后缀为.zip;
  • 2.然后解压.zip文件,解压出Payload文件夹,这里边的.app文件就是我们需要的目标文件;
  • 3.在终端使用命令class-dump -H[.app文件路径] -o [输出文件夹路径];就会生成我们需要解析的文件中的.h文件了。
1
class-dump -H /Users/zhangzhongzui/Desktop/ConfusionDemo\ 2018-06-12\ 21-54-54/Payload/ConfusionDemo.app -o /Users/zhangzhongzui/Desktop/ConfusionDemo\ 2018-06-12\ 21-54-54/Payload

可以看到我们在代码里写的方法名,参数名都被解析出来了。

logo

真的是很可怕,有了这些方法名,坏人们就很容易利用他们来做坏事了。那接下来我们就来看看怎么样进行代码混淆,让我们的代码不是那么容易被解析出来吧。

代码混淆

创建准备文件

这里生成混淆代码的方法我们通过shell脚本来实现,同时我们需要一个文档来写入我们需要进行混淆的方法名或是变量名。

打开终端,cd到文件所在目录,使用

1
2
touch confuse.sh
touch func.list

然后将这两个文件加入到项目中。

logo

写入shell脚本

接下来我们在confuse.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
67
68
69
70
71
72
73
#!/bin/bash
# 这是Shell脚本,如果不懂shell,自行修炼:http://www.runoob.com/linux/linux-shell.html
# 以下使用sqlite3进行增加数据,如果不了解sqlite3命令,自行修炼:http://www.runoob.com/sqlite/sqlite-tutorial.html
#数据表名
TABLENAME="CodeObfuscationOC"
#数据库名
SYMBOL_DB_FILE="CodeObfuscation.db"
#要被替换的方法列表文件
STRING_SYMBOL_FILE="$PROJECT_DIR/ConfusionDemo/func.list"
#被替换后的宏定义在此文件里
HEAD_FILE="$PROJECT_DIR/$PROJECT_NAME/CodeObfuscation.h"
#维护数据库方便日后做bug排查
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
}
#生成随机16位名称
randomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' | head -c 16
}
#删除旧数据库文件
rm -f $SYMBOL_DB_FILE
#删除就宏定义文件
rm -f $HEAD_FILE
#创建数据表
createTable
#touch命令创建空文件,根据指定的路径
touch $HEAD_FILE
echo '#ifndef CodeObfuscation_h
#define CodeObfuscation_h' >> $HEAD_FILE
echo "//confuse string at `date`" >> $HEAD_FILE
#使用cat将方法列表文件里的内容全部读取出来,形成数组,然后逐行读取,并进行替换
cat "$STRING_SYMBOL_FILE" | while read -ra line;
do
if [[ ! -z "$line" ]]
then
random=`randomString`
echo $line $random
#将生成的随机字符串插入到表格中
insertValue $line $random
#将生成的字符串写入到宏定义文件中,变量是$HEAD_FILE
echo "#define $line $random" >> $HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE
sqlite3 $SYMBOL_DB_FILE .dump

添加run script命令

接下来打开Targets -> Bulid Phases -> + -> New Run Script Phase

logo

然后添加$PROJECT_DIR/ConfusionDemo/confuse.sh,让应用每次启动时去跑一下我们的脚本。

给脚本授权

接下来还是在我们项目的文件夹下,给我们的脚本赋予最高权限

1
chmod 777 confuse.sh

这里有人说用 755 ,但是用755好像还是不行,干脆给最高权限,用777。

添加预编译文件PCH

接下来再添加一个PCH文件,实现整个项目的替换。

logo

然后配置一下PCH文件。

logo

添加$PROJECT_DIR/ConfusionDemo/PrefixHeader.pch

生成CodeObfuscation.h文件

这时候我们编译一下代码,会发现项目中多出了一个CodeObfuscation.h文件。这个文件就是替换方法名的文件,我们在PCH文件中引入他。

在func中添加准备替换的方法名

ok,到了最后一步了,这时候我们只需要打开func.list文件,写入我们想要混淆的方法名。就大功告成了。

1
2
3
4
5
6
7
8
9
viewControllerTestMethodA
viewControllerTestMethodB
viewControllerTestMethodC
viewControllerMethodWithParameter
testString
testArray
testMutDic

结果

OK,该做的已经做完了,接下来我们再打一个包,看一下结果。

编译之后我们就可以看到,CodeObfuscation.h文件中就发生了变化。

1
2
3
4
5
6
7
8
9
10
11
#ifndef CodeObfuscation_h
#define CodeObfuscation_h
//confuse string at Tue Jun 12 22:28:04 CST 2018
#define viewControllerTestMethodA CTBxmOXAbJYekhnH
#define viewControllerTestMethodB RnPEjnXygFXLdikO
#define viewControllerTestMethodC IzHlDYOpaAFYFTXa
#define viewControllerMethodWithParameter nWqyalBcfoUSRVpc
#define testString MNPoVYdmCcklAnCO
#define testArray kHMRxPlGXGeqekxL
#define testMutDic hphPSODIvbBFSTHX
#endif
logo

可以看到,原来的代码都变成了一些乱七八糟的代码,混淆成功了。

最后

到此,今天的内容就基本结束了,这只是iOS安防的最基本最初级的工作,而且用的方法也是念茜女神很久以前提出的一个方案。并且这里有几点需要注意!!!

  • 1.不可以混淆iOS中的系统方法;
  • 2.不可以混淆iOS中init等初始化方法;
  • 3.不可以混淆xib的文件,会导致找不到对应文件;
  • 4.不可以混淆storyboard中用到的类名;
  • 5.混淆有风险,有可能会被App Store以2.1大礼包拒掉。

以上文章有什么不对的地方还请大佬多多指教和批评。

参考文档

class-dump的安装和使用
iOS开发/App安全/代码自动混淆<笔记>
iOS安全攻防(二十三):Objective-C代码混淆
iOS-代码混淆