iOS-代碼混淆加固策略

技 術(shù) 文 章 / 超 人


對(duì)于IOS來說,由于系統(tǒng)是封閉的,APP上架需要通過App Store,安全性來說相當(dāng)高。但是對(duì)于大廠和知名APP而言,別人給的安全保障永遠(yuǎn)沒有自己做的來得踏實(shí)。所以對(duì)于大廠、少部分企業(yè)級(jí)和金融支付類應(yīng)用來說加固是相當(dāng)重要的。

下面是目前幾個(gè)專業(yè)加固大廠提供的加固策略

  • 網(wǎng)易


    網(wǎng)易

    網(wǎng)易安全三板斧:

  1. 第一板斧是防靜態(tài)分析,這里包括字符串加密、符號(hào)混淆、代碼邏輯混淆和游戲存檔加密;

2.第二板斧是防動(dòng)態(tài)調(diào)試、反調(diào)試和通信安全(數(shù)據(jù)加密);

  1. 第三板斧是外掛檢測(cè)、加速掛、內(nèi)存修改掛和自動(dòng)任務(wù)掛等
  • 愛加密


    愛加密
  • safengine


    afengine
  • 幾維安全


    幾維安全
  • 梆梆安全


    梆梆安全

本文將針對(duì)以上幾點(diǎn)進(jìn)行實(shí)現(xiàn),對(duì)于一些不太容易實(shí)現(xiàn)的將會(huì)做方向性討論

  • 字符串加密
  • 代碼混淆(方法命,類命,變量名,符號(hào)表)
  • 代碼邏輯混淆
  • 反調(diào)試

字符串加密

對(duì)字符串加密的方式目前我所了解到掌握到的最可靠方式就是用腳本將代碼中的所有標(biāo)記需要加密的字符串進(jìn)行異或轉(zhuǎn)換,這樣代碼中就不存在明文字符串了。當(dāng)然第三方的字符串加密不可能這么簡(jiǎn)單,具體怎么做的我也不太清楚。不過為了增加字符串加密的難度復(fù)雜性,我們可以先將字符串用加密工具轉(zhuǎn)換(例如AES、base64等)后的把加字符串放在工程中,并且把解密的鑰匙放在工程中,用異或轉(zhuǎn)換,把解密鑰匙和加密后的字符串轉(zhuǎn)換,這樣就有2層保障,增加了復(fù)雜度。

  • 首先 我們創(chuàng)建任意一個(gè)工程,在工程中寫入下面的代碼,并在每句打上斷點(diǎn),再選擇Xcode工具欄的Debug --> Debug Workflow --> Always Show Disassembly。這樣你就可以在斷點(diǎn)處進(jìn)入?yún)R編模式界面,最后運(yùn)行程序
/* 加密NSString字符串 */
    NSString *str = @"Hello World";
    NSLog(@"%@",str);
    /* 加密char*字符串 */
    char* cStr = "Super Man";
    NSLog(@"%s",cStr);
斷點(diǎn)處進(jìn)入?yún)R編模式界面

你會(huì)發(fā)現(xiàn),你的字符串內(nèi)容暴露在了匯編模式中,這會(huì)導(dǎo)致別人在逆向分析你的工程時(shí)能看見你的字符串內(nèi)容,我們一般接口、域名、加解密鑰匙串、AppKey、AppId等比較重要的東西會(huì)放在客戶端用作字符串,這就很容易暴露出來。

  • 步驟1 首先需要在工程代碼中進(jìn)行修改,把下面的宏和decryptConfusionCS,decryptConstString函數(shù)放入代碼中,用宏包含每個(gè)需要轉(zhuǎn)換的字符串。

/* 字符串混淆解密函數(shù),將char[] 形式字符數(shù)組和 aa異或運(yùn)算揭秘 */
extern char* decryptConfusionCS(char* string)
{
    char* origin_string = string;
    while(*string) {
        *string ^= 0xAA;
        string++;
    }
    return origin_string;
}

/* 解密函數(shù),返回的是NSString類型的 */
extern NSString* decryptConstString(char* string)
{
    /* 先執(zhí)行decryptConfusionString函數(shù)解密字符串 */
    char* str = decryptConfusionCS(string);
    /* 獲取字符串的長(zhǎng)度 */
    unsigned long len = strlen(str);
    NSUInteger length = [[NSString stringWithFormat:@"%lu",len] integerValue];
     NSString *resultString = [[NSString alloc]initWithBytes:str length:length encoding:NSUTF8StringEncoding];
    return resultString;
}


