日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

作者:JShaman.com:w2sft

內(nèi)容預(yù)告:

本文將實例講解以下JS代碼混淆加密技術(shù):

方法名轉(zhuǎn)義和轉(zhuǎn)碼、成員表達式轉(zhuǎn)IIFE、函數(shù)標(biāo)準(zhǔn)化、數(shù)值混淆、布爾型常量值混淆、二進制表達式轉(zhuǎn)為調(diào)用表達式、字符串轉(zhuǎn)Unicode、局部變量變形、屏蔽輸出語句,以及:無限斷點、時間差檢測等反調(diào)試方案。

大綱:

理論層面:為什么要對JS代碼進行混淆加密?

技術(shù)層面:用JS編程實現(xiàn)對JS代碼混淆加密。

防逆向措施:檢測與對抗。

專業(yè)的混淆加密:JShaman。

彩蛋:字節(jié)碼加密技術(shù)。

理論層面:為什么要對JS代碼進行混淆加密?

1、問:JS代碼需要考慮安全性嗎?

答:當(dāng)然。

2、問:為什么?

答:JS因為應(yīng)用環(huán)境需要,功能設(shè)計目的等歷史原因,成為了一種代碼公開透明的語言。

前端JS代碼,直接暴露在瀏覽器中,任何訪問者,都可以隨意查看代碼。這就導(dǎo)致代碼可以被分析、復(fù)制、盜用等,進而引發(fā)安全問題,如被利用代碼bug攻擊、揭露功能邏輯、復(fù)制出雷同應(yīng)用等等。

互聯(lián)網(wǎng)早些年,安全場景如上。而發(fā)展到當(dāng)下,JS的應(yīng)用范圍更加廣泛,如NodeJS的興起,使很多后端服務(wù)、產(chǎn)品、項目也應(yīng)用了JS。

在后端的角度,如果項目或產(chǎn)品,提交給第三方時,是否要交出源碼?顯然不妥。

假設(shè)服務(wù)器被入侵,如果部署的后端服務(wù)產(chǎn)品源碼也是JS明文,那將導(dǎo)致更嚴重的安全問題。

更多的應(yīng)用領(lǐng)域,如小程序開發(fā)、H5應(yīng)用,含ThreeJS引擎類游戲,等,都廣泛應(yīng)用了JS。

在所有這些場景中,都不應(yīng)該忽視JS代碼的安全問題,都應(yīng)該且需要對JS代碼進行保護。

3、問:如何讓JS代碼變的安全?

答:對JS代碼進行保護:混淆&加密,使代碼不可讀。即:它人依然可以看到代碼,但看到的是加密的代碼、無法理解代碼,更無法修改。

深入并精準(zhǔn)的說:通過混淆加密,使代碼變的難以閱讀和理解。可能有人說,混淆后機器能執(zhí)行,人就能理解,只是需要的時間長短問題。這種極端的說法,從理論上來說沒錯,如果可以投入足夠長的時間,程序員甚至可以直接用0101寫代碼。而從實際角度而言,一段代碼如果保護后分析需要的時長,超過開發(fā)需要的時長,保護的目的就達到了,就會勸退99.9999%對它有想法的正常人類。

理論已探討完畢,接下來步入正題,探索如何對JS代碼進行混淆加密,可不僅僅是應(yīng)用層面,而是全面掌握:會用、知其然,知其所在然,還要動手編碼,實現(xiàn):用JS對JS代碼混淆加密。

接下來的內(nèi)容,將在NodeJS環(huán)境中,使用JS編程,實現(xiàn)對JS代碼的混淆加密。

技術(shù)層面:用JS編程實現(xiàn)對JS代碼混淆加密。

技術(shù)理論:如何實現(xiàn)?

確定實現(xiàn)方案之前,首先需要排除幾種不可用方案:

  • Eval思路不可用:可以被下斷點調(diào)試或API HOOK,而輕松還原出原始代碼。
  • 可逆加密方式不可用:加密方式可逆,則必然有解密函數(shù),只需定位于解密出口,即可得到原始代碼。
  • 異步代碼獲取并執(zhí)行不可用:同樣可被調(diào)試或hook,得到代碼。
  • 可取的方式:代碼混淆+數(shù)據(jù)加密。

