版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
軟件安全Part章節(jié)10軟件防護(hù)技術(shù)代碼混淆(Obfuscatedcode)亦稱花指令,是將計(jì)算機(jī)程序的代碼,轉(zhuǎn)換成一種功能上等價(jià),但是難于閱讀和理解的形式的行為。將代碼中的各種元素,如變量,函數(shù),類的名字改寫成無(wú)意義的名字。比如改寫成單個(gè)字母,或是簡(jiǎn)短的無(wú)意義字母組合,甚至改寫成“__”這樣的符號(hào)重寫代碼中的部分邏輯,將其變成功能上等價(jià),但是更難理解的形式。比如將for循環(huán)改寫成while循環(huán),將循環(huán)改寫成遞歸,精簡(jiǎn)中間變量,等等。打亂代碼的格式。比如刪除空格,將多行代碼擠到一行中,或者將一行代碼斷成多行等等。10.1.1代碼混淆10.1防逆向分析軟件水印根據(jù)水印被加載的時(shí)刻不同,可以分為靜態(tài)軟件水印和動(dòng)態(tài)軟件水印。10.1.2軟件水印10.1防逆向分析靜態(tài)水印嵌入在程序的源代碼或數(shù)據(jù)中,不受程序是否運(yùn)行的影響。靜態(tài)水印又可以進(jìn)一步分為靜態(tài)數(shù)據(jù)水印和靜態(tài)代碼水印。動(dòng)態(tài)水印隱藏在程序的執(zhí)行狀態(tài)中,需要輸入特定的序列才能出發(fā)水印的生成。區(qū)別于靜態(tài)水印,動(dòng)態(tài)水印則保存在程序的執(zhí)行狀態(tài)中,而不是程序源代碼本身。動(dòng)態(tài)水印主要有3類:EasterEgg水印數(shù)據(jù)結(jié)構(gòu)水印執(zhí)行狀態(tài)水印10.1.3原生代碼保護(hù)10.1防逆向分析10.1.4資源保護(hù)--PC端10.1防逆向分析這里的資源是指存儲(chǔ)在PE程序文件中的非程序自身指令的數(shù)據(jù),如字串表、圖標(biāo)、圖片、窗口資源等。在PE程序中,它們被集中存儲(chǔ)在一個(gè)數(shù)據(jù)區(qū)域內(nèi),而這個(gè)區(qū)域是PE程序中非常重要的區(qū)域,因此保護(hù)系統(tǒng)自然不會(huì)放過(guò)對(duì)資源的處理。但是,受限于資源區(qū)段的特殊性,且保護(hù)系統(tǒng)很難準(zhǔn)確識(shí)別資源中的具體數(shù)據(jù)格式和用途,所以,除了幾種特定類型的資源外,保護(hù)系統(tǒng)為了實(shí)現(xiàn)較好的兼容性,只能將其他資源都作為純二進(jìn)制數(shù)據(jù)來(lái)對(duì)待。因此,保護(hù)系統(tǒng)無(wú)法將具體資源變形或者加密,只能整體移動(dòng)其位置,或者對(duì)其實(shí)行整體算術(shù)加密,這限制了資源保護(hù)的強(qiáng)度。大部分的保護(hù)系統(tǒng)對(duì)于資源的加密都停留在壓縮移位上,當(dāng)程序運(yùn)行后就將資源解壓或解密,放到一個(gè)內(nèi)存區(qū)域,并修正內(nèi)存中的PE文件頭。10.1.4資源保護(hù)--PC端10.1防逆向分析有些保護(hù)系統(tǒng)會(huì)HOOK各種與資源相關(guān)的函數(shù),然后在調(diào)用這些函數(shù)的時(shí)候動(dòng)態(tài)解密資源。以下是VMProtect保護(hù)系統(tǒng)的例子打開(kāi)資源保護(hù)加密程序,直接?xùn)丝闯绦蜻\(yùn)行時(shí)的一些與資源相關(guān)的系統(tǒng)函數(shù)入口,如下圖所示。10.1.4資源保護(hù)--移動(dòng)端10.1防逆向分析資源文件保護(hù)的舉例首先使用反編譯工具apktool對(duì)某應(yīng)用進(jìn)行反編譯,使用命令為:“apktoold-sxxx.apk”,反編譯成功之后,得到的資源文件的目錄如圖10.1.4資源保護(hù)--移動(dòng)端10.1防逆向分析這個(gè)應(yīng)用的資源文件有:color、layout、menu等,可以使用xml編輯工具對(duì)這些文件夾下的資源文件進(jìn)行修改。例如圖中紅色橫線所標(biāo)示的payment_list_item.xml文件,從該文件的名稱可知該文件跟支付信息相關(guān),可對(duì)其進(jìn)行修改,就能往原有Apk的支付信息中添加一些自己的東西,最后通過(guò)apktool進(jìn)行回編譯就能創(chuàng)建一個(gè)經(jīng)過(guò)修改過(guò)的APK應(yīng)用。通過(guò)這個(gè)例子可以看出資源安全的重要性,那如何做到資源安全呢?資源文件的規(guī)范性命名使得攻擊人員輕易猜測(cè)這些文件的作用,但是若不規(guī)范命名,又給開(kāi)發(fā)過(guò)程增添額外的負(fù)擔(dān)。而且,對(duì)于加固系統(tǒng)來(lái)說(shuō),是無(wú)法涉及到應(yīng)用程序的原始編譯過(guò)程的。10.1.4資源保護(hù)--移動(dòng)端10.1防逆向分析Android應(yīng)用查找資源的流程Android應(yīng)用程序?yàn)榱诉m配不同的手機(jī)之間屏幕的差異性,以及適配不同的國(guó)家、地區(qū)和語(yǔ)言等,包含了許多不同的資源文件。應(yīng)用程序運(yùn)行時(shí)Android系統(tǒng)會(huì)自動(dòng)根據(jù)設(shè)備的配置信息進(jìn)行適配,因此給定一個(gè)相同的資源ID,在不同的設(shè)備配置之下,查找到的可能是不同的資源。在Android系統(tǒng)中,Resources類可以根據(jù)ID來(lái)查找資源,AssetManager類根據(jù)文件名來(lái)查找資源。事實(shí)上,如果一個(gè)資源ID對(duì)應(yīng)的是一個(gè)文件,那么Resources類是先根據(jù)ID來(lái)找到資源文件名稱,然后再將該文件名稱交給AssetManager類來(lái)打開(kāi)對(duì)應(yīng)的文件的。基本流程如右圖10.1.4資源保護(hù)--移動(dòng)端10.1防逆向分析Resources類是通過(guò)resources.arsc把資源的ID轉(zhuǎn)化成資源文件的名稱,然后交由AssetManager來(lái)加載的。resources.arsc這個(gè)文件是存放在APK包中的,他是由編譯工具在打包過(guò)程中生成的,它本身是一個(gè)資源的索引表,里面維護(hù)著資源ID、Name、Path或者Value的對(duì)應(yīng)關(guān)系A(chǔ)ssetManager通過(guò)這個(gè)索引表,就可以通過(guò)資源的ID找到這個(gè)資源對(duì)應(yīng)的文件或者數(shù)據(jù)因此通過(guò)修改resources.arsc文件和res目錄,可以達(dá)到資源名稱混淆的效果。10.1.5加殼--PC端--殼的概念10.1防逆向分析計(jì)算機(jī)軟件里有一段專門負(fù)責(zé)保護(hù)軟件不被非法修改或反編譯的程序。它們附加在原程序上通過(guò)Windows加載器載入內(nèi)存后,先于原始程序執(zhí)行,得到控制權(quán),執(zhí)行過(guò)程中對(duì)原始程序進(jìn)行解密、還原,還原完成后再把控制權(quán)交還給原始程序,執(zhí)行原來(lái)的代碼的部分。這樣的程序稱為“殼”。10.1.5加殼--PC端--殼的概念10.1防逆向分析加殼軟件一般都有良好的操作界面,使用也比較簡(jiǎn)單。除了一些商業(yè)殼,還有一些個(gè)人開(kāi)發(fā)的殼,種類較多。殼對(duì)軟件提供了良好保護(hù)的同時(shí),也帶來(lái)了兼容性的問(wèn)題,選擇一款殼保護(hù)軟件后,要在不同硬件和系統(tǒng)上多測(cè)試。由于殼能保護(hù)自身代碼,因此許多木馬或病毒都喜歡用殼來(lái)保護(hù)和隱藏自己。對(duì)于一些流行的殼,殺毒引擎能對(duì)目標(biāo)軟件脫殼,再進(jìn)行病毒檢査。大多數(shù)私人殼,殺毒軟件不會(huì)專門開(kāi)發(fā)解壓引擎,而是直接把殼當(dāng)成木馬或病毒處理有加殼就一定會(huì)有脫殼。一般的脫殼軟件多是專門針對(duì)某加殼軟件而編的,雖然針對(duì)性強(qiáng)、效果好,但收集麻煩。因此掌握手動(dòng)脫殼技術(shù)十分必要。10.1.5加殼--PC端--壓縮引擎10.1防逆向分析一些加殼軟件能將文件壓縮,大多數(shù)情況下,壓縮算法是調(diào)用現(xiàn)成的壓縮引擎。目前壓縮引擎種類比較多,不同的壓縮引擎有不同特點(diǎn),如一些對(duì)圖像壓縮效果好,一些對(duì)數(shù)據(jù)壓縮效果好。加殼軟件選擇壓縮引擎特點(diǎn):在保證壓縮比的條件下,壓縮速度慢些關(guān)系不大,但解壓速度要快,這樣加了殼的EXE文件運(yùn)行起來(lái)速度才不會(huì)受太大的影響。10.1.5加殼--PC端--壓縮殼10.1防逆向分析不同的外殼所側(cè)重的方面也不一樣,有的側(cè)重于壓縮,有的則側(cè)重于加密。壓縮殼的特點(diǎn)就是減小軟件體積大小,加密保護(hù)不是其重點(diǎn)。目前兼容性和穩(wěn)定性比較好的壓縮殼有UPX、ASPack、PECompact等。10.1.5加殼--PC端--壓縮殼--UPX10.1防逆向分析UPX是一個(gè)以命令行方式操作的可執(zhí)行文件免費(fèi)壓縮程序,兼容性和穩(wěn)定性很好。UPX包含DOS、Linux和Windows等版本,并且開(kāi)源。UPX的命令格式為:upx[-123456789dlthVL][-qvfk][-ofile]file..UPX早期版本壓縮引擎是自己實(shí)現(xiàn)的,3.x版本也支持LZMA第三方壓縮引擎。UPX除了對(duì)目標(biāo)程序進(jìn)行壓縮外,也可解壓縮。UPX的開(kāi)發(fā)近乎完美,它不包含任何反調(diào)試或保護(hù)策略。另外,UPX保護(hù)工具UPXPR、UPX-Scrambler等可修改UPX加殼標(biāo)志,使UPX自解壓縮功能失效。10.1.5加殼--PC端--壓縮殼--ASPack10.1防逆向分析SPack是一款Win32可執(zhí)行文件壓縮軟件,可壓縮Win32位可執(zhí)行文件EXE、DLL、OCX,具有很好的兼容性和穩(wěn)定性。官方主頁(yè):程序界面如下圖:10.1.5加殼--PC端--加密殼10.1防逆向分析加密殼種類比較多,不同的殼側(cè)重點(diǎn)不同,一些殼單純保護(hù)程序,另一些殼還提供額外的功能,如提供注冊(cè)機(jī)制、使用次數(shù)、時(shí)間限制等。加密殼還有一個(gè)特點(diǎn),越是有名的加密売,研究的人也越多,其被脫殼或破解的可能性也越大,加密殼在強(qiáng)度與兼容性上做得好的并不多,以下是幾款常見(jiàn)的加密殼。10.1.5加殼--PC端--加密殼--ASProtect10.1防逆向分析SProtect是一款非常強(qiáng)大的Win32位保護(hù)工具,這款殼開(kāi)創(chuàng)了殼的新時(shí)代。它擁有壓縮、加密、反跟蹤代碼、CRC校驗(yàn)和花指令等保護(hù)措施。它使用Blowfish、Twofish、TEA等強(qiáng)勁的加密算法,還有RSA1024作為注冊(cè)密鑰生成器。它還通過(guò)API鉤子與加殼的程序進(jìn)行通信,并且ASProtect為軟件幵發(fā)人員提供SDK,實(shí)現(xiàn)加密程序內(nèi)外結(jié)。SDK支持VC、VB、Delphi等。10.1.5加殼--PC端--加密殼--ASProtect10.1防逆向分析ASProtect加殼過(guò)程中也可掛接用戶自己寫的DLL文件,方法是在“ExternalOptions”選項(xiàng)中加上目標(biāo)DLL即可。這樣,用戶可以在DLL中加入自己的反跟蹤代碼,以提高軟件的反跟蹤能力。10.1.5加殼--PC端--加密殼--Armadillo10.1防逆向分析Armadillo也稱穿山甲,是一款應(yīng)用面較廣的商業(yè)保護(hù)軟件(其界面如下)。Armadillo有如下保護(hù)功能:Nanomites、ImportTableElimination、StrategicCodeSplicing、Memory-PatchingProtections等。10.1.5加殼--PC端--加密殼--EXECryptor10.1防逆向分析EXECryptor是一款商業(yè)保護(hù)軟件(其主界面如下所示)其可以為目標(biāo)軟件加上注冊(cè)機(jī)制、時(shí)間限制、使用次數(shù)等附加功能。這款殼的特點(diǎn)是Anti-Debug比較強(qiáng)大,同時(shí)做得比較隱蔽,另外就是采用了虛擬機(jī)保護(hù)一些關(guān)鍵代碼。要使這款殼有強(qiáng)大的保護(hù),必須合理使用SDK功能,將關(guān)鍵的功能代碼用虛擬機(jī)保護(hù)起來(lái)。10.1.5加殼--PC端--加密殼--Themida10.1防逆向分析Themida是Oreans的一款商業(yè)保護(hù)軟件(其主界面如下所示)Themida最大特點(diǎn)就是其虛擬機(jī)保護(hù)技術(shù),因此在程序中擅用SDK,將關(guān)鍵的代碼讓Themida用虛擬機(jī)保護(hù)起來(lái)。Themida最大的缺點(diǎn)就是生成的軟件比較大。10.1.5加殼--移動(dòng)端10.1防逆向分析Android軟件加殼實(shí)現(xiàn)對(duì)核心應(yīng)用程序進(jìn)行加固和保護(hù),加大應(yīng)用程序被逆向破解的難度.加殼的Android程序運(yùn)行時(shí),首先運(yùn)行“殼”程序,“殼”程序解密并釋放核心程序?!皻ぁ背绦蛑袑?shí)現(xiàn)了對(duì)核心程序的加密和保護(hù)以防止被惡意分析和破解。10.1.5加殼--移動(dòng)端10.1防逆向分析以Android應(yīng)用運(yùn)行原理的分層結(jié)構(gòu)分析加固應(yīng)用程序,其基本的構(gòu)架具體如下圖所示:10.1.5加殼--移動(dòng)端10.1防逆向分析Android應(yīng)用程序運(yùn)行時(shí)在系統(tǒng)中以進(jìn)程形式體現(xiàn),進(jìn)程創(chuàng)建完畢后從外存將dex文件映射到進(jìn)程的內(nèi)存空間中,完成一系列的初始化后,由應(yīng)用框架層抽象應(yīng)用的主要運(yùn)行邏輯。在DVM、支持庫(kù)中對(duì)應(yīng)用框架層進(jìn)行具體實(shí)現(xiàn),從而完成程序的運(yùn)行。而加固應(yīng)用利用Android程序運(yùn)行原理,在殼進(jìn)程啟動(dòng)后,主動(dòng)解密和加載被保護(hù)程序字節(jié)碼,利用應(yīng)用框架層中完成進(jìn)程的生命周期;在運(yùn)行時(shí)層實(shí)現(xiàn)了具體的安全加固技術(shù),增加自我保護(hù)技術(shù)等,以實(shí)現(xiàn)對(duì)應(yīng)用程序的加固。10.1.5加殼--移動(dòng)端--簡(jiǎn)單的加殼方案10.1防逆向分析加殼是在二進(jìn)制的程序中植入一段代碼,在運(yùn)行的時(shí)候優(yōu)先取得程序的控制權(quán),做一些額外的工作。大多數(shù)病毒就是基于此原理。文件加殼的過(guò)程如下:10.1.5加殼--移動(dòng)端--加殼作用10.1防逆向分析加殼的程序可以有效阻止對(duì)程序的反匯編分析,以達(dá)到它不可告人的目的。這種技術(shù)也常用來(lái)保護(hù)軟件版權(quán),防止被軟件破解。10.1.5加殼--移動(dòng)端--Android
Dex文件加殼原理10.1防逆向分析PC平臺(tái)現(xiàn)在已存在大量的標(biāo)準(zhǔn)的加殼和解殼工具,但是Android作為新興平臺(tái)還未出現(xiàn)APK加殼工具。AndroidDex文件大量使用引用給加殼帶來(lái)了一定的難度,但是從理論上講,AndroidAPK加殼也是可行的。這個(gè)過(guò)程中,牽扯到以下三個(gè)角色:加殼程序:加密源程序?yàn)榻鈿?shù)據(jù)、組裝解殼程序和解殼數(shù)據(jù)解殼程序:解密解殼數(shù)據(jù),并運(yùn)行時(shí)通過(guò)DexClassLoader動(dòng)態(tài)加載源程序:需要加殼處理的被保護(hù)代碼10.1.5加殼--移動(dòng)端--Android
Dex文件加殼原理10.1防逆向分析根據(jù)解殼數(shù)據(jù)在解殼程序DEX文件中的不同分布,有兩種AndroidDex加殼的實(shí)現(xiàn)方案:(一)解殼數(shù)據(jù)位于解殼程序文件尾部該種方式簡(jiǎn)單實(shí)用,合并后的DEX文件結(jié)構(gòu)如圖:10.1.5加殼--移動(dòng)端--Android
Dex文件加殼原理10.1防逆向分析加殼程序工作流程●加密源程序APK文件為解殼數(shù)據(jù)●把解殼數(shù)據(jù)寫入解殼程序Dex文件末尾,并在文件尾部添加解殼數(shù)據(jù)的大小●修改解殼程序DEX頭中checksum、signature和file_size頭信息●修改源程序AndroidMainfest.xml文件并覆蓋解殼程序AndroidMainfest.xml文件解殼DEX程序工作流程●讀取DEX文件末尾數(shù)據(jù)獲取借殼數(shù)據(jù)長(zhǎng)度●從DEX文件讀取解殼數(shù)據(jù),解密解殼數(shù)據(jù)。以文件形式保存解密數(shù)據(jù)到a.APK文件●通過(guò)DexClassLoader動(dòng)態(tài)加載a.apk10.1.5加殼--移動(dòng)端--Android
Dex文件加殼原理10.1防逆向分析(二)解殼數(shù)據(jù)位于解殼程序文件頭該種方式相對(duì)比較復(fù)雜,合并后DEX文件結(jié)構(gòu)如圖:10.1.5加殼--移動(dòng)端--Android
Dex文件加殼原理10.1防逆向分析加殼程序工作流程●加密源程序APK文件為解殼數(shù)據(jù)●計(jì)算解殼數(shù)據(jù)長(zhǎng)度,并添加該長(zhǎng)度到解殼DEX文件頭末尾,并繼續(xù)解殼數(shù)據(jù)到文件頭末尾●修改解殼程序DEX頭中checksum、signature、file_size、header_size、string_ids_off、type_ids_off、proto_ids_off、field_ids_off、method_ids_off、class_defs_off和data_off相關(guān)項(xiàng)。
分析map_off數(shù)據(jù),修改相關(guān)的數(shù)據(jù)偏移量●修改源程序AndroidMainfest.xml文件并覆蓋解殼程序AndroidMainfest.xml文件解殼DEX程序工作流程●從0x70處讀取解殼數(shù)據(jù)長(zhǎng)度●從DEX文件讀取解殼數(shù)據(jù),解密解殼數(shù)據(jù)。以文件形式保存解密數(shù)據(jù)到a.APK●通過(guò)DexClassLoader動(dòng)態(tài)加載a.APK10.1.6資源加密10.1防逆向分析代碼加密是現(xiàn)代保護(hù)系統(tǒng)的核心。代碼加密的最終目的都是將原始的代碼轉(zhuǎn)換為等價(jià)的、極其復(fù)雜的、更多的代碼,這要求加密后的代碼與加密前的代碼在執(zhí)行結(jié)果上盡可能等價(jià)。代碼加密技術(shù)分為局部代碼加密和全局代碼加密,其區(qū)別在于:局部加密一般針對(duì)的是單條或者為數(shù)不多的幾條指令,而全局加密是通過(guò)全局考慮程序的代碼布局轉(zhuǎn)而進(jìn)行加密的技術(shù)。10.1.6資源加密--代碼變形10.1防逆向分析代碼變形技術(shù)是指將1條或多條指令轉(zhuǎn)變?yōu)榕c執(zhí)行結(jié)果等價(jià)的1條或多條其他指令。局部變形一般只考慮1條代碼的變形全局變形是將2條或者多條代碼結(jié)合起來(lái)考慮變形以下是1條指令的變形。選取一條普通的指令,示例如下:這是一條簡(jiǎn)單的賦值指令,目的是將CPU寄存器eax的內(nèi)容設(shè)定為12345678h。可通過(guò)以下方式將這條代碼復(fù)雜化這是2條代碼的組合,這個(gè)組合的功能是先將12345678h壓入棧,然后彈出到CPU的eax寄存器。運(yùn)行結(jié)果也是將12345678h放到寄存器eax中,因此這兩條指令是等價(jià)的,可以置換。但是,后面的代碼明顯比前面的代碼復(fù)雜。10.1.6資源加密--代碼變形10.1防逆向分析還可以進(jìn)一步將這個(gè)過(guò)程復(fù)雜化,代碼如下:這段代碼最終也實(shí)現(xiàn)了向eax賦值的目的,但是很明顯,它已經(jīng)變得復(fù)雜了。而且,在這段代碼中又出現(xiàn)了類似“moveax,12345678h”的代碼“moveax,1234h”,可以將這段代碼用其他的等價(jià)代碼替換,變成如下的樣子。10.1.6資源加密--代碼變形10.1防逆向分析這樣進(jìn)行下去,我們可以將1條簡(jiǎn)單的指令蟛脹成任何數(shù)量的指令為了理解這個(gè)簡(jiǎn)單的賦值過(guò)程需要閱讀大量代碼,最后才確定,原來(lái)只是做了1條指令的工作。這就是代碼變形,甚至是所有代碼加密的核心思路。10.1.6資源加密--代碼變形10.1防逆向分析下面多條代碼的例子,也就是全局代碼的變形。假設(shè)有如下代碼:這是兩條簡(jiǎn)單的數(shù)據(jù)傳送代碼,但是這兩條代碼是有序列關(guān)聯(lián)的,其中第2條代碼的執(zhí)行依賴于第1條代碼指令的結(jié)果。當(dāng)然,我們很容易想到可以將代碼逐條變形,但是這么復(fù)雜的程序有時(shí)候不如同時(shí)變形2條代碼。例如,可以用下面的代碼進(jìn)行等價(jià)替換。10.1.6資源加密--代碼變形10.1防逆向分析可以看到,這種變形和第一種變形是不一樣的。在這種變形中,同時(shí)考慮了兩條指令的執(zhí)行,包括執(zhí)行順序和最終結(jié)果。無(wú)法看到單獨(dú)的“movcax,ebx”指令的等價(jià)替換,或者“movecx,eax”指令的等價(jià)替換,但整體執(zhí)行的結(jié)果卻是等價(jià)的,這就是全局代碼變形的特點(diǎn)。這種特點(diǎn)將使通過(guò)變形后的代碼推導(dǎo)出變形前的代碼的操作更加困難。10.1.6資源加密--代碼變形10.1防逆向分析上面的兩種模式,就是基于代碼指令變形的基本思路。代碼變形在代碼保護(hù)上的一個(gè)例子,如圖所示。這是WinLicense代碼虛擬機(jī)的入口代碼,是典型的使用代碼變形技術(shù)的例子。下面直接給出結(jié)束部分,如圖所示。10.1.6資源加密--代碼變形10.1防逆向分析0056899A處的call指令編號(hào)為313,說(shuō)明從入口到這里執(zhí)行了313條指令序列。用自動(dòng)化技術(shù)執(zhí)行代碼簡(jiǎn)化,可以了解這300多行指令究竟是何目的,如下圖所示。10.1.6資源加密--代碼變形10.1防逆向分析前面的300多行指令,其目的是模擬pushfd及pushad指令以保存環(huán)境10.1.6資源加密--花指令10.1防逆向分析花指令是代碼保護(hù)中一種很簡(jiǎn)單的技巧。其原理是在原始的代碼中插入一段無(wú)用的或者能夠干擾調(diào)試器反匯編引擎的代碼,這段代碼本身沒(méi)有任何功能性的作用,只是作為擾亂代碼分析的手段。有如下代碼:假設(shè)這是2條原始代碼,可以通過(guò)在這2條代碼中插入花指令使代碼的分析復(fù)化。例如,可以將代碼變成如下代碼:其區(qū)別就在于多了一條“moveax,eax”指令。這條指令沒(méi)有任何用處,但是它增加了理解原始代碼的難度。例如,至少在第2段代碼中,必須閱讀3條指令。又如,可以將代碼變成如下代碼:10.1.6資源加密--花指令10.1防逆向分析多出了一個(gè)“call”。但是,這段代碼與上面的代碼是等價(jià)的。這就是花指令的另外一個(gè)目的--擾亂調(diào)試器的反匯編引擎。大多數(shù)調(diào)試器的反匯編引擎都是靜態(tài)工作的,在這段代碼中,當(dāng)0100368A處的代碼被執(zhí)行后,CPU會(huì)因?yàn)榇a的控制而轉(zhuǎn)人0100368D處。結(jié)果代碼的執(zhí)行流程如下:0100368C處的代碼永遠(yuǎn)不會(huì)被執(zhí)行,但是調(diào)試器很難事先知道這一點(diǎn)10.1.6資源加密--代碼亂序10.1防逆向分析代碼亂序的思路是非常容易理解的。代碼指令一般都是按照一定序列執(zhí)行的,例如下面的代碼:
代碼亂序的意思就是,通過(guò)1種或者多種方法打亂這種指令的排列方式,以干擾大腦的直觀分析能力。但是,為了保證執(zhí)行結(jié)果的相同,代碼亂序的主要目的是破壞直觀感受,代碼的真實(shí)執(zhí)行順序是不能改變的。例如,可以將上面的代碼變換為下面的等價(jià)代碼:10.1.6資源加密--代碼亂序10.1防逆向分析通過(guò)觀察上面的代碼可以發(fā)現(xiàn),將原來(lái)代碼序列中的指令拆分,并打亂其順序,然后用jmp指令將它們的執(zhí)行流程連接起來(lái)。這樣處理后,這兩段代碼在執(zhí)行結(jié)果上就是一樣的。但容易發(fā)現(xiàn),閱讀和理解第2段代碼的難度要比第1段高出不少。10.1.6資源加密--代碼亂序10.1防逆向分析某保護(hù)系統(tǒng)的實(shí)際代碼,如圖所示,其中所有跳轉(zhuǎn)都超出了調(diào)試器的可視范圍。10.1.6資源加密--多分支10.1防逆向分析多分支技術(shù)是一種利用不同的條件跳轉(zhuǎn)指令將程序執(zhí)行流程復(fù)雜化的技術(shù)。代碼亂序技術(shù)對(duì)代碼的執(zhí)行流程是沒(méi)有改變的,所以要還原亂序的代碼并不困難。然而,多分支技術(shù)對(duì)代碼程序的執(zhí)行流程卻是有改變的,如下代碼。這里有一段由4條指令組成的指令序列,可以通過(guò)如下方式將其變形。10.1.6資源加密--多分支10.1防逆向分析當(dāng)指令執(zhí)行到0100368A處時(shí),執(zhí)行流程有可能跳轉(zhuǎn)到0100368F處繼續(xù)執(zhí)行,也有可能接著執(zhí)行0100368C處的代碼,這樣,這段代碼的執(zhí)行流程就出現(xiàn)了不確定性,需要在代碼執(zhí)行時(shí)才能夠確定代碼的執(zhí)行流程。這段代碼的執(zhí)行結(jié)果和第1段代碼始終相同,這就是多分枝的核心思想。如果在分析時(shí)無(wú)法確定代碼的具體執(zhí)行流程,就會(huì)大大增加分析和理解代碼的難度??梢园l(fā)現(xiàn),在第2段代碼中,實(shí)際上是在原有代碼的基礎(chǔ)上增加了一個(gè)代碼分支。那么就可以在這種情況下做出更大的改變。例如,用不同的代碼替換兩個(gè)分支處的代碼,將其修改為如下形式。10.1.6資源加密--多分支10.1防逆向分析如果不能判斷0100368A處跳轉(zhuǎn)代碼的兩個(gè)目的地的代碼是否等價(jià),那么就不得不同時(shí)分析0100368C處的代碼和0100368F處的代碼,這就增加了代碼分析量。因此,這是一種非常有效的干擾代碼分析的手段。10.1.6資源加密--call鏈10.1防逆向分析call鏈?zhǔn)且环N專門針對(duì)call指令的加密方法。call鏈的思想在于,在一個(gè)正常的PE程序中可以找出非常多的call指令。如圖1.38所示,用OllyDbg的“AllCommands..”查找“CallAny”,可以找到許多指令。10.1.6資源加密--call鏈10.1防逆向分析call指令在調(diào)用子程序的時(shí)候會(huì)將call指令后面的地址壓入棧頂,這樣就可以同時(shí)抽取許多不同的call指令,然后讓它們相互調(diào)用,最后根據(jù)壓入棧的返回地址在事先保存的原始call指令的目標(biāo)地址表中找到call指令的原始目標(biāo)地址,從而進(jìn)入這個(gè)目標(biāo)地址。例如,可以構(gòu)建如下代碼:10.1.6資源加密--call鏈10.1防逆向分析這是一個(gè)call鏈,當(dāng)所有call指令都被執(zhí)行后,棧里面的數(shù)據(jù)如圖所示:根據(jù)入棧的順序和數(shù)量,可以找出最初被調(diào)用的那個(gè)call指令,然后轉(zhuǎn)入那個(gè)call指令最初的目標(biāo)地址。當(dāng)程序代碼中有許多call指令經(jīng)過(guò)這樣的處理以后,會(huì)對(duì)靜態(tài)分析工具(例如IDA)造成非常大的干擾。10.2防動(dòng)態(tài)調(diào)試10.2.1函數(shù)檢測(cè)函數(shù)檢測(cè)就是通過(guò)Windows自帶的公開(kāi)或未公開(kāi)的函數(shù)直接檢測(cè)程序是否處于調(diào)試狀態(tài)。最簡(jiǎn)單的調(diào)試器檢測(cè)函數(shù)是IsDebuggerPresent,該函數(shù)的原型為“BOOLWINAPIIsDebuggerPresent(VOID)”,當(dāng)檢測(cè)到程序處于調(diào)試狀態(tài)時(shí)返回“TRUE”。IsDebuggerPresent函數(shù)的匯編代碼如下圖所示。10.2防動(dòng)態(tài)調(diào)試10.2.1函數(shù)檢測(cè)
不難發(fā)現(xiàn),該函數(shù)實(shí)際上是從程序的PEB信息中取出PEB的第3個(gè)字節(jié)。PEB的數(shù)據(jù)結(jié)構(gòu)如下圖所示。10.2防動(dòng)態(tài)調(diào)試10.2.1函數(shù)檢測(cè)
可以看到,在PEB結(jié)構(gòu)中,第3個(gè)字節(jié)正是成員BeingDebugged,也就是說(shuō),當(dāng)進(jìn)程處于調(diào)試狀態(tài)時(shí),系統(tǒng)會(huì)將該字節(jié)設(shè)定為1,實(shí)例代碼如下圖所示。10.2防動(dòng)態(tài)調(diào)試10.2.2數(shù)據(jù)檢測(cè)
數(shù)據(jù)檢測(cè)是指程序通過(guò)測(cè)試一些與調(diào)試相關(guān)的關(guān)鍵位置的數(shù)據(jù)來(lái)判斷是否處于調(diào)試狀態(tài)。例如,在函數(shù)檢測(cè)中,可以通過(guò)PEB的第3個(gè)字節(jié)表示進(jìn)程是否處于調(diào)試狀態(tài)??梢詷?gòu)建檢測(cè)代碼,如右圖所示。10.2防動(dòng)態(tài)調(diào)試10.2.3符號(hào)檢測(cè)符號(hào)檢測(cè)是一種具有針對(duì)性的檢測(cè),主要針對(duì)一些使用了驅(qū)動(dòng)的調(diào)試器或者監(jiān)視器,如SOFTICE、TRW、SYSDEBUGGER、FILEMON、PROCESSEXPLORER等。這些調(diào)試器在啟動(dòng)后會(huì)創(chuàng)建相應(yīng)的驅(qū)動(dòng)鏈接符號(hào),以用于應(yīng)用層與其驅(qū)動(dòng)的通信。但是,因?yàn)槠鋭?chuàng)建的符號(hào)一般情況下比較固定,所以符號(hào)檢測(cè)就通過(guò)測(cè)試這些符號(hào)的名稱來(lái)確定是否存在相應(yīng)的調(diào)試軟件。例如,我們經(jīng)常在調(diào)試CreateFile時(shí)看到的類似“\\.\SoftICE”的符號(hào)名稱,就表示正在檢測(cè)調(diào)試器,示例代碼如下圖所示。10.2防動(dòng)態(tài)調(diào)試10.2.4窗口檢測(cè)窗口檢測(cè)通過(guò)檢測(cè)當(dāng)前桌面中是否存在特定的調(diào)試器窗口來(lái)判斷是否存在調(diào)試器,一般利用FindWindows等函數(shù)來(lái)查找相關(guān)窗口。這種方式現(xiàn)在已經(jīng)很少使用,因?yàn)樗泻芏嗳秉c(diǎn),如窗口名稱和類名很容易改變、只能通過(guò)這種方式檢測(cè)、只能檢測(cè)到是否存在調(diào)試器窗口、不能檢測(cè)到調(diào)試器是否正在調(diào)試該程序,示例代碼如下圖所示。10.2防動(dòng)態(tài)調(diào)試10.2.5特征碼檢測(cè)特征碼檢測(cè)枚舉當(dāng)前所有正在進(jìn)行的進(jìn)程,并在進(jìn)程的內(nèi)存空間中搜索特定調(diào)試器的代碼片段。定位OllyDbg調(diào)試器的特征代碼,如下圖所示。
選取一段具有明顯的OllyDbg特的數(shù)據(jù),示例如下。0x41,0x00,0x62,0x00,0x6F,0x00,0x75,0x00,0x74,0x00,0x20,0x00,0x4F,0x00,0x6C,0x00,0x6C,0x00,0x79,0x00,0x44,0x00,0x62,0x00,0x67,0x00,0x00,0x00,0x4F,0x00,0x4B,0x00,0x00,0x0010.2防動(dòng)態(tài)調(diào)試10.2.6行為檢測(cè)行為檢測(cè)是指在程序中通過(guò)代碼感知程序處于調(diào)試時(shí)與未處于調(diào)試時(shí)的各種差異來(lái)判斷程序是否處于調(diào)試狀態(tài)。舉個(gè)例子,調(diào)試程序時(shí)步過(guò)2條指令所花費(fèi)的時(shí)間會(huì)遠(yuǎn)遠(yuǎn)超過(guò)CPU連續(xù)執(zhí)行這2條指令所花費(fèi)的時(shí)間??梢酝ㄟ^(guò)rdtsc指令構(gòu)建如下代碼。當(dāng)單步到00401006處且有所停留時(shí),0040100A處會(huì)有感知。
00401004 0F31 rdtsc
00401006 89D1
movecx,edx
00401008 0F31 rdtsc
0040100A 29CA
subedx,ecx
0040100C 83FA02 cmpedx,2
0040100F 7701
jashort0040101210.2防動(dòng)態(tài)調(diào)試10.2.7斷點(diǎn)檢測(cè)斷點(diǎn)檢測(cè)功能根據(jù)調(diào)試器設(shè)置斷點(diǎn)的技術(shù)原理來(lái)檢測(cè)軟件代碼中是否設(shè)置了斷點(diǎn)在調(diào)試器中,一般使用兩種方式設(shè)置代碼斷點(diǎn):通過(guò)修改代碼指令為int3觸發(fā)軟件異常通過(guò)硬件調(diào)試寄存器設(shè)定硬件斷點(diǎn)針對(duì)軟件斷點(diǎn),保護(hù)系統(tǒng)分析重要的代碼區(qū)域,檢測(cè)指令是否存在設(shè)計(jì)之外的int3指令10.2防動(dòng)態(tài)調(diào)試10.2.7斷點(diǎn)檢測(cè)在函數(shù)入口處一般都是跨模塊處理的,根據(jù)異常處理機(jī)制,在設(shè)置異常處理程序之前,模塊外的異常處理程序很難處理其他模塊的異常,因此這段代碼一旦執(zhí)行必定引起程序異常。而調(diào)試程序時(shí),在函數(shù)入口設(shè)定斷點(diǎn)是非常正常的,所以,如果保護(hù)系統(tǒng)偵測(cè)到類似這樣的代碼,就可以判定存在調(diào)試器。硬件斷點(diǎn)的偵測(cè)要復(fù)雜一些。由于程序工作在保護(hù)模式下,無(wú)法訪問(wèn)硬件調(diào)試斷點(diǎn),因此在保護(hù)系統(tǒng)中,如果要偵測(cè)硬件斷點(diǎn),一般需要構(gòu)建異常程序來(lái)獲取dr系列寄存器的值。斷點(diǎn)偵測(cè)是一個(gè)非常有用的偵測(cè)手段,但是其應(yīng)用非常困難,這主要是由其效率低、確定關(guān)鍵代碼比較困難造成的。10.2防動(dòng)態(tài)調(diào)試10.2.8功能破壞功能破壞是指通過(guò)某種技術(shù)手段,在保證被保護(hù)程序能夠正常執(zhí)行的情況下,將系統(tǒng)原本提供的與調(diào)試相關(guān)的功能破壞,從而使調(diào)試器無(wú)法正常工作。NtSetInformationThread是系統(tǒng)提供的一個(gè)設(shè)置線程屬性的函數(shù),這個(gè)函數(shù)的原型如下。NTSTATUS NTAPI NtSetInformationThread(
IN HANDLE ThreadHandle,
IN THREAD_INFORMATION_CLASS ThreadInformaitonClass,
IN PVOID
ThreadInformation,
IN ULONG ThreadInformationLength
);10.2防動(dòng)態(tài)調(diào)試10.2.8功能破壞在這個(gè)函數(shù)的參數(shù)ThreadInfoClass中指定了許多與線程相關(guān)的屬性,其中有一項(xiàng)是ThreadHideFromDebugger。這一屬性可以對(duì)調(diào)試器隱蔽被設(shè)置線程的異常,我們可以構(gòu)建如下圖所示的代碼來(lái)破壞調(diào)試器下軟件斷點(diǎn)的能力。10.2防動(dòng)態(tài)調(diào)試10.2.8功能破壞在測(cè)試上面的程序時(shí)發(fā)現(xiàn),盡管用調(diào)試器啟動(dòng)了程序,但最后一個(gè)DebugBreak()函數(shù)還是會(huì)引發(fā)程序的異常,而且調(diào)試器無(wú)法捕獲該異常。還有一些功能模塊會(huì)引起系統(tǒng)級(jí)別的破壞。例如,有很多內(nèi)核驅(qū)動(dòng)的保護(hù)程序總是將被保護(hù)程序的進(jìn)程“武裝”起來(lái),使調(diào)用WriteProcessMemory等函數(shù)的操作失敗,這也是屬于功能破壞。10.2防動(dòng)態(tài)調(diào)試10.2.8功能破壞
在測(cè)試上面的程序時(shí)我們發(fā)現(xiàn),盡管用調(diào)試器啟動(dòng)了程序,但最后一個(gè)DebugBreak()函數(shù)還是會(huì)引發(fā)程序的異常,而且調(diào)試器無(wú)法捕獲該異常。還有一些功能模塊會(huì)引起系統(tǒng)級(jí)別的破壞。例如,有很多內(nèi)核驅(qū)動(dòng)的保護(hù)程序總是將被保護(hù)程序的進(jìn)程“武裝”起來(lái),使調(diào)用WriteProcessMemory等函數(shù)的操作失敗,這也是屬于功能破壞,在這里我們只需要了解這種概念就可以了。10.3運(yùn)行環(huán)境檢測(cè)、反沙箱虛擬機(jī)時(shí)一種特殊的調(diào)試?yán)?,是目前分析和調(diào)試程序不可或缺的利器。虛擬機(jī)擁有一種特殊的能力,就是對(duì)真實(shí)系統(tǒng)環(huán)境的模擬,這樣可以使軟件無(wú)法正確判斷當(dāng)前的環(huán)境。例如,一款程序是針對(duì)計(jì)算機(jī)硬件序列號(hào)實(shí)行一機(jī)一碼授權(quán)的,如果這款軟件對(duì)其在虛擬機(jī)中運(yùn)行時(shí)獲取的信息進(jìn)行了授權(quán),那么由于虛擬機(jī)環(huán)境是可以復(fù)制的,所以程序的一機(jī)一碼授權(quán)能力從某種程度上就失效了。另外,虛擬機(jī)對(duì)于分析者對(duì)程序的分析也是相當(dāng)有幫助的。正確使用虛擬機(jī)的快照等功能,會(huì)使復(fù)雜的分析大大簡(jiǎn)化。所以,為了避免上述情況出現(xiàn),好的軟件保護(hù)系統(tǒng)將檢測(cè)并禁止被保護(hù)的軟件在虛擬機(jī)中運(yùn)行,這就需要有能夠識(shí)別虛擬機(jī)環(huán)境的技術(shù),即反虛擬機(jī)技術(shù)。10.3運(yùn)行環(huán)境檢測(cè)、反沙箱10.3.1檢測(cè)android_server端口號(hào)android_server的默認(rèn)監(jiān)聽(tīng)的端口號(hào)是23946,可以通過(guò)檢測(cè)23946端口號(hào)是否開(kāi)啟判斷應(yīng)用程序是否被調(diào)試。Linux系統(tǒng)中的/proc/net/tcp會(huì)記錄相關(guān)連接信息,首先看到在沒(méi)有連接android_server時(shí)候的信息列表:
然后通過(guò)adb將IDA的android_serverpush到android手機(jī)里并啟動(dòng)這個(gè)服務(wù)觀察變化如圖:10.3運(yùn)行環(huán)境檢測(cè)、反沙箱10.3.1檢測(cè)android_server端口號(hào)在這里重點(diǎn)關(guān)注這一列:代表本地地址與端口號(hào),在連接上android_server以后可以看到信息列表多了一行。可以看到在底層多了5D8A的端口,這個(gè)是十六進(jìn)制表示正是十進(jìn)制23946的表示,因此可以檢測(cè)這個(gè)文件下面的這個(gè)端口號(hào)來(lái)進(jìn)行達(dá)到反調(diào)試的作用。當(dāng)然這里也可以通過(guò)執(zhí)行netstat–apn命令來(lái)進(jìn)行查看。10.3運(yùn)行環(huán)境檢測(cè)、反沙箱10.3.2通過(guò)檢測(cè)android_server關(guān)鍵字以及文件目錄在調(diào)試進(jìn)程時(shí),進(jìn)程會(huì)被IDA中的android_serverptrace,并且進(jìn)程名字存在于“/proc/pid/cmdline”中,當(dāng)然這里的pid指的是android_server的進(jìn)程號(hào),這個(gè)可以通過(guò)TracePid來(lái)獲得,通過(guò)下面這個(gè)圖可以看出來(lái):把它adbpull出來(lái),可以看到的是:因此說(shuō)在這里可以檢測(cè)這個(gè)名字,如果有這個(gè)名字說(shuō)明正在被調(diào)試,那就可以kill掉這個(gè)程序。一般情況下,android_server都會(huì)放在/data/local/tmp/文件下,因此還可以檢測(cè)這個(gè)文件是不是有android_server,如果有,程序退出。10.3運(yùn)行環(huán)境檢測(cè)、反沙箱10.3.3檢測(cè)Tracerpid的值在調(diào)試狀態(tài)下,Linux會(huì)向/proc/pid/status寫入進(jìn)程狀態(tài)信息,TracerPid字段會(huì)寫入調(diào)試進(jìn)程的pid,以下是在調(diào)試前后/proc/pid/status的文件的變化。可以檢測(cè)Tracerpid的值,如果不為0,只能說(shuō)明一點(diǎn):當(dāng)前進(jìn)程正在被調(diào)試,那就kill掉退出。(1)檢查簽名獲取簽名Hash值的代碼如下:
移動(dòng)端10.4.1文件校驗(yàn)判斷其簽名Hash是否為這個(gè)值,來(lái)檢査軟件是否被篡改過(guò),相應(yīng)的代碼如下:
移動(dòng)端10.4.1文件校驗(yàn)10.4.1文件校驗(yàn)
移動(dòng)端(2)校驗(yàn)保護(hù)重編譯Android軟件的實(shí)質(zhì)是重新編譯classes.dex文件,代碼經(jīng)過(guò)重新編譯后,生成的classes.dex文件的Hash值已經(jīng)改變。我們可以檢査程序安裝后classes.dex文件的Hash值,來(lái)判斷軟件是否被重打包過(guò)。相應(yīng)代碼如下:PC端10.4.1文件校驗(yàn)程序啟動(dòng)時(shí)計(jì)算程序文件的校驗(yàn)值與事先計(jì)算好的校驗(yàn)值進(jìn)行比較,從而判斷文件是否被篡改。PC端10.4.1文件校驗(yàn)現(xiàn)在的很多破解技術(shù)往往不直接修改程序文件,而是在程序運(yùn)行以后直接修改程序內(nèi)存中的數(shù)據(jù)。內(nèi)存校驗(yàn)就是一種防止破解者通過(guò)程序運(yùn)行以后修改程序內(nèi)存數(shù)據(jù)而達(dá)到破解目的的反破解方式。PC端10.4.1文件校驗(yàn)當(dāng)程序運(yùn)行以后,其內(nèi)存數(shù)據(jù)是隨時(shí)變化的,無(wú)論是系統(tǒng)修改還是程序自身代碼都有可能修改內(nèi)存中的數(shù)據(jù),所以,內(nèi)存校驗(yàn)無(wú)法校驗(yàn)所有的內(nèi)存數(shù)據(jù)。那么,選取哪些數(shù)據(jù)進(jìn)行校驗(yàn)最合適呢?先觀察一下PE程序被映射到內(nèi)存后數(shù)據(jù)存放位置內(nèi)存空間的特點(diǎn)。可以看到,程序?qū)?text、.rsrc、.reloc區(qū)段的訪問(wèn)類型都是只讀,而對(duì).data區(qū)段可以讀、寫、訪問(wèn),這就說(shuō)明:在程序運(yùn)行的時(shí)候,大多數(shù)情況下,.text、.rsrc、.reloc區(qū)段的內(nèi)容都不會(huì)發(fā)生變化,可以校驗(yàn)這些空間中的數(shù)據(jù);而.data區(qū)段的內(nèi)容隨時(shí)都有可能發(fā)生變化,將不能進(jìn)行校驗(yàn)。PC端10.4.1文件校驗(yàn)有兩種方式校驗(yàn)這些區(qū)段?!袷孪葟腜E程序文件中計(jì)算出區(qū)段的校驗(yàn)值,并在程序啟動(dòng)后與相應(yīng)內(nèi)存中的區(qū)段校驗(yàn)值進(jìn)行對(duì)比。但是,程序映射到內(nèi)存空間與文件中的數(shù)據(jù)并非是任何情況下都相同的,當(dāng)程序存在重定位節(jié)并發(fā)生了重定位的情況下,區(qū)段會(huì)不一樣,因此這種情況下需要進(jìn)行特殊處理。●事先不計(jì)算區(qū)段的校驗(yàn)值,而是在程序啟動(dòng)時(shí)計(jì)算,然后定時(shí)再次計(jì)算并比較兩次的計(jì)算結(jié)果,如果不同就說(shuō)明內(nèi)存數(shù)據(jù)被修改了。10.4.2內(nèi)存校驗(yàn)
對(duì)整個(gè)代碼數(shù)據(jù)校驗(yàn)
毎個(gè)程序至少有一個(gè)代碼區(qū)塊和數(shù)據(jù)區(qū)塊。數(shù)據(jù)區(qū)塊屬性可讀寫,程序運(yùn)行時(shí).全局變量通常會(huì)放在這里,這些變量數(shù)據(jù)會(huì)動(dòng)態(tài)變化,因此校驗(yàn)這部分是沒(méi)有意義的。而代碼區(qū)塊屬性只讀,存放的是程序代碼,在程序運(yùn)行過(guò)程中數(shù)據(jù)是不會(huì)變化的,因此用這部分進(jìn)行內(nèi)存校驗(yàn)是可行的。具體實(shí)現(xiàn)的思路如下:●從內(nèi)存映像得到PE相關(guān)數(shù)據(jù),如代碼區(qū)塊的RVA值和內(nèi)存大小等●根據(jù)得到的代碼區(qū)塊的RVA值和內(nèi)存大小,計(jì)算其內(nèi)存數(shù)據(jù)的CRC-32值●讀取自身文件先前儲(chǔ)存的CRC-32值●比較兩個(gè)CRC-32值10.4.2內(nèi)存校驗(yàn)
對(duì)整個(gè)代碼數(shù)據(jù)校驗(yàn)
這個(gè)方法還能有效地抵抗調(diào)試器的普通斷點(diǎn),因?yàn)檎{(diào)試器一般通過(guò)給應(yīng)用程序代碼硬加INT3指令來(lái)實(shí)埂中斷,這樣就改變了代碼區(qū)塊的數(shù)據(jù),計(jì)算CRC-32值就會(huì)與原來(lái)的不同。10.4.2內(nèi)存校驗(yàn)
對(duì)整個(gè)代碼數(shù)據(jù)校驗(yàn)
程序加殼后,讀取的是外殼的代碼區(qū)塊RVA值和大小與計(jì)算出來(lái)的CRC-32校驗(yàn)值不同。解決辦法是編程時(shí)直接用代碼區(qū)塊的RVA具體值參與計(jì)算,這些具體的值可以用PE工具,將這些值填進(jìn)源程序中再編譯即可。圖中,代碼區(qū)塊(.text)的RVA值為1000h,大小為36AEh10.4.2內(nèi)存校驗(yàn)
對(duì)整個(gè)代碼數(shù)據(jù)校驗(yàn)
為了方便加殼,改進(jìn)后的代碼如下:10.4.2內(nèi)存校驗(yàn)
校驗(yàn)內(nèi)存代碼片段
在實(shí)際過(guò)程中,有時(shí)只需對(duì)一小段代碼進(jìn)行內(nèi)存校驗(yàn),以防止調(diào)試工具的INT3斷點(diǎn)。實(shí)現(xiàn)代碼如下:10.4.2內(nèi)存校驗(yàn)
校驗(yàn)內(nèi)存代碼片段
上述代碼中CRC32()函數(shù)的返回值可通過(guò)調(diào)試器跟蹤得到,再填進(jìn)源代碼里重新編譯即可。具體的匯編代碼如下:跟蹤調(diào)試時(shí),如對(duì)401014h?40102Bh之間代碼設(shè)INT3斷點(diǎn)時(shí),CRC校驗(yàn)將發(fā)生變化,從而發(fā)現(xiàn)程序被跟蹤。實(shí)際操作時(shí),可以不提示斷點(diǎn)被發(fā)現(xiàn),而是悄悄退出,使得校驗(yàn)史隱蔽。10.5.1靜態(tài)混淆PC端--外形混淆
主要通過(guò)刪除和改名,使攻擊者難以閱讀和理解,并減小程序的大小。上面的三個(gè)函數(shù)名均替換為fat后,三個(gè)函數(shù)進(jìn)行了重載,函數(shù)調(diào)用根據(jù)參數(shù)類型進(jìn)行區(qū)分調(diào)用。10.5.1靜態(tài)混淆PC端--外形混淆
就算法的性能而言,外形混淆算法為程序增加的混淆度有限,算法的強(qiáng)度性能比較低,但是這類算法具有高度單向性,其彈性性能可達(dá)到單向混淆,同時(shí)算法沒(méi)有給程序帶來(lái)額外的開(kāi)銷,算法實(shí)現(xiàn)容易。因此得到了廣泛的應(yīng)用,大多數(shù)混淆器都支持外形混淆。10.5.1靜態(tài)混淆PC端--結(jié)構(gòu)混淆用偽裝的條件判斷語(yǔ)句來(lái)隱藏真實(shí)的執(zhí)行路徑,使得攻擊者對(duì)程序的控制流難以理解下圖中,對(duì)于按次序執(zhí)行的兩個(gè)語(yǔ)句A、B,增加一個(gè)控制條件,以決定B的執(zhí)行。通過(guò)這種方式加大逆向工程的難度,但是所有的干擾控制都不會(huì)影響B(tài)的執(zhí)行。10.5.1靜態(tài)混淆PC端--結(jié)構(gòu)混淆
平展控制流技術(shù)是控制結(jié)構(gòu)混淆的一種。它的目標(biāo)是通過(guò)對(duì)控制流圖進(jìn)行平展,使得所有基本塊看起來(lái)具有相同的前驅(qū)和后繼集合,從而達(dá)到對(duì)程序的控制流邏輯關(guān)系進(jìn)行混淆的目的。下面以一個(gè)小程序演示平展控制流技術(shù)。10.5.1靜態(tài)混淆PC端--結(jié)構(gòu)混淆
上述的源程序通過(guò)應(yīng)用平展控制流后得到下圖控制流圖,S是switch塊,x是調(diào)度變量。當(dāng)控制進(jìn)入到函數(shù)中,基本塊init將控制轉(zhuǎn)移到A。在此之后,控制流通過(guò)不同基本塊中對(duì)x的賦值來(lái)指導(dǎo)。10.5.1靜態(tài)混淆PC端--結(jié)構(gòu)混淆盡管混淆后代碼的控制流行為不是很明顯,但是可以通過(guò)檢測(cè)賦給調(diào)度變量的常數(shù)來(lái)重構(gòu)控制流圖??刂平Y(jié)構(gòu)混淆算法增加了程序u1、u2、u3、u5的復(fù)雜度,抵抗攻擊能力強(qiáng),但是開(kāi)銷很大。10.5.1靜態(tài)混淆PC端--布局混淆
布局混淆是指刪除或者混淆軟件源代碼或者中間代碼中與執(zhí)行無(wú)關(guān)的輔助文本信息,增加攻擊者閱讀和理解代碼的難度。軟件代碼中的常量名、變量名、類名和方法名等標(biāo)識(shí)符的命名規(guī)則和字面意義有利于攻擊者對(duì)代碼的理解,布局混淆通過(guò)混淆這些標(biāo)識(shí)符增加攻擊者對(duì)軟件代碼理解的難度。布局混淆是最簡(jiǎn)單的混淆方法,它不改變軟件的代碼和執(zhí)行過(guò)程。10.5.1靜態(tài)混淆PC端--數(shù)據(jù)混淆
數(shù)據(jù)混淆算法對(duì)程序中的數(shù)據(jù)結(jié)構(gòu)進(jìn)行轉(zhuǎn)換,以非常規(guī)的方式組織數(shù)據(jù),增加攻擊者獲取有效信息的難度。方法有靜態(tài)數(shù)據(jù)動(dòng)態(tài)生成,數(shù)組結(jié)構(gòu)轉(zhuǎn)換,類繼承轉(zhuǎn)換,數(shù)據(jù)存儲(chǔ)空間轉(zhuǎn)換等。●靜態(tài)數(shù)據(jù)動(dòng)態(tài)生成靜態(tài)數(shù)據(jù),尤其是字符串?dāng)?shù)據(jù),包含大量攻擊者需要的信息,利用函數(shù)或子程序?qū)o態(tài)數(shù)據(jù)進(jìn)行動(dòng)態(tài)生成的方式混淆,能增加程序u1、u2復(fù)雜度。●數(shù)組結(jié)構(gòu)轉(zhuǎn)換它包括將數(shù)組拆分或者合并,增加或減少數(shù)組的維度等。合并增加了程序u1、u2復(fù)雜度,拆分?jǐn)?shù)組增加u1、u2、u6復(fù)雜度,改變數(shù)組維度增加了u1、u2、u6、u3復(fù)雜度?!耦惱^承轉(zhuǎn)換類是面向?qū)ο笳Z(yǔ)言中重要的模塊化與抽象化概念。類的設(shè)計(jì)結(jié)構(gòu),繼承關(guān)系反映了程序的設(shè)計(jì)思路。類繼承轉(zhuǎn)換就是對(duì)設(shè)計(jì)結(jié)構(gòu)和繼承關(guān)系進(jìn)行混淆。它包括合并類,分割類和類型隱藏等等。類繼承轉(zhuǎn)換提高了程序的u1、u7復(fù)雜度,額外開(kāi)銷也很小。10.5.1靜態(tài)混淆
移動(dòng)端--控制流平臺(tái)化
在不改變?cè)创a的功能前提下,將C或C++代碼中的if、while、for、do等控制語(yǔ)句轉(zhuǎn)換成switch分支語(yǔ)句。這樣做的好處是可以模糊switch中case代碼塊之間的關(guān)系,從而增加分析難度。控制流平坦化目前用的最多的是ollvm的開(kāi)源混淆方案,很多國(guó)內(nèi)加固廠商都可以看到使用它的身影。對(duì)于ollvm的反混淆思路,多采用基于符號(hào)執(zhí)行的方法來(lái)消除控制流平坦化。10.5.1靜態(tài)混淆
移動(dòng)端--花指令
花指令也叫垃圾指令,是指在原始程序中插入一組無(wú)用的字節(jié),但又不會(huì)改變程序的原始邏輯,程序仍然可以正常運(yùn)行,然而反匯編工具在反匯編這些字節(jié)時(shí)會(huì)出錯(cuò),由此造成反匯編工具失效,提高破解難度。在花指令的對(duì)抗上,主要的方法就是利用代碼掃描技術(shù)檢測(cè)出花指令的位置和長(zhǎng)度,然后利用NOP指令進(jìn)行替換和取代即可。10.5.1靜態(tài)混淆
移動(dòng)端--java函數(shù)反射法
函數(shù)反射調(diào)用是指利用java的反射機(jī)制對(duì)函數(shù)或者方法進(jìn)行調(diào)用,通過(guò)大量運(yùn)用反射會(huì)使得代碼的冗余度大大增加,反匯編后的代碼會(huì)變得難以閱讀和理解,增大反匯編難度。在函數(shù)反射調(diào)用的動(dòng)態(tài)對(duì)抗上,主要是利用函數(shù)反射調(diào)用的特殊規(guī)律,對(duì)加密的代碼進(jìn)行相對(duì)應(yīng)的還原處理。10.5.1靜態(tài)混淆
移動(dòng)端--ProGard該工具的原理是使用簡(jiǎn)短無(wú)意義的英文字母對(duì)代碼中的包含的變量名、函數(shù)名以及類名進(jìn)行替代,該過(guò)程是不可逆的。ProGuard具有局限性,只能進(jìn)行簡(jiǎn)單的類名、函數(shù)名混淆。10.5.2動(dòng)態(tài)態(tài)混淆
預(yù)防性混淆
這種混淆通常是針對(duì)一些專用的反編譯器而設(shè)計(jì)的,一般來(lái)說(shuō),這些技術(shù)利用反編譯器的弱點(diǎn)或者Bug來(lái)設(shè)計(jì)混淆方案。例如,有些反編譯器對(duì)于Return后面的指令不進(jìn)行反編譯,而有些混淆方案恰恰將代碼放在Return語(yǔ)句后面。這種混淆的有效性對(duì)于不同反編譯器的作用也不太相同的。10.5.2動(dòng)態(tài)態(tài)混淆
自修改代碼技術(shù)
自修改代碼技術(shù)是程序運(yùn)行期間修改或產(chǎn)生代碼的一種機(jī)制,其主要利用了馮羅伊曼體系結(jié)構(gòu)的存儲(chǔ)程序的特點(diǎn),即指令和數(shù)據(jù)存儲(chǔ)在同一個(gè)內(nèi)存空間中,因此指令可以被視作數(shù)據(jù)被其他指令讀取和修改。自修改保護(hù)機(jī)制可以有效抵御靜態(tài)逆向分析而且由于代碼僅在需要時(shí)才以明文的形式出現(xiàn),可以在一定程度上阻礙逆向工具獲取程序所有的明文代碼,從而抵抗動(dòng)態(tài)分析。10.5.2動(dòng)態(tài)態(tài)混淆
虛擬機(jī)保護(hù)技術(shù)
虛擬機(jī)保護(hù)其實(shí)也屬于自修改代碼的一種,但是由于其保護(hù)強(qiáng)度高,逐漸成為研究的熱點(diǎn),從而自成體系。虛擬機(jī)保護(hù)與傳統(tǒng)自修改代碼技術(shù)的最主要區(qū)別是虛擬機(jī)增加了一層自定義的指令集,而且其難以逆向,破解者想要獲得程序源碼,首先必須弄懂虛擬機(jī)的指令集,這極大增加了逆向的開(kāi)銷。虛擬機(jī)保護(hù)技術(shù)通過(guò)增加復(fù)雜度和在時(shí)間和空間上開(kāi)銷,獲取了更高的保護(hù)強(qiáng)度。10.6軟件水印10.6.1定義與分類軟件水印(SoftwareWaterMarking)是數(shù)字水印技術(shù)的分支,是近年來(lái)出現(xiàn)的軟件產(chǎn)品版權(quán)保護(hù)技術(shù),可以用來(lái)標(biāo)識(shí)作者、發(fā)行商、所有者、使用者等信息,并攜帶有版權(quán)保護(hù)信息和身份認(rèn)證信息,可以鑒別出非法復(fù)制和盜用的軟件產(chǎn)品。10.6軟件水印10.6.1定義與分類根據(jù)軟件水印的提取技術(shù)來(lái)分,可分為靜態(tài)水印和動(dòng)態(tài)水印。靜態(tài)水印存儲(chǔ)在可執(zhí)行程序代碼中,比較典型的是把水印信息放在安裝模塊部分,或者是指令代碼中,或者是調(diào)試信息的符號(hào)部分。靜態(tài)水印又可以進(jìn)一步分為靜態(tài)數(shù)據(jù)水印和靜態(tài)代碼水印。區(qū)別于靜態(tài)水印,動(dòng)態(tài)水印則保存在程序的執(zhí)行狀態(tài)中,而不是程序源代碼本身。這種水印可用于證明程序是否經(jīng)過(guò)了迷亂變換處理。動(dòng)態(tài)水印主要有3類:EasterEgg水印、動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu)水印和執(zhí)行狀態(tài)水印。其中,每種情況都需要有預(yù)先輸入,然后根據(jù)輸入,程序會(huì)運(yùn)行到某種狀態(tài),這些狀態(tài)就代表水印。3.6軟件水印3.6.2靜態(tài)水印靜態(tài)軟件水印的存在不依賴于程序的運(yùn)行狀態(tài),水印嵌入時(shí)不需要運(yùn)行程序,并且在程序的執(zhí)行過(guò)程中保持不變,可以在軟件的分發(fā)與運(yùn)行過(guò)程中被提取驗(yàn)證。根據(jù)水印嵌入位置的不同可分為靜態(tài)數(shù)據(jù)水印與靜態(tài)代碼水印。10.6軟件水印10.6.2靜態(tài)水印——靜態(tài)數(shù)據(jù)水印靜態(tài)數(shù)據(jù)水印將水印信息嵌入在程序的數(shù)據(jù)區(qū)域,比如注釋、頭文件、資源文件、字符串或者調(diào)試信息中。由于它嵌入的位置比較有限,因此隱蔽性較差,容易被攻擊者定位,也難以抵抗代碼混淆工具等保留語(yǔ)義轉(zhuǎn)換攻擊。例如,將水印信息隱藏在字符串中,攻擊者可以使用代碼混淆工具,將字符串分割為多個(gè)字符子串,并把它們散布在程序中,從而水印信息被分解,導(dǎo)致水印不能被正常提取;或者將水印信息隱藏在圖片資源里,如果使用圖片修改工具對(duì)圖片進(jìn)行編輯,也會(huì)破壞水印信息。10.6軟件水印10.6.2靜態(tài)水印——靜態(tài)代碼水印代碼水印技術(shù)利用代碼冗余信息,將水印嵌入到這些冗余信息中。例如在一些順序無(wú)關(guān)的指令中,通過(guò)修改這些指令順序?qū)崿F(xiàn)嵌入水印的目的。Davidson提出的算法就是通過(guò)調(diào)整基本塊序列來(lái)嵌入水印信息,攻擊者可以通過(guò)增加基本塊來(lái)修改原始水印。Moskowitz提出將水印與代碼一起嵌入在程序的特殊資源里(例如圖片和音樂(lè)),程序執(zhí)行時(shí)從資源里提取代碼并執(zhí)行,這種算法的隱蔽性很低,憑空產(chǎn)生的代碼很容易引起攻擊者的懷疑,因此實(shí)用性較差。10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印在程序中像x=a+b這樣的方程式是很常見(jiàn)的。有些數(shù)學(xué)方程式是可交換的,比如x+y=y+x?;谶@個(gè)概念,一個(gè)有相同數(shù)學(xué)意義的方程式可能有多種寫法。因此,可根據(jù)方程式形式的不同來(lái)嵌入水印數(shù)據(jù)。例如求x與y的和有兩種方式,x+y或y+x,選擇其中的一種我們就嵌入了1bit的信息。選取方程式中的兩種操作用來(lái)嵌入水印數(shù)據(jù):加法和乘法。僅當(dāng)操作符的兩個(gè)操作數(shù)之一是常量時(shí)這些操作才是可交換的。以為x*y例,x或y中有一個(gè)是3,采用3*x或者x*3,其數(shù)學(xué)含義并不發(fā)生改變。但若x和y都是變量,則這種交換是不安全的,可能會(huì)影響數(shù)學(xué)表達(dá)式的結(jié)果。下面給出一個(gè)實(shí)例。實(shí)現(xiàn)原理10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印令x=5,則(++x)×(x++)=6×6=36 (2-1)(x++)×(++x)=5×7=35 (2-2)因此(x++)×(++x)≠
(++x)×(x++) (2-3)實(shí)現(xiàn)原理10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印根據(jù)可安全交換操作的操作數(shù)順序,可以嵌入水印信息。有兩種嵌入方法:若嵌入的數(shù)據(jù)位是0,則保持原來(lái)的操作數(shù)順序,若嵌入的數(shù)據(jù)位是1,則將兩個(gè)操作數(shù)的順序進(jìn)行交換后再插入原程序。嵌入水印時(shí),若嵌入位為0,則不再交換,嵌入位為1時(shí),再將這兩個(gè)操作數(shù)順序進(jìn)行交換?;诜匠淌降能浖》椒ú捎玫氖堑诙N嵌入手段。它的水印檢測(cè)手段不需借助原程序,只需判斷提取部位的操作數(shù)是否是按順序的。如果是,則提取位為0,若不是,則提取位為1實(shí)現(xiàn)原理10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印兩個(gè)操作數(shù)的順序是這樣規(guī)定的:若可安全交換操作的兩個(gè)操作數(shù)都是常量,則規(guī)定左操作數(shù)小于等于右操作數(shù)為順序的,若可安全交換操作的兩個(gè)操作數(shù)有一個(gè)是變量,則規(guī)定左操作數(shù)是常量,右操作數(shù)是變量,才是順序的。為了便于操作數(shù)順序的調(diào)整,應(yīng)首先建立方程式的樹(shù)形結(jié)構(gòu)。操作符為內(nèi)結(jié)點(diǎn),操作數(shù)為葉子節(jié)點(diǎn),并按運(yùn)算優(yōu)先級(jí)來(lái)生成樹(shù)形結(jié)構(gòu)。比如x×3×y+4×(x+6)的分析樹(shù)如下圖所示:實(shí)現(xiàn)原理10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印根據(jù)操作的選取方法,按照先根順序訪問(wèn)分析樹(shù),該方程中有3處可用來(lái)嵌入水?。簒×3,x+6和4×(x+6)。首先根據(jù)規(guī)定的順序?qū)Ψ匠淌阶髡{(diào)整。其中x×3和x+6需要調(diào)整,調(diào)整后的樹(shù)形結(jié)構(gòu)如下圖所示。實(shí)現(xiàn)原理調(diào)整后的方程式為x×3×y+4×(x+6) (2-4)10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印然后根據(jù)嵌入規(guī)則可以向該方程式嵌入3位水印數(shù)據(jù)。比如嵌入的水印數(shù)據(jù)為“010”,則需要將第2個(gè)可交換操作,作兩個(gè)操作數(shù)的交換,第1個(gè)和第3個(gè)擱置不懂。即交換6+x為x+6,交換后的分析樹(shù)如下圖所示。該分析樹(shù)的方程式為:x×3×y+4×(x+6) (2-5)實(shí)現(xiàn)原理10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印將新的方程式嵌入源程序的原始位置即可。據(jù)此實(shí)現(xiàn)了不改變程序的正確性,嵌入了水印。提取時(shí),按照先根順序訪問(wèn)分析樹(shù),若可交換位置是按順序的,提取的數(shù)據(jù)為0,若逆序,則提取的水印為1。實(shí)現(xiàn)原理10.6軟件水印10.6.2靜態(tài)水印案例——基于方程式的靜態(tài)代碼水印基于方程式的軟件水印算法將水印數(shù)據(jù)嵌入在方程式部分操作數(shù)順序中,在保證程序正確性的前提下,無(wú)任何運(yùn)行負(fù)擔(dān)地給程序嵌入了水印數(shù)據(jù),對(duì)程序性能的影響幾乎為0,且對(duì)程序的大小幾乎沒(méi)有任何影響。這是一種靜態(tài)水印嵌入方法,嵌入位置十分隱蔽,不易被攻擊者發(fā)現(xiàn),但雖然程序中方程式數(shù)目比較多,每個(gè)方程式可安全交換操作數(shù)目比較有限。因此,該方法的數(shù)據(jù)率不十分理想,且易受到混淆攻擊。若程序中代碼塊位置發(fā)生變動(dòng),提取出的水印信息就是亂序的,無(wú)法正確還原為初始水印。性能分析10.6軟件水印10.6.3動(dòng)態(tài)水印動(dòng)態(tài)軟件水印技術(shù)將水印信息隱藏在程序的執(zhí)行狀態(tài)中,而不是隱藏在程序的代碼或者數(shù)據(jù)中。動(dòng)態(tài)軟件水印根據(jù)特定的輸入序列I=I0...IK來(lái)嵌入水印信息,當(dāng)執(zhí)行完Ik時(shí),水印圖在內(nèi)存中生成,由于水印圖是動(dòng)態(tài)生成的,因此稱這種水印技術(shù)為動(dòng)態(tài)軟件水印技術(shù)。常用的動(dòng)態(tài)水印技術(shù)有以下幾種:EasterEgg水印、動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu)水印、執(zhí)行蹤跡水印。10.6軟件水印10.6.3動(dòng)態(tài)水印——EasterEgg水印根據(jù)特定的輸入序列嵌入水印信息,提取水印時(shí),當(dāng)執(zhí)行完這些特定的輸入時(shí),會(huì)顯示出嵌入的水印。嵌入的水印信息可以是圖片,或者版權(quán)者的姓名,公司的URL等。由于提取水印信息時(shí),EasterEgg水印暴露了所嵌水印的位置,只要發(fā)現(xiàn)了正確的輸入序列,使用標(biāo)準(zhǔn)的調(diào)試工具可以去除水印信息。10.6軟件水印10.6.3動(dòng)態(tài)水印——?jiǎng)討B(tài)數(shù)據(jù)結(jié)構(gòu)水印將水印信息隱藏在程序的數(shù)據(jù)結(jié)構(gòu)中,例如樹(shù)、鏈表、圖等。當(dāng)執(zhí)行特定的輸入序列時(shí),隱藏水印信息的數(shù)據(jù)結(jié)構(gòu)在堆中生成。提取水印時(shí)也需要在特定的輸入下執(zhí)行程序,當(dāng)輸入完畢后,通過(guò)檢測(cè)隱藏水印信息的數(shù)據(jù)結(jié)構(gòu)變量當(dāng)前值來(lái)進(jìn)行水印提取,提取時(shí)可以使用一個(gè)水印提取進(jìn)程,或者使用調(diào)試工具調(diào)試程序時(shí)查看變量的值。動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu)水印與EasterEgg相比有一個(gè)顯著的優(yōu)點(diǎn):當(dāng)輸入特定的序列時(shí),程序不會(huì)產(chǎn)生一個(gè)明顯的輸出,因此不容易找出水印嵌入的位置,從而避免引起攻擊者的注意。10.6軟件水印10.6.3動(dòng)態(tài)水印——執(zhí)行蹤跡水印通過(guò)在特定的輸入下執(zhí)行程序,對(duì)程序中指令的執(zhí)行順序或內(nèi)存地址走向進(jìn)行編碼生成水印。檢測(cè)水印時(shí),通過(guò)檢測(cè)地址流和操作碼順序的統(tǒng)計(jì)特性來(lái)完成?;煜D(zhuǎn)換以及代碼優(yōu)化等工具會(huì)削弱指令的執(zhí)行
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 外墻飾面磚專項(xiàng)工程施工方案
- 中風(fēng)恢復(fù)期中醫(yī)護(hù)理方案
- 2025-2030王在基因編輯技術(shù)行業(yè)市場(chǎng)現(xiàn)狀供需分析及投資評(píng)估規(guī)劃分析研究報(bào)告
- 2025-2030物聯(lián)網(wǎng)行業(yè)市場(chǎng)潛力挖掘及發(fā)展前景與投資方向研究報(bào)告
- 2025-2030物聯(lián)網(wǎng)智能家居系統(tǒng)互操作協(xié)議互聯(lián)技術(shù)拓展
- 2025-2030物聯(lián)網(wǎng)市場(chǎng)發(fā)展現(xiàn)狀分析行業(yè)趨勢(shì)創(chuàng)新前景預(yù)測(cè)報(bào)告
- 2025-2030物流配送網(wǎng)絡(luò)行業(yè)市場(chǎng)現(xiàn)狀運(yùn)營(yíng)分析及效率提升規(guī)劃分析研究報(bào)告
- 2025-2030物流行業(yè)市場(chǎng)發(fā)展現(xiàn)狀與投資前景分析報(bào)告
- 嘔吐患者護(hù)理流程及注意事項(xiàng)
- 人力資源績(jī)效提升方案與案例
- 鉗工個(gè)人實(shí)習(xí)總結(jié)
- 大健康養(yǎng)肝護(hù)肝針專題課件
- 物流公司托板管理制度
- 道路高程測(cè)量成果記錄表-自動(dòng)計(jì)算
- 關(guān)于醫(yī)院“十五五”發(fā)展規(guī)劃(2026-2030)
- DB31-T 1587-2025 城市軌道交通智能化運(yùn)營(yíng)技術(shù)規(guī)范
- 醫(yī)療護(hù)理操作評(píng)分細(xì)則
- 自考-經(jīng)濟(jì)思想史知識(shí)點(diǎn)大全
- 冬季駕駛車輛安全培訓(xùn)
- 醫(yī)學(xué)師承出師考核申請(qǐng)表
- 晚期癌癥疼痛控制課件
評(píng)論
0/150
提交評(píng)論