/*
 * 使用heyujia_confusion宏控制加密解密
 * 當(dāng)heyujia_confusion宏被定義的時(shí)候,執(zhí)行加密腳本,對(duì)字符串進(jìn)行加密
 * 當(dāng)heyujia_confusion宏被刪除或?yàn)槎x時(shí),執(zhí)行解密腳本,對(duì)字符串解密
 */
#define heyujia_confusion

#ifdef heyujia_confusion
/* heyujia_confusion 宏被定義,那么就進(jìn)行執(zhí)行解密腳本 */
/* confusion_NSSTRING宏的返回結(jié)果是NSString 類型的 */
#define confusion_NSSTRING(string) decryptConstString(string)
/* confusion_CSTRING宏的返回結(jié)果是char* 類型的 */
#define confusion_CSTRING(string) decryptConfusionCS(string)
#else
/* heyujia_confusion 宏沒有被定義,那么就執(zhí)行加密腳本 */
/* 加密NSString類型的 */
#define confusion_NSSTRING(string) @string
/* 加密char *類型的 */
#define confusion_CSTRING(string) string
#endif

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    /* 使用confusion_NSSTRING宏包含需要加密的NSString字符串 */
    NSString *str = confusion_NSSTRING("Hello World");
    NSLog(@"%@",str);
    /* 使用confusion_NSSTRING宏包含需要加密的char*字符串 */
    char* cStr = confusion_CSTRING("Super Man");
    NSLog(@"%s",cStr);    
}
  • 步驟2 使用終端cd 到需要加密的工程目錄下 執(zhí)行touch confusion.pytouch decrypt.py 命令,生產(chǎn)加密和解密腳本文件

  • 步驟3 把下面代碼加入解密腳本confusion.py中

#!/usr/bin/env python
# encoding=utf8
# -*- coding: utf-8 -*-
# author by heyujia
# 腳本將會(huì)用于對(duì)指定目錄下的.h .m源碼中的字符串進(jìn)行轉(zhuǎn)換
# 替換所有字符串常量為加密的char數(shù)組,形式((char[]){1, 2, 3, 0})

import importlib
import os
import re
import sys


# replace替換字符串為((char[]){1, 2, 3, 0})的形式,同時(shí)讓每個(gè)字節(jié)與0xAA異或進(jìn)行加密
# 當(dāng)然可以不使用0xAA 使用其他的十六進(jìn)制也行 例如0XBB、0X22、0X11
def replace(match):
    string = match.group(2) + '\x00'
    replaced_string = '((char []) {' + ', '.join(["%i" % ((ord(c) ^ 0xAA) if c != '\0' else 0) for c in list(string)]) + '})'
    return match.group(1) + replaced_string + match.group(3)


# obfuscate方法是修改傳入文件源代碼中用confusion_NSSTRING標(biāo)記的所有字符串
# 使用replace函數(shù)對(duì)字符串進(jìn)行異或轉(zhuǎn)換
def obfuscate(file):
    with open(file, 'r') as f:
        code = f.read()
        f.close()
        code = re.sub(r'(confusion_NSSTRING\(|confusion_CSTRING\()"(.*?)"(\))', replace, code)
        code = re.sub(r'//#define ggh_confusion', '#define ggh_confusion', code)
        with open(file, 'w') as f:
            f.write(code)
            f.close()


# openSrcFile方法是讀取源碼路徑下的所有.h和.m 文件
# 對(duì)每個(gè)文件執(zhí)行obfuscate函數(shù)
def openSrcFile(path):
    print("混淆的路徑為 "+ path)
    # this folder is custom
    for parent,dirnames,filenames in os.walk(path):
        #case 1:
        #        for dirname in dirnames:
        #            print((" parent folder is:" + parent).encode('utf-8'))
        #            print((" dirname is:" + dirname).encode('utf-8'))
        #case 2
        for filename in filenames:
            extendedName = os.path.splitext(os.path.join(parent,filename))
            if (extendedName[1] == '.h' or extendedName[1] == '.m'):
                print("處理源代碼文件: "+ os.path.join(parent,filename))
                obfuscate(os.path.join(parent,filename))


#這里需要修改源碼的路徑為自己工程的文件夾名稱
srcPath = '../daimahunxiao'