混淆原理:非replace或regexp方式字符串替換,而是對JS源碼進行重編譯。從源碼,進行詞法分析、語法分析、得到AST(抽象語法樹),此處是重點,得到AST后,在AST中執(zhí)行關(guān)鍵混淆加密操作,如:字符算陣列化、字符加密、平展控制流、僵尸代碼值入、反調(diào)試埋雷、花指令插入等,最后,再將AST重建為JS代碼。這樣就得到了一份被更改的面目全非的安全JS代碼:不可讀、不可理解、不可修改、不可還原。

編程現(xiàn)實:用JS對JS代碼混淆加密。

由以上的理論可知,重點是混淆加密,而入口點及整體流程框架是AST操作。

JS代碼&AST。

在JS引擎之下,代碼編譯執(zhí)行大體流程是:

JS代碼→AST(抽象語法樹)→ByteCode(字節(jié)碼)→機器碼→解釋器→執(zhí)行。

AST設(shè)計之初并不是用于對JS代碼混淆加密,但AST卻很適合這個事情。

基于AST的JS代碼混淆加密大體流程:

JS代碼→AST→(基于AST的混淆加密)→JS代碼。

題外話:能在ByteCode階段進行加密嗎?某些情況下可以,比如NodeJS環(huán)境中的JS代碼,可以編譯為ByteCode。但在前端運行的JS代碼,且于DOM有交互的則不理想,小總結(jié)而言,有將JS代碼進行VM式的加密方法,但通用性較差,使用起來復(fù)雜。因為這些弊端,因此,不是普遍性的JS代碼保護方案。

注:在本結(jié)尾,會有一個彩蛋內(nèi)容,實例介紹NodeJS字節(jié)碼生成及運行。

圖1,NodeJS字節(jié)碼效果:

JS代碼安全之路:用JS對JS代碼混淆加密

 

回到正題,JS代碼如何轉(zhuǎn)化為AST?

其實,沒有想象中那么復(fù)雜。得益于NodeJS成熟的生態(tài),已經(jīng)有多個已實現(xiàn)模塊可以完成這一操作。比較流行的如:esprima、babel,都可以實現(xiàn)對JS代碼進行詞法分析、語法分析、生成AST、AST操作、從AST再生成JS代碼。

用esprima進行JS代碼混淆加密。程序框架。

圖2、esprima框架demo:

JS代碼安全之路:用JS對JS代碼混淆加密

 

如圖2所示,使用esprima進行JS代碼保護的原始功能框架。

代碼介紹:

Esprima實現(xiàn)將JS代碼轉(zhuǎn)化為AST;

estraverse對AST節(jié)點進行遍歷,混淆加密的邏輯操作都將在此環(huán)節(jié)實現(xiàn);

escodegen則是將操作后的AST轉(zhuǎn)為JS代碼輸出。

此demo代碼未對AST進行任何處理,所以圖中右側(cè)的執(zhí)行結(jié)果中可以看到,輸出的JS代碼與最初代碼完全一致。

AST是這樣子的。

前面已經(jīng)對AST進行了說明,AST具體是什么樣?

一個方便的辦法,是使用astexplorer.net,可以對輸入的代碼的AST即時同步顯示:

圖3、const a=1的AST:

JS代碼安全之路:用JS對JS代碼混淆加密

 

Demo中使用的一行JS語句:“const a=1”,其AST即如圖中所顯示。

AST是一個JSON結(jié)構(gòu)。

Program表示程序,子節(jié)點body中,是變量定義kind是“const”,字面量是“a”,值是“1”。

看似雜亂,但很規(guī)整,細看便不難理解。

demo程序里,在節(jié)點操作處可以用console輸出AST,與astexplorer輸出一至,不過前者更方便些。

圖4、在程序中輸出AST:

JS代碼安全之路:用JS對JS代碼混淆加密

 

借助Esprima修改AST實例:改“==”為“===”。

圖5:

JS代碼安全之路:用JS對JS代碼混淆加密

 

代碼如上圖,這是一個很簡單的示例。

程序中,estraverse對示例代碼結(jié)點進行處理,當(dāng)匹配到“==”時,改為“===”。

