美文网首页iOS混淆加密
iOS代码混淆(转)

iOS代码混淆(转)

作者: 一Bu小心丶 | 来源:发表于2017-09-08 16:18 被阅读54次

    该脚本大致使用的工具如下:vi、grep、sed、find、awk、cut、sort、uniq、cat、md5等。

    针对要加密的内容,分别给出关键字提取脚本命令。

    脚本中$ROOTFOLDER代表工程根目录,$EXCLUDE_DIR 代表要排除的目录,举例如下:

    [objc]view plaincopy

    ROOTFOLDER="demoProject"

    EXCLUDE_DIR="--exclude-dir=*.framework --exclude-dir=include --exclude-dir=libraries --exclude-dir=Libs --exclude-dir=lib"

    关键字提取

    1.文件名

    第一步先将包含路径的文件名写入文件

    [objc]view plaincopy

    find $ROOTFOLDER -type f | sed"/\/\./d">f.list

    第二步文件中提取文件名

    [objc]view plaincopy

    cat f_rep.list| awk -F/'{print $NF;}'| awk -F.'{print $1;}'| sed"/^$/d"| sort | uniq

    但从文件名提取的功能上,上面两个步骤完全可以合并为一步,但是在实际功能实现中还是要求将上面分为两步的

    2.类名

    [objc]view plaincopy

    grep -h -r -I"^@interface"$ROOTFOLDER  $EXCLUDE_DIR  --include'*.[mh]'| sed"s/[:(]/ /"|awk'{split($0,s," ");print s[2];}'|sort|uniq

    其中sort,排序;uniq 去除重复的

    3.协议名

    [objc]view plaincopy

    grep -h -r -I"^@protocol"$ROOTFOLDER  $EXCLUDE_DIR  --include'*.[mh]'| sed"s/[\<,;].*$//g"|awk'{print $2;}'| sort | uniq

    4.属性名

    [objc]view plaincopy

    grep -r -h -I  ^@property$ROOTFOLDER  $EXCLUDE_DIR --include'*.[mh]'| sed"s/(.*)/ /g"| sed"s/<.*>//g"|sed"s/[,*;]/ /g"| sed"s/IBOutlet/ /g"|awk'{split($0,s," ");print s[3];}'|sed"/^$/d"| sort |uniq

    其中

    [objc]view plaincopy

    sed"/^$/d"

    是去除空行,

    5.函数名

    [objc]view plaincopy

    grep -h -r -I"^[-+]"$ROOTFOLDER $EXCLUDE_DIR --include'*.[mh]'|sed"s/[+-]//g"|sed"s/[();,: *\^\/\{]/ /g"|sed"s/[ ]*

    函数名提取,目前只是提取函数名第一段的名称,如:

    [objc]view plaincopy

    -(void)funName:(NSString*)param1secondParam:(NSString*)param2;

    那么该脚本只会提取出funName。脚本中

    [objc]view plaincopy

    sed"/^init/d"

    是将函数中的以init开头的函数去除,因为,oc中初始化函数默认是以init开头的,如果把该类的函数也混淆的话,会有问题的。

    那么,以上脚本即可实现各种关键词的收集,收集后合并成一个文件,然后再排序去重复。

    小小结

    上述脚本提取出来的关键字包括系统自带的,也包括我们自己自定添加的,如果全部拿出混淆,那么我们混淆后的程序肯定是无法运行的,甚至无法通过编译。那么我们该怎么办?这个问题就是设计篇中提出的比较麻烦多事。最容易想到点方法就是,判断该关键字是否是系统自用的,如果是就不去混淆,相反就去混淆。那怎么系统用了哪些关键字?简单的很了,就是用上述提到的脚本,将系统使用的关键字,提取出来,作为系统自用的保留字。这样用排除法就可以解决这个麻烦的问题了,虽然比较笨拙,但是管用。

    那么第一步就需要制作一个系统保留字字典库。用上述脚本即可完成。

    那么第二步就是提取要替换的关键字,同样是用上述脚本,仔细看,你会发现个问题。提取文件名的时候,是将所有文件名都提取出来了,包括排除的目录,因此,在这个地方会有问题。我们要在文件名提取时,排除已经排除的目录或者将排除的目录文件名作为临时保留字。

    过滤并加密保留字

    将以上两步获取的关键字进行过滤。

    [objc]view plaincopy

    cat $SOURCECODEKEYWORDS |

    whileread line

    do

    ifgrep $line $RESKEYSALL

    then

    echofilter1: $line

    else

    md5-r -s $line  | sed s/\"//g >> $REPLACEKEYWORDS

    fi

    done

    其中$SOURCECODEKEYWORDS是从ROOTFOLDER中提取的要混淆的关键字

    替换工程中关键字

    该步骤是本功能的核心,要实现文件中的关键字替换,不对,准确的说,应该是文件中的关键字单词替换。这个就是设计篇中提到的问题。

    愿字符串:"This is my fish.” 要将is” 替换为”is not“。我们希望的当然是:“This is not my fish.” 而不是“This not is not my fis noth.” 。也就是说,要达到想要的目的,必须是单词匹配替换,这个很重要。经过实践证明,OS X版的sed并没有实现单词匹配替换,只能是将匹配正则表达式的行,进行字符串替换,也就是替换后是我们不想要的结果。这个可肿么办?还好经过一番挖掘,找到一种比较笨拙的办法,效果如下,又要发挥愚公精神了。

    [objc]view plaincopy

    sed -i'''

    '"$v2"'s/)'"$var2"':/)'"$var1"':/g

    '"$v2"'s/('"$var2"':/('"$var1"':/g

    '"$v2"'s/'"$var2"':/'"$var1"':/g

    '"$v2"'s/\"'"$var2"':/\"'"$var1"':/g

    ' $v1

    其中,v2代表行号;var2代表要替换的关键字,即例子中的“is”;var1是混淆后的字符串;v1 是指文件路径,包括文件名;-i表示直接修改文件,后面必须带两个单引号,要不然会有错误,单引号内容应该是要备份的文件名,在此不需要备份所以为空;在第一行和最后一行之间的意思是,描述单词出现时的各种场景,要想达到单词匹配的效果,那就在此必须列举所有情景,这个真够蛋疼的~~,愚公上吧!!!

    这个还有一个办法是,自己写一个程序实现文件中的单词替换;

    还还有一个方法是:大神,您给个呗!最后的办法:求大神了.....

    替换属性设置方法

    [objc]view plaincopy

    cat repProperty.txt|

    whileread line

    do

    ar=(`echo"$line"|cut -f1-2-d" "`)

    first=`echo ${ar[1]}|cut -c -1| sed"y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/"`

    second=`echo ${ar[1]}|cut -c2-`

    lastFind=`echo set$first$second`

    lastRep=`echo setZ${ar[0]}m`

    rm -f rep.tmp

    ifgrep -r -n -I -w"$lastFind"$ROOTFOLDER $EXCLUDE_DIR   --include="*.[mhc]"--include="*.mm"--include="*.storyboard"--include="*.xib">rep.tmp

    then

    cat rep.tmp|

    whileread l

    do

    v1=$(echo"$l"|cut -d: -f1)

    v2=$(echo"$l"|cut -d: -f2)

    sed -i''''"$v2"'s/'"$lastFind"'/'"$lastRep"'/g'$v1

    echo"step3:"$l

    done

    else

    echo"step3:do not find:"$lastFind

    fi

    done

    这个也是相对比较麻烦的,因为oc的属性系统是可以自动合成setter函数的,所以属性的混淆需要额外多考虑点。上面的做法是,根据提取的过滤后的属性关键字,生成属性设置函数,然后查找过程中是否有用到,有就混淆掉。

    文件名混淆

    [objc]view plaincopy

    cat f_rep.list|

    whileread line

    do

    echo"old name:"$line

    v1=$(echo"$line"| sed"s/\// /g"| awk'{print $NF}')

    echo"v1="$v1

    v2=$(echo $v1| sed"s/\./ /g"| awk'{print $1}')

    echo"v2="$v2

    ifgrep -w $v2$RESKEYSALL

    then

    echo"find."

    else

    v3=$(echo $v1| sed"s/\./ /g"| awk'{print "."$2}')

    echo"v3="$v3

    v4=$(md5-q -s"$v2"| sed"s/.*/z&m/g")

    echo"v4="$v4

    v5=$(echo"$line"| sed"s/"$v1"//g")

    echo"v5="$v5

    mv $line $v5$v4$v3

    echo"new name:"$v5$v4$v3

    fi

    done

    文件名混淆的原理就是将需要混淆的文件路径,提取出要混淆的部分,然后组合成最终的文件名,使用mv命令完成文件名混淆。

    至此,设计篇中提及的要混淆的内容已经全部完成混淆。

    注意事项

    1.需要将工程名称作为临时保留关键字

    如:工程名称demoProject,那么demoProject要作为保留字,否则混淆后,可能target的名称也会被混淆掉,这个不是我们期望的;

    2.需要将工程中的子目录名称作为临时保留关键字

    如:在工程目录下有子文件夹AFNetworking,在Xcode工程的导航里也可以看到AFNetworking的分组,此时,如果AFNetworking也被混淆,那么工程中的分组会变成混淆后的字符串,但是工程目录下的子文件夹AFNetworking并没有改变,所以此时,会找不到响应的文件;根本原因是我们的混淆没有对文件夹名进行混淆。

    3.需要将访问网络时组织的参数名称作为临时保留关键字

    如:有一个属性名为:passport;恰好在组织网络参数时,有一个字段也叫passport,如果作为属性关键字passport被混淆了,那么组织网络参数时用的passport也会被混淆掉,所以此时传给后台的关键字passport就变了,导致后台无法识别;因此,出现这个情况时,要添加到临时的保留字中;如果编码规范的话,不用添加临时保留字也会避免~

    4......

    下面是混淆后的效果截图:

    https://github.com/kongcup/ZMConfuse

    1.终端cd 到zmconfuse.sh文件 所在的文件夹内。

    2.再把你的工程文件拷贝到此文件夹内。

    3.打开zmconfuse.sh文件,把 ROOTFOLDER="shakefun" 的shakefun替换成你的工程文件名。

    4.添加排除的第三方库等。保存修改。

    5.直接把zmconfuse.sh文件,拖到终端内,ENTER。

    完成!!

    转自:http://blog.csdn.net/zm53373581/article/details/49120895

    相关文章

      网友评论

        本文标题:iOS代码混淆(转)

        本文链接:https://www.haomeiwen.com/subject/wkfnjxtx.html