if __name__ == '__main__':
    print("本腳本用于對(duì)源代碼中被標(biāo)記的字符串進(jìn)行加密")
    
    if len(srcPath) > 0:
        openSrcFile(srcPath)
    else:
        print("請(qǐng)輸入正確的源代碼路徑")
        sys.exit()

  • 步驟4 把下面的解密代碼放入decrypt.py解密腳本中
#!/usr/bin/env python
# encoding=utf8
# -*- coding: utf-8 -*-
# author by heyujia
# 解密腳本
# 替換所有標(biāo)記過的加密的char數(shù)組為字符串常量,""

import importlib
import os
import re
import sys


# 替換((char[]){1, 2, 3, 0})的形式為字符串,同時(shí)讓每個(gè)數(shù)組值與0xAA異或進(jìn)行解密
def replace(match):
    string = match.group(2)
    decodeConfusion_string = ""
    for numberStr in list(string.split(',')):
        if int(numberStr) != 0:
            decodeConfusion_string = decodeConfusion_string + "%c" % (int(numberStr) ^ 0xAA)
    replaced_string = '\"' + decodeConfusion_string + '\"'

    print("replaced_string = " + replaced_string)
    
    return match.group(1) + replaced_string + match.group(3)


# 修改源代碼,加入字符串加密的函數(shù)
def obfuscate(file):
    with open(file, 'r') as f:
        code = f.read()
        f.close()
        code = re.sub(r'(confusion_NSSTRING\(|confusion_CSTRING\()\(\(char \[\]\) \{(.*?)\}\)(\))', replace, code)
        code = re.sub(r'[/]*#define ggh_confusion', '//#define ggh_confusion', code)
        with open(file, 'w') as f:
            f.write(code)
            f.close()


#讀取源碼路徑下的所有.h和.m 文件
def openSrcFile(path):
    print("解密路徑: "+ path)
    # this folder is custom
    for parent,dirnames,filenames in os.walk(path):
        #case 1:
        #        for dirname in dirnames:
        #            print((" parent folder is:" + parent).encode('utf-8'))
        #            print((" dirname is:" + dirname).encode('utf-8'))
        #case 2
        for filename in filenames:
            extendedName = os.path.splitext(os.path.join(parent,filename))
            #讀取所有.h和.m 的源文件
            if (extendedName[1] == '.h' or extendedName[1] == '.m'):
                print("已解密文件:"+ os.path.join(parent,filename))
                obfuscate(os.path.join(parent,filename))