為了明確修改節(jié)點細節(jié),再對前后代碼進行分析。由圖6、圖7看到,差異僅在節(jié)點中的operator。

圖6、代碼中使用“==”:

JS代碼安全之路:用JS對JS代碼混淆加密

 

圖7、代碼中使用“===”:

JS代碼安全之路:用JS對JS代碼混淆加密

 

借助Esprima修改AST實例:把parseInt改為標(biāo)準(zhǔn)語法。

parseInt方法,有兩個參數(shù),參數(shù)一是要轉(zhuǎn)化的值,參數(shù)二是可選擇項,是要轉(zhuǎn)化的進制類型。

圖8:

JS代碼安全之路:用JS對JS代碼混淆加密

 

通過astexplorer,先了解parseInt的AST,未使用參數(shù)二時,AST如下:

圖9:

JS代碼安全之路:用JS對JS代碼混淆加密

 

如果有第二參數(shù),則AST如下:

圖10:

JS代碼安全之路:用JS對JS代碼混淆加密

 

那么,要將parseInt轉(zhuǎn)為標(biāo)準(zhǔn)形式即是要給只有一個參數(shù)的調(diào)用增加第二參數(shù)。

代碼及執(zhí)行結(jié)果如下:

圖11:

JS代碼安全之路:用JS對JS代碼混淆加密

 

因為初入手的原因,以上描述較為細致,后續(xù)將簡化。

方法名轉(zhuǎn)義和轉(zhuǎn)碼。

如:console.log轉(zhuǎn)為console[log]形式。

通過在aspexplorer中比較可知,造成語句形式差異的原因是CallExpression成員中computed屬性值的不同。

圖12:

JS代碼安全之路:用JS對JS代碼混淆加密

 

那么,只需修改節(jié)對應(yīng)節(jié)點的computed屬性值即可:

圖13:

JS代碼安全之路:用JS對JS代碼混淆加密

 

而修改的條件,則是判斷AST節(jié)點是CallExpression。上面的例子中,也是使用相似的條件判斷方法,找出要修改內(nèi)容相對應(yīng)的AST節(jié)點。

再進一步,將方法名轉(zhuǎn)為十六進制字符,console[log]會成為:console['x6cx6fx67'],以此進一步降低代碼可讀性。

圖14、增加字符串轉(zhuǎn)16進制操作:

JS代碼安全之路:用JS對JS代碼混淆加密

 

例程代碼輸出為:

圖15:

JS代碼安全之路:用JS對JS代碼混淆加密

 

運行混淆后的代碼:

圖16:

JS代碼安全之路:用JS對JS代碼混淆加密

 

從簡單的例程,可以初步學(xué)習(xí)到對AST的操作方法。

接下來,實現(xiàn)一個有點難度的功能。

成員表達式轉(zhuǎn)為IIFE

成員表達式通常指調(diào)用對象的成員,例如 console 對象的 log 成員。

IIFE,全稱為:Immediately Invoked Function Expression,在JAVAScript編程中,是指:立即調(diào)用函數(shù)表達式。

為了方便理解,先展示此功能實現(xiàn)后的效果:

圖17:

JS代碼安全之路:用JS對JS代碼混淆加密

 

如上圖中,console的log、warn、error方法,以及字符串的toUperCase()方法,在保護后都會成為匿名自執(zhí)行的函數(shù),且方法名都以數(shù)組化的形式被另外存放,代碼相比之前混亂了許多。

圖18、IIFE代碼執(zhí)行效果:

JS代碼安全之路:用JS對JS代碼混淆加密

 

實現(xiàn)方法如下:

主架構(gòu)與之前略有差異,traverse方法改為replace,enter事件改為leave事件,如下圖:

圖19:

JS代碼安全之路:用JS對JS代碼混淆加密

 

對變量定義結(jié)點,如console.log輸出的信息,以及成員函數(shù),如console的log方法進行操作。

圖20、改寫字符串定義、成員函數(shù)調(diào)用:

JS代碼安全之路:用JS對JS代碼混淆加密

 

Add_string函數(shù)把字符串信息、方法名,都寫入到一個新的字符串?dāng)?shù)組,并且把方法改為IIFE。

字符串?dāng)?shù)組建立、方法改為IIFE的具體實現(xiàn)如下圖:

圖21:

JS代碼安全之路:用JS對JS代碼混淆加密

 

然后,把新增的數(shù)組加入到AST中,最重再重建代碼:

圖22:

JS代碼安全之路:用JS對JS代碼混淆加密

 

這樣就完成了本例功能。

注:本例僅供功能演示,尚有不嚴謹?shù)倪壿嫞热绯蓡T方法IIFE化之前,除應(yīng)該判斷node.type為MemberExpression,還應(yīng)排除節(jié)點computed為true的情況,否則代碼執(zhí)行會發(fā)生錯誤。

正如前文中所述,能對AST進行操作的模塊不止esprima,babel也是個很好的選擇。

接下來的例子,將使用babel來完成。

Babel的使用方式與esprima極為相似,其代碼框架如下:

圖23:

JS代碼安全之路:用JS對JS代碼混淆加密

 

同樣是:JS代碼→AST→節(jié)點處理→JS代碼。

用Babel修改AST實例:去除代碼中的console.log輸出語句。

代碼如下圖所示:

圖24、用Babel在AST中去除console.log節(jié)點:

JS代碼安全之路:用JS對JS代碼混淆加密

 

匹配AST中的成員操作節(jié)點,且滿足條件callee的對像名為console,屬性方法名為log,如檢測掉,則remove該節(jié)點。

運行效果如下圖所示,測試代碼中含有console.log,修改后輸出中已經(jīng)被去除。

圖25:

JS代碼安全之路:用JS對JS代碼混淆加密

 

嚴謹?shù)目紤]的話,需要注意對象掛載的識別,如global.console.log,此時remove則會剩下global,將導(dǎo)致語法錯誤,因此還應(yīng)該判斷父節(jié)點類型來排除這種情況。

指定局部變量變形

圖26、對min、number兩個局部變量變形:

JS代碼安全之路:用JS對JS代碼混淆加密

 

相當(dāng)于是可設(shè)定、可配置的對某些變量進行變形。

反向思考,也可以排除對某些變量的處理,等同于白名單,類似于JShaman平臺中的“保留字”功能。

刪除代碼中的空行。

圖27:

JS代碼安全之路:用JS對JS代碼混淆加密

 

EmptyStatement表示空語句AST節(jié)點。

字符串轉(zhuǎn)Unicode。

圖28:

JS代碼安全之路:用JS對JS代碼混淆加密

 

代碼及執(zhí)行結(jié)果如上圖,原理為:判斷節(jié)字符串字面量節(jié)點是否為Unicode格式,如不是則轉(zhuǎn)為Unicode。

在這幾個例子中,可看到與esprima的差異,esprima使用的是enter、leave方法,Babel中是直接對要處理的節(jié)點類型操作,如上圖中的StringLiteral。

更條理化的寫法,上面的代碼可以修改如下,這個方法被稱為Babel-plugin(插件):

圖29:

JS代碼安全之路:用JS對JS代碼混淆加密

 

二進制表達式轉(zhuǎn)為調(diào)用表達式

即BinaryExpression節(jié)點轉(zhuǎn)為CallExpression。

先看效果:

圖30,左側(cè)為二進制表達式,右側(cè)為調(diào)用表達式:

JS代碼安全之路:用JS對JS代碼混淆加密

 

二進制表達式AST形式:

JS代碼安全之路:用JS對JS代碼混淆加密

 

實現(xiàn)代碼:

圖31:

JS代碼安全之路:用JS對JS代碼混淆加密

 

調(diào)用表達式AST形式:

圖32:

JS代碼安全之路:用JS對JS代碼混淆加密

 

代碼中的這部分,即是將二進制表達式轉(zhuǎn)化為調(diào)用表達式:

圖33:

JS代碼安全之路:用JS對JS代碼混淆加密

 

布爾型常量值混淆

代碼及效果如下圖:

圖34:

JS代碼安全之路:用JS對JS代碼混淆加密

 

數(shù)值混淆

代碼及效果如下圖:

圖35:

JS代碼安全之路:用JS對JS代碼混淆加密

 