#源碼路徑
srcPath = '../daimahunxiao'
if __name__ == '__main__':
    print("字符串解混淆腳本,將被標(biāo)記過的char數(shù)組轉(zhuǎn)為字符串,并和0xAA異或。還原代碼")
    if len(srcPath) > 0:
        openSrcFile(srcPath)
    else:
        print("請(qǐng)輸入正確的源代碼路徑!")
        sys.exit()
  • 步驟5 根據(jù)自己的需求修改下腳本里面的代碼 和 文件路徑。

  • 步驟6 把步驟1中的宏heyujia_confusion注釋了,然后執(zhí)行加密腳本,在終端中輸入python confusion.py,
    (1.如果報(bào)錯(cuò),請(qǐng)查看下自己Mac電腦中的python版本,如果是python3就輸入python3 confusion.py.
    (2.如果報(bào)Non-ASCII character '\xe8' in file confusion.py on line 2相關(guān)的錯(cuò),請(qǐng)確定腳本的前面3行是

#!/usr/bin/env python
# encoding=utf8
# -*- coding: utf-8 -*-

必須有這三行代碼,才能在腳本中輸入中文
(3.如果報(bào)IndentationError: unexpected indent,請(qǐng)注意腳本中的每行代碼的換行符和縮進(jìn)格式必須標(biāo)準(zhǔn)

  • 執(zhí)行完步驟6后的結(jié)果
    執(zhí)行完不步驟6后的結(jié)果

    此時(shí)字符串已被加密,運(yùn)行程序會(huì)發(fā)現(xiàn)一切正常
    輸出結(jié)果

加密后匯編界面

加密后匯編界面看不見我們的字符串內(nèi)容了,但是我們用來解密的方法還是暴露在了匯編界面,所以我們后期還需要對(duì)方法名,變量名,類命等做混淆。

  • 步驟7 把步驟1中的宏heyujia_confusion取消注釋,然后執(zhí)行解密腳本,在終端中輸入python decrypt.py
    解密后

    解密后文本又變回了原樣。

這里只是基本的異或轉(zhuǎn)換加密,讓代碼中的字符串變成看不懂的char [],實(shí)際操作中遠(yuǎn)遠(yuǎn)不止這么簡(jiǎn)單
例如:

  • 首先:我們先用加密工具例如:AES.Base64等把需要轉(zhuǎn)換的字符串先加密變成加密字符串
  • 然后:在用異或轉(zhuǎn)換加密的腳本把加密字符串進(jìn)行轉(zhuǎn)換(包括解密用的鑰匙串)
  • 在使用的時(shí)候:先異或解密字符串,然后根據(jù)解密鑰匙串把字符串在轉(zhuǎn)為可用的字符串

ps.還有一種保護(hù)字符串的方法,就是使用NSLocalizedString字符串本地化。


雖然跟著我的步驟你確實(shí)加密成功了,但是你卻無法實(shí)際驗(yàn)證。所以要驗(yàn)證最終的混淆結(jié)果是否達(dá)到效果,你還需要學(xué)習(xí)如何破殼解密IPA如何動(dòng)態(tài)靜態(tài)逆向編程分析工程源碼,大家可以先看看我這篇文章。先掌握逆向分析后在來做代碼混淆,就能驗(yàn)證混淆結(jié)果是否有效

變量、方法名,類名混淆

對(duì)于混淆這一塊,網(wǎng)上真的是千篇一律,基本都是copy的念大嬸的內(nèi)容,沒有一點(diǎn)自己的創(chuàng)新和思考。網(wǎng)上的方法我也用過,但是有缺陷,只能混淆方法名或者說自己固定的內(nèi)容去替換。第一不自動(dòng),對(duì)于大項(xiàng)目而言每個(gè)方法名自己添加,太麻煩。第二變量混淆有問題,因?yàn)橹皇菃渭兊淖址鎿Q,用宏代替。當(dāng)遇到使用_ 下劃線訪問變量時(shí),就會(huì)出現(xiàn)錯(cuò)誤。

對(duì)于變量、方法名,類名的混淆,其實(shí)跟字符串混淆差不多,都是加密混淆,然后解密混淆。不同的是,變量、方法名,類名的混淆目的是為了讓別人反編譯的時(shí)候不知道你的變量、方法,類是具體用來干什么的,不會(huì)想明文那樣一目了然。增加逆向難度?;煜膬?nèi)容不需要想字符串一樣,最后程序運(yùn)行時(shí)還要轉(zhuǎn)成中文正常使用。由于本人對(duì)shell腳本語言也不是非常熟悉,想要按照自己的思路寫一套完整的混淆腳本還不行。所以這部分也是在網(wǎng)上找的,算是目前最實(shí)用最完善的混淆

  • 首先 打開終端cd到需要混淆的工程目錄下,輸入
    touch obConfusion.sh (加密混淆腳本文件)
    touch obDecrypt.sh(解密混淆腳本文件)
    生成2個(gè)腳本文件

  • 然后在工程目錄以外創(chuàng)建一個(gè)文件夾,用于保存加密時(shí)生成的加密文本內(nèi)容,該內(nèi)容會(huì)在解密是用到

  • 最后是在obConfusion.shobDecrypt.sh文件中加入腳本內(nèi)容

下面是加密混淆腳本內(nèi)容

#!/bin/sh
##################################
#  (該腳本是在https://github.com/heqingliang/CodeObfus 上找到的)
#  代碼混淆腳本  heyujia 2018.03.15
#
##################################

#識(shí)別含有多字節(jié)編碼字符時(shí)遇到的解析沖突問題
export LC_CTYPE=C
export LANG=C

#配置項(xiàng):
#項(xiàng)目路徑,會(huì)混淆該路徑下的文件
ProjectPath="/Users/xieyujia/Desktop/ios/學(xué)習(xí)項(xiàng)目/daimahunxiao"
#這個(gè)路徑是混淆成功后,原文本和替換文本解密對(duì)應(yīng)的文件存放路徑(該路徑不能在項(xiàng)目目錄或其子目錄),混淆成功后會(huì)在該路徑下生成一個(gè)解密時(shí)需要的文件,根據(jù)該文件的文本內(nèi)容把混淆后的內(nèi)容更換為原文本內(nèi)容,該文件名的組成由$(date +%Y%m%d)"_"$(date +%H%M)及日期_小時(shí)組成,每分鐘會(huì)不一樣。所以解密的時(shí)候需要每次更換文件路徑
SecretFile="/Users/xieyujia/Desktop/ios/學(xué)習(xí)項(xiàng)目/tihuan"$(date +%Y%m%d)"_"$(date +%H%M)

#第一個(gè)參數(shù)為項(xiàng)目路徑
if [[ $1 ]]
then
if [[ $1 != "_" ]]; then
ProjectPath=$1
fi
fi
#第二個(gè)參數(shù)指定密鑰文件路徑及文件名
if [[ $2 ]]
then
if [[ $2 != "_" ]]; then
SecretFile=$2
fi
fi
##############################################################################

#查找文本中所有要求混淆的屬性\方法\類,只會(huì)替換文本中ob_開頭和_fus結(jié)尾的字符串(區(qū)分大小寫,例如oB_就不會(huì)做混淆),如果注釋內(nèi)容有該類型的字符串,也會(huì)進(jìn)行替換。對(duì)于使用 _下劃線訪問的變量屬性,不會(huì)有影響,一樣會(huì)替換成對(duì)應(yīng)_的混淆內(nèi)容。
resultfiles=`grep 'ob_[A-Za-z0-9_]*_fus' -rl $ProjectPath`
#查找結(jié)果為空則退出
if [[ -z $resultfiles ]]
then
echo "項(xiàng)目沒有需要混淆的代碼"
exit
else
echo "開始混淆代碼..."
echo  > $SecretFile
fi

x=$(awk  '
BEGIN{srand();k=0;}
#隨機(jī)數(shù)生成函數(shù)
function random_int(min, max) {
return int( rand()*(max-min+1) ) + min;
}
#隨機(jī)字符串生成函數(shù)
function random_string(len) {
result="UCS"k;
alpbetnum=split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z", alpbet, ",");
for (i=0; i<len; i++) {
result = result""alpbet[ random_int(1, alpbetnum) ];
}
return result;
}
/ob_[A-Za-z0-9_]*_fus/{
x = $0;
#匹配需要混淆的屬性變量方法
while (match(x, "ob_[A-Za-z0-9_]*_fus") > 0) {
tempstr=substr(x, RSTART, RLENGTH);
#判斷是否有之前已經(jīng)找過的重復(fù)字符串
for ( i = 0; i < k; i++ ){
if (strarr[i] == tempstr){break;}
}
if(i<k){
#重復(fù)字符串,直接刪除。所以不用擔(dān)心混淆內(nèi)容過多,可能會(huì)出現(xiàn)重復(fù)的混淆字符串
x=substr(x, RSTART+RLENGTH);
continue;
}else{
#不是重復(fù)字符串,添加到替換數(shù)組
strarr[k++]=tempstr;
}
randomstr=random_string(20);
printf("%s:%s|", tempstr,randomstr);
#替換隨機(jī)字符串
gsub(tempstr,randomstr, x);
x = substr(x, RSTART+RLENGTH);
}
}' $resultfiles )

#加密對(duì)寫入密鑰文件
echo $x > $SecretFile

recordnum=1
while [[ 1 == 1 ]]; do
record=`echo $x|cut -d "|" -f$recordnum`
if [[ -z $record ]]
then
break
fi
record1=`echo $record|cut -d ":" -f1`
echo "原項(xiàng):"$record1
record2=`echo $record|cut -d ":" -f2`
echo "加密項(xiàng):"$record2
#替換文件夾中所有文件的內(nèi)容(支持正則)
#單引號(hào)不能擴(kuò)展
sed -i '' "s/${record1}/${record2}/g" `grep $record1 -rl $ProjectPath`
echo "第"$recordnum"項(xiàng)混淆代碼處理完畢"
let "recordnum = $recordnum + 1"
done

#查找需要混淆的文件名并替換
filerecordnum=1
while [[ 1 == 1 ]]; do
filerecord=`echo $x|cut -d "|" -f$filerecordnum`
if [[ -z $filerecord ]]
then
break
fi
filerecord1=`echo $filerecord|cut -d ":" -f1`
#echo "原項(xiàng):"$filerecord1
filerecord2=`echo $filerecord|cut -d ":" -f2`
#echo "加密項(xiàng):"$filerecord2
#改文件名

find $ProjectPath -name $filerecord1"*"| awk '
BEGIN{frecord1="'"$filerecord1"'";frecord2="'"$filerecord2"'";finish=1}
{
filestr=$0;
gsub(frecord1,frecord2,filestr);
print "mv " $0 " " filestr";echo 第"finish"個(gè)混淆文件處理完畢";
finish++;
}'|bash
let "filerecordnum = $filerecordnum + 1"
done

下面是解密混淆腳本的內(nèi)容

#!/bin/sh
######################################
#
#  代碼還原腳本  RyoHo 2018.03.15
#
######################################

#識(shí)別含有多字節(jié)編碼字符時(shí)遇到的解析沖突問題
export LC_CTYPE=C
export LANG=C

#配置項(xiàng):
#已經(jīng)混淆的項(xiàng)目路徑
ProjectPath="/Users/xieyujia/Desktop/ios/學(xué)習(xí)項(xiàng)目/daimahunxiao"
#這個(gè)是文件路徑而不是目錄,是混淆的時(shí)候生成的文本文件路徑,每次不一樣。所以每次加密后,解密時(shí)需要更換路徑
SecretFile="/Users/xieyujia/Desktop/ios/學(xué)習(xí)項(xiàng)目/tihuan20180315_1456"
#第一個(gè)參數(shù)為項(xiàng)目路徑
if [[ $1 ]]
then
if [[ $1 != "_" ]]; then
ProjectPath=$1
fi
fi
#第二個(gè)參數(shù)指定密鑰文件路徑及文件名
if [[ $2 ]]
then
if [[ $2 != "_" ]]; then
SecretFile=$2
fi
fi
##############################################################################
#內(nèi)容還原
x=`cat $SecretFile`
recordnum=1
while [[ 1 == 1 ]]; do
record=`echo $x|cut -d "|" -f$recordnum`
if [[ -z $record ]]
then
break
fi
record1=`echo $record|cut -d ":" -f1`
echo "原項(xiàng):"$record1
record2=`echo $record|cut -d ":" -f2`
echo "加密項(xiàng):"$record2
#若項(xiàng)目中加密項(xiàng)與密鑰文件的加密項(xiàng)不符合則退出程序
searchresult=`grep $record2 -rl $ProjectPath`
if [[ -z $searchresult ]]; then
echo "指定的密鑰文件不能還原"
exit
fi
#替換文件夾中所有文件的內(nèi)容(支持正則)
#單引號(hào)不能擴(kuò)展
sed -i '' "s/${record2}/${record1}/g" $searchresult
echo "第"$recordnum"項(xiàng)混淆代碼還原完畢"
let "recordnum = $recordnum + 1"
done
#文件還原
filerecordnum=1
while [[ 1 == 1 ]]; do
filerecord=`echo $x|cut -d "|" -f$filerecordnum`
if [[ -z $filerecord ]]
then
break
fi
filerecord1=`echo $filerecord|cut -d ":" -f1`
#echo "原項(xiàng):"$filerecord1
filerecord2=`echo $filerecord|cut -d ":" -f2`
#echo "加密項(xiàng):"$filerecord2
#改文件名

find $ProjectPath -name $filerecord2"*"| awk '
BEGIN{
frecord1="'"$filerecord1"'";
frecord2="'"$filerecord2"'";
finish=1;
}
{
filestr=$0;
gsub(frecord2,frecord1,filestr);
print "mv " $0 " "filestr ";echo 第"finish"個(gè)混淆文件還原完畢"
finish++;
}'|bash
let "filerecordnum = $filerecordnum + 1"
done

應(yīng)大家需要把腳本源碼地址放出來

建議大家看看腳本內(nèi)容,有利于學(xué)習(xí)理解。該腳本是有針對(duì)性的混淆內(nèi)容,可以自己修改腳本中的正則表達(dá)式來確定混淆的內(nèi)容。腳本中只會(huì)替換文本中ob_開頭和fus結(jié)尾的字符串(區(qū)分大小寫,例如oB就不會(huì)做混淆),如果注釋內(nèi)容有該類型的字符串,也會(huì)進(jìn)行替換。對(duì)于使用 下劃線訪問的變量屬性,不會(huì)有影響,一樣會(huì)替換成對(duì)應(yīng)的混淆內(nèi)容。
提供一個(gè)shell腳本學(xué)習(xí)的網(wǎng)站


代碼邏輯混淆

下一小節(jié)代碼邏輯混淆,目前還在代碼邏輯混淆這塊還在攻破學(xué)習(xí)中,網(wǎng)上大多數(shù)方法不好或者過時(shí)無效。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。