JS代碼混淆加密,雖不至博大精深,但也屬于高段位技術(shù)。

在此分享部分淺顯方案,以展現(xiàn)其實用效果,用于說明混淆加密手段對于JS代碼加固的有效性。此外,還有更多高端的防護手段,如JShaman應(yīng)用的:平展控制流、時間限制、域名鎖定、僵尸代碼植入等。

圖36、JShaman的JS代碼保護配置功能:

JS代碼安全之路:用JS對JS代碼混淆加密

 

防逆向措施:檢測與對抗。

對JS代碼進行混淆加密之后,代碼安全度得到相當(dāng)?shù)募訌姡€能更進一步,為了防止不法者進行逆向分析、破解,可在代碼中加入防破解對抗功能。這也是被JShaman應(yīng)用的方案。

  • 無限斷點。

JS當(dāng)中有一個debugger指令,當(dāng)處于調(diào)試工具中時,如在瀏覽器中,會形成斷點,使調(diào)試中斷,利用此特性,在程序中加入無限的debugger,可使代碼無法被調(diào)試。

圖37、每100毫秒一個斷點:

JS代碼安全之路:用JS對JS代碼混淆加密

 

瀏覽器中執(zhí)行效果如下,當(dāng)打開“調(diào)試器”時,程序會不停的中斷,導(dǎo)致無法跟蹤代碼:

圖38:

JS代碼安全之路:用JS對JS代碼混淆加密

 

時間差檢測。

代碼及執(zhí)行效果如下圖所示:

圖39:

JS代碼安全之路:用JS對JS代碼混淆加密

 

檢測原理是:

在代碼中加入console.log輸出和console.clear語句,未在調(diào)試工具中時,這兩句代碼執(zhí)行是不需渲染顯示的,執(zhí)行耗時短,但假如在瀏覽器中打開了開發(fā)者工具,則會因為顯示輸出并清除的操作而消耗較多時間,這會被程序察覺出耗時異常,從而檢測出是在被調(diào)試。

專業(yè)的混淆加密:JShaman

本文講述了部分JS代碼混淆加密技術(shù)及實現(xiàn),更多更專業(yè)的防護方案未有盡述,這里再展示一段經(jīng)JShaman保護的代碼,領(lǐng)略專業(yè)級的JS代碼安全。

圖40、測試代碼準(zhǔn)備進行混淆加密:

JS代碼安全之路:用JS對JS代碼混淆加密

 

圖41、保護選項設(shè)置:

JS代碼安全之路:用JS對JS代碼混淆加密

 

圖42、混淆加密后的JS代碼:

JS代碼安全之路:用JS對JS代碼混淆加密

 

彩蛋:字節(jié)碼加密技術(shù)。

提示:JS字節(jié)碼(ByteCode)加密技術(shù),理論可行,但通用性較差,在此僅做技術(shù)介紹,不推薦做為項目或產(chǎn)品正式使用方案。

  • 字節(jié)碼生成

在NodeJS中將JS代碼生成字節(jié)碼,方法很簡單,需借助google的V8引擎,V8引擎內(nèi)置有JS虛擬機。通過v8虛擬機,將JS代碼編譯為字節(jié)碼。全程僅需十幾行代碼,如下圖:

圖43:

JS代碼安全之路:用JS對JS代碼混淆加密

 

關(guān)鍵處是cachedData,即字節(jié)碼。

  • 運行字節(jié)碼

V8虛擬機是能夠識別和直接運行該字節(jié)碼的。

代碼如下,如同創(chuàng)建字節(jié)碼一樣簡單。

圖44:

JS代碼安全之路:用JS對JS代碼混淆加密

 

生成的字節(jié)碼是非文本形式的,如強行打開,內(nèi)容如下圖:

圖45、字節(jié)碼文件內(nèi)容:

JS代碼安全之路:用JS對JS代碼混淆加密

 

JS字節(jié)碼生成并運行效果如下:

圖46:

JS代碼安全之路:用JS對JS代碼混淆加密

 

代碼改變世界,獻給廣大JS開發(fā)者。全文結(jié)束,感謝閱讀。

分享到:
標(biāo)簽:JS
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定