




已閱讀5頁(yè),還剩96頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 畢業(yè)設(shè)計(jì)源碼下載: 本文配套程序下載地址 : 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ()-大學(xué)生畢業(yè)設(shè)計(jì)站 ,免費(fèi)畢業(yè)設(shè)計(jì)論文 ,無(wú)憂無(wú)慮畢設(shè)網(wǎng) 大學(xué)生畢業(yè)設(shè)計(jì) ,出售各類畢業(yè)設(shè)計(jì)源碼 ,論文 ,程序源碼 ,網(wǎng)站源碼 ,免費(fèi)視頻教程 ,我們將竭誠(chéng)為您服務(wù)! 軟件 加密 技術(shù)及實(shí)現(xiàn) 雷 鵬 ( 桂林電子工業(yè)學(xué)院 計(jì)算機(jī)系 ) 摘 要 當(dāng)今盜版軟件的泛濫成災(zāi)幾乎已經(jīng)成為了我們中國(guó)民族軟件的災(zāi)難,為了防止軟件的非法復(fù)制、盜版,保護(hù)軟件開發(fā)商的利益,就必須對(duì)軟件進(jìn)行加密保護(hù)?,F(xiàn)在市面上有許多反盜版軟件,但這類軟件多是單機(jī)處理,并且只使用簡(jiǎn)單的加 密手段,很容易被解密者破解。 本文描述了一個(gè)通過(guò) Internet,集加密和電子注冊(cè)于一身的完善的軟件保護(hù)方案。該方案基于多種密碼學(xué)意義上可靠的算法,如對(duì)稱加密算法,散列算法,數(shù)字簽名,密鑰交換等等。通過(guò)對(duì) Windows 下 PE 可執(zhí)行文件的結(jié)構(gòu)及載入機(jī)制進(jìn)行深刻的剖析 , 巧妙的使用這些密碼學(xué)算法及多種反破解方案對(duì) PE 文件進(jìn)行加密保護(hù)。 在該方案的實(shí)現(xiàn)中,使用 CryptoAPI 中的數(shù)字簽名算法 RSA,加密算法RC2 和 RC4,散列算法 SHA,同時(shí)自己編寫了使用了 MD5 算法用于快速計(jì)算大量數(shù)據(jù)的摘要;網(wǎng)絡(luò)接口使用 WinSocket;編程語(yǔ)言選用匯編語(yǔ)言和 C+混合編程方式;反破解方案有檢測(cè)文件完整性、檢測(cè)代碼完整性、反跟蹤、反反匯編、反 Dump、代碼變形等等。 由于使用了可靠的密碼學(xué)算法,使軟件加密的強(qiáng)度大大提高;由于使用了 Internet 在線注冊(cè)方式,用戶使用也非常方便。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 畢業(yè)設(shè)計(jì)源碼下載: 關(guān)鍵詞 加密 ;數(shù)字簽名 ;散列;反跟蹤 ;電子注冊(cè) 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 畢業(yè)設(shè)計(jì)源碼下載: Software Protection technique and its realization LEI Peng ( GuiLin Institute of Electronic Technology . The Department of Computing ) Abstract The flooding of pirate software has been a calamity of our national software industry . In order to prevent software from pirate , and protect the profit of the software developer , they must encrypt their software to get a protection . There are several software protection tools in the market currently , but these tools were standalone nine tenths , and they only used simple encryption algorithms , so they could be cracked easily by the crackers . This thesis describes a perfect software encryption and protection scheme which integrate the encryption and electronic register . This scheme is based on multiple reliable cryptographic algorithms such as symmetric encryption algorithm , digital signature , hashing and key exchange . The PE file format (Portable Executable File Format) and its loading mechanism under Windows are dissected thoroughly in this thesis . Then these cryptographic algorithms and several anti-crack method are used gracefully to encrypt and protect the PE file . Within the realization of this scheme , the RSA digital signature algorithm , RC2 and RC4 encryption algorithm , SHA hasing algorithm etc 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 畢業(yè)設(shè)計(jì)源碼下載: in MicroSoft CryptoAPI are used . In order to increase the performace of caculate the digest of large number of data, MD5 hashing algorithm was rewritten . WinSocket API is used as the network interface . The blend of C+ and assembly are used for easily contoling the bottom layer of the system and simplify the programming . The anti-crack method consits the integralization of the file checking , the integralization of the code checking , and anti-debug , anti-disassembly , anti-dump and code metamorphose etc . The reliable cyrpto algorithms guarantee the crypto strength . As a result of online register , the retail users and the software developers get convenience . Key words Encrypt ; Digital Signature ; Hashing ; Anti-Debug ; Electronic Register 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 目 錄 1 概述 . 1 2 密碼學(xué)簡(jiǎn)介 2.1 概念 . 3 2.2 對(duì)稱密碼算法 . 6 2.3 公開密碼算法 . 6 2.4 單向散列函數(shù) . 7 2.5 數(shù)字簽名 . 8 3 Windows 環(huán)境下 PE 文件簡(jiǎn)介 3.1 WIN32 與 PE 基本概念 . 10 3.2 PE 首部 . 12 3.3 PE 文件的導(dǎo)入表 . 14 4 當(dāng)前流行的一些軟件保護(hù)技術(shù) 4.1 序列號(hào)保護(hù) . 21 4.2 時(shí)間限制 . 22 4.3 Key File 保護(hù) . 23 4.4 CD-check . 23 4.5 反跟蹤技術(shù)( Anti-Debug) . 23 4.6 反反匯編技術(shù)( Anti- Disassmbly) . 24 4.7 軟件狗 . 25 4.8 Vbox 保護(hù)技術(shù) . 25 4.9 SalesAgent 保護(hù)技術(shù) . 26 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 4.10 SecuROM 保護(hù)技術(shù) . 26 4.11 軟盤加密 . 26 4.12 將軟件與機(jī)器硬件信息結(jié)合 . 26 4.13 加殼 . 27 5 該軟件的設(shè)計(jì)思想 5.1 傳統(tǒng)保護(hù)的不足 . 28 5.2 網(wǎng)絡(luò)的流行 . 29 5.3 我的方案 . 29 5.4 該方案的可行性分析 . 29 6 該軟件的整體構(gòu)架、開發(fā)工具及方法 6.1 需求分析 . 32 6.2 整體框架 . 35 6.3 各取所長(zhǎng)(匯編與 C/C+ 各取所長(zhǎng)) . 35 6.4 C/C+ 與匯編語(yǔ)言混合編程時(shí)的互調(diào)協(xié)議 . 36 6.5 該軟件中各模塊對(duì)語(yǔ)言特性的限制及解決方法 . 40 6.6 C/C+ 和匯編語(yǔ)言的預(yù)編譯 . 45 7 該軟件的實(shí)現(xiàn)及技術(shù)細(xì)節(jié) 7.1 CryptoAPI 簡(jiǎn)介 . 47 7.2 幾個(gè)公共函數(shù)和宏 . 49 7.3 模塊共用的結(jié)構(gòu)體定義 . 54 7.4 Shield 模塊 . 56 7.4.1 殼程序中 API 和庫(kù)函數(shù)的處理 . 59 7.4.2 殼程序主體 . 62 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 7.4.3 加密殼程序 . 63 7.4.4 運(yùn)行中修改自 身代碼 . 64 7.4.5 代碼散列校驗(yàn) . 64 7.4.6 跳轉(zhuǎn)到客戶程序入口 . 65 7.4.7 載入并銷毀 Client 程序的 ImportTable . 66 7.4.8 自毀殼程序代碼 . 69 7.4.9 編譯方法 . 70 7.5 Merge 模塊 . 71 7.6 Register 模塊 . 76 7.7 Server 模塊 . 77 7.8 軟件授權(quán)協(xié)議的實(shí)現(xiàn) . 78 7.9 Client 的代碼(數(shù)據(jù))的加密 /解密流程圖示 . 82 8 使用說(shuō)明及演示 8.1 使用說(shuō)明 . 83 8.2 演示及效果 . 83 9 限制、不足與展望 9.1 使用該軟件的限制 . 86 9.2 該軟件的不足 . 86 9.3 對(duì)該軟件的展望 . 87 10 結(jié)束語(yǔ) 10.1 總結(jié) . 91 10.2 致謝 . 91 參考文獻(xiàn) . 92 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 1 - 1 概述 我引用應(yīng)用密碼學(xué)作者 Bruce Schneier的話: 世界上有兩種密碼:一種是防止你的小妹妹看你的文件;另一種是防止當(dāng)局者閱讀你的文件資料。 如果把一封信鎖在保險(xiǎn)柜中,把保險(xiǎn)柜藏在紐約的某個(gè)地方,然后告訴你去看這封信。這并不是安全,而是隱藏。相反,如果把一封信鎖在保險(xiǎn)柜中,然后把保險(xiǎn)柜及其設(shè)計(jì)規(guī)范和許多同樣的保險(xiǎn)柜給你,以便你和世界上最好的開 保險(xiǎn)柜的專家能夠研究鎖的裝置。而你還是無(wú)法打開保險(xiǎn)柜去讀這封信,這樣才是安全的。 意思是說(shuō),一個(gè)密碼系統(tǒng)的安全性只在于密鑰的保密性,而不在算法的保密性。 對(duì)純數(shù)據(jù)的加密的確是這樣。對(duì)于你不愿意讓他看到這些數(shù)據(jù)(數(shù)據(jù)的明文)的人, 用可靠的加密算法,只要破解者不知道被加密數(shù)據(jù)的密碼 , 他就不可解讀這些數(shù)據(jù) 。 但是, 軟件的加密不同于數(shù)據(jù)的加密,它只能是 “ 隱藏 ” 。不管你愿意不愿意讓他(合法用戶,或 Cracker)看見(jiàn)這些數(shù)據(jù)(軟件的明文),軟件最終總要在機(jī)器上運(yùn)行,對(duì)機(jī)器,它就必須是明文。既然機(jī)器可以 “ 看見(jiàn) ” 這些明 文,那么 Cracker,通過(guò)一些技術(shù),也可以看到這些明文。 于是,從理論上,任何軟件加密技術(shù)都可以破解。只是破解的難度不同而已。有的要讓最高明的 Cracker 忙上幾個(gè)月,有的可能不費(fèi)吹灰之力,就被破解了。 所以,反盜版的任務(wù)(技術(shù)上的反盜版,而非行政上的反盜版)就是增加 Cracker 的破解難度。讓他們花費(fèi)在破解軟件上的成本,比他破解這個(gè)軟件的獲利還要高。無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 2 - 這樣 Cracker 的破解變得毫無(wú)意義 誰(shuí)會(huì)花比正版軟件更多的錢去買盜版軟件 ? 然而,要做到 “ 難破解 ” ,何嘗容易? Sony 曾 宣稱的超強(qiáng)反 盜版( Key 2 Audio音樂(lè) CD 反盜版),使用了很尖端的技術(shù),然而最近卻被一枝記號(hào)筆破解了 ,成為人們的飯后笑料 ! 所以,很多看上去很好的技術(shù),可能在 Cracker 面前的確不堪一擊。就像馬其諾防線一樣, Cracker 不從你的防線入手,而是 “ 繞道 ” 。這樣,讓你的反盜版技術(shù)在你做夢(mèng)也想不到的地方被 Crack 了。 為什么會(huì)這樣呢 ?歸根到底是因?yàn)檐浖跈C(jī)器上運(yùn)行,并且軟件和機(jī)器是分離的 這一點(diǎn)是關(guān)鍵,如果軟件和硬件完全綁定,不能分離,是可以做到象 IDEA 之類幾乎不可破解的系統(tǒng)的。這將在后面談傳 統(tǒng)軟件保護(hù)技術(shù)時(shí)詳細(xì)說(shuō)明。 對(duì)我的這個(gè)解決方案,我 不能保證 Crack 高手在幾天之內(nèi)不能破解它,我 只能說(shuō):“ 在這個(gè)軟件中,我盡量堵住了當(dāng)前破解者普遍使用的方法以及 “ 我想得到 ” 的可能的缺口。 ” 但是我相信,傾注了我三個(gè)月心血的反盜版軟件,決不是一個(gè) “ 玩具式 ” 的反盜版軟件。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 3 - 2 密碼學(xué)簡(jiǎn)介 2.1 概念 (1) 發(fā)送者和接收者 假設(shè)發(fā)送者想發(fā)送消息給接收者,且想安全地發(fā)送信息:她想確信偷聽者不能閱讀發(fā)送的消息。 (2) 消息和加密 消息被稱為明文。用某種方法偽裝消息以隱藏它的內(nèi)容的過(guò)程稱為加密,加了密的消息稱為密文,而把密文轉(zhuǎn) 變?yōu)槊魑牡倪^(guò)程稱為解密。圖 2-1表明了這個(gè)過(guò)程。 加密 解密明文 密文 原 始 明 文 圖 2-1 加密和解密 明文用 M(消息)或 P(明文)表示,它可能是比特流(文本文件、位圖、數(shù)字化的語(yǔ)音流或數(shù)字化的視頻圖像)。至于涉及到計(jì)算機(jī), P是簡(jiǎn)單 的 二進(jìn)制數(shù)據(jù)。明文可被傳送或存儲(chǔ),無(wú)論在哪種情況, M指待加密的消息。 密文用 C 表示,它也是二進(jìn)制數(shù)據(jù),有時(shí)和 M 一樣大,有時(shí)稍大(通過(guò)壓縮和加密的結(jié)合, C 有可能比 P 小些。然而,單單加密通常達(dá)不到這一點(diǎn))。加密函數(shù) E作用于 M得到密文 C,用數(shù)學(xué)表示為: E( M) =C. 相反地,解密函數(shù) D作用于 C產(chǎn)生 M D( C) =M. 先加密后再解密消息,原始的明文將恢復(fù)出來(lái),下面的等式必須成立: D( E( M) =M 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 4 - (3) 鑒別、完整性和抗抵賴 除了提供機(jī)密性外,密碼學(xué)通常有其它的作用: . (a) 鑒別 消息的接收者應(yīng)該能夠確認(rèn)消息的來(lái)源;入侵者不可能偽裝成他人。 (b) 完整性 檢驗(yàn) 消息的接收者應(yīng)該能夠驗(yàn)證在傳送過(guò)程中消息沒(méi)有被修改;入侵者不可能用假消息代替合法消息。 (c) 抗抵賴 發(fā)送者事后不可能虛假地否認(rèn)他發(fā)送的消息。 (4) 算法和密鑰 密碼算法也叫密碼,是用于 加密和解密的數(shù)學(xué)函數(shù)。(通常情況下,有兩個(gè)相關(guān)的函數(shù):一個(gè)用作加密,另一個(gè)用作解密) 如果算法的保密性是基于保持算法的秘密,這種算法稱為受限制的算法。受限制的算法具有歷史意義,但按現(xiàn)在的標(biāo)準(zhǔn),它們的保密性已遠(yuǎn)遠(yuǎn)不夠。大的或經(jīng)常變換的用戶組織不能使用它們,因?yàn)槊坑幸粋€(gè)用戶離開這個(gè)組織,其它的用戶就必須改換另外不同的算法。如果有人無(wú)意暴露了這個(gè)秘密,所有人都必須改變他們的算法。 更糟的是,受限制的密碼算法不可能進(jìn)行質(zhì)量控制或標(biāo)準(zhǔn)化。每個(gè)用戶組織必須有他們自己的唯一算法。這樣的組織不可能采用流行的硬件或軟件產(chǎn)品。 但竊聽者卻可以買到這些流行產(chǎn)品并學(xué)習(xí)算法,于是用戶不得不自己編寫算法并予以實(shí)現(xiàn),如果這個(gè)組織中沒(méi)有好的密碼學(xué)家,那么他們就無(wú)法知道他們是否擁有安全的算法。 盡管有這些主要缺陷,受限制的算法對(duì)低密級(jí)的應(yīng)用來(lái)說(shuō)還是很流行的,用戶或者沒(méi)有認(rèn)識(shí)到或者不在乎他們系統(tǒng)中內(nèi)在的問(wèn)題。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 5 - 現(xiàn)代密碼學(xué)用密鑰解決了這個(gè)問(wèn)題,密鑰用 K 表示。 K 可以是很多數(shù)值里的任意值。密鑰 K 的可能值的范圍叫做密鑰空間。加密和解密運(yùn)算都使用這個(gè)密鑰(即運(yùn)算都依賴于密鑰,并用 K作為下標(biāo)表示),這樣,加 /解密函數(shù)現(xiàn)在變成: EK(M)=C DK(C)=M. 這些函數(shù)具有下面的特性(見(jiàn)圖 2-2): DK( EK( M) =M. 加密 解密明文 密文原始明文密鑰 密鑰 圖 2-2 使用一個(gè)密鑰的加 /解密 加密 解密明文 密文原始明文加密密鑰解密密鑰 圖 2-3 使用兩個(gè)密鑰的加 /解密 有些算法使用不同的加密密鑰和解密密鑰(見(jiàn)圖 2-3),也就是說(shuō)加密密鑰 K1與相應(yīng)的解密密鑰 K2不同,在這種情況下: EK1(M)=C DK2(C)=M DK2 (EK1(M)=M 所有這些算法的安全性都基于密鑰的安全性;而不是基于算法的細(xì)節(jié)的安全性。這就意 味著算法可以公開,也可以被分析,可以大量生產(chǎn)使用算法的產(chǎn)品,即使偷無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 6 - 聽者知道你的算法也沒(méi)有關(guān)系;如果他不知道你使用的具體密鑰,他就不可能閱讀你的消息。 密碼系統(tǒng)由算法、以及所有可能的明文、密文和密鑰組成的。 基于密鑰的算法通常有兩類:對(duì)稱算法和公開密鑰算法。下面將分別介紹: 2.2 對(duì)稱密碼算法 對(duì)稱算法有時(shí)又叫傳統(tǒng)密碼算法,就是加密密鑰能夠從解密密鑰中推算出來(lái),反過(guò)來(lái)也成立。在大多數(shù)對(duì)稱算法中,加 /解密密鑰是相同的。這些算法也叫秘密密鑰算法或單密鑰算法,它要求發(fā)送者和接收者在安全通信之前,商定一個(gè)密鑰。對(duì)稱算法的 安全性依賴于密鑰,泄漏密鑰就意味著任何人都能對(duì)消息進(jìn)行加 /解密。只要通信需要保密,密鑰就必須保密。 對(duì)稱算法的加密和解密表示為: EK( M) =C DK( C) =M 對(duì)稱算法可分為兩類。一次只對(duì)明文中的單個(gè)比特(有時(shí)對(duì)字節(jié))運(yùn)算的算法稱為序列算法或序列密碼。另一類算法是對(duì)明文的一組比特亞行運(yùn)算,這些比特組稱為分組,相應(yīng)的算法稱為分組算法或分組密碼。現(xiàn)代計(jì)算機(jī)密碼算法的典型分組長(zhǎng)度為 64比特 這個(gè)長(zhǎng)度大到足以防止分析破譯,但又小到足以方便使用(在計(jì)算機(jī)出現(xiàn)前,算法普遍地每次只對(duì)明文的一個(gè)字符運(yùn)算,可認(rèn)為是序列密 碼對(duì)字符序列的運(yùn)算)。 2.3 公開密碼算法 公開密鑰算法(也叫非對(duì)稱算法)是這樣設(shè)計(jì)的:用作加密的密鑰不同于用作解密的密鑰,而且解密密鑰不能根據(jù)加密密鑰計(jì)算出來(lái)(至少在合理假定的長(zhǎng)時(shí)間內(nèi))。之所以叫做公開密鑰算法,是因?yàn)榧用苊荑€能夠公開,即陌生者能用加密密鑰加密信息,但只有用相應(yīng)的解密密鑰才能解密信息。在這些系統(tǒng)中,加密密鑰叫做無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 7 - 公開密鑰(簡(jiǎn)稱公鑰),解密密鑰叫做私人密鑰(簡(jiǎn)稱私鑰)。私人密鑰有時(shí)也叫秘密密鑰。為了避免與對(duì)稱算法混淆,此處不用秘密密鑰這個(gè)名字。 用公開密鑰 K加密表示為 EK(M)=C. 雖然公開密鑰 和私人密鑰是不同的,但用相應(yīng)的私人密鑰解密可表示為: DK(C)=M 有時(shí)消息用私人密鑰加密而用公開密鑰解密,這用于數(shù)字簽名(后面將詳細(xì)介紹),盡管可能產(chǎn)生混淆,但這些運(yùn)算可分別表示為: EK(M)=C DK(C)=M 當(dāng)前的公開密碼算法的速度,比起對(duì)稱密碼算法,要慢的多,這使得公開密碼算法在大數(shù)據(jù)量的加密中應(yīng)用有限。 2.4 單向散列函數(shù) 單向散列函數(shù) H(M) 作用于一個(gè)任意長(zhǎng)度的消息 M,它返回一個(gè)固定長(zhǎng)度的散列值 h,其中 h 的長(zhǎng)度為 m 。 輸入為任意長(zhǎng)度且輸出為固定長(zhǎng)度的函數(shù)有很多種,但單向散 列函數(shù)還有使其單向的其它特性: (1) 給定 M ,很容易計(jì)算 h ; (2) 給定 h ,根據(jù) H(M) = h 計(jì)算 M 很難 ; (3) 給定 M ,要找到另一個(gè)消息 M 并滿足 H(M) = H(M ) 很難。 在許多應(yīng)用中,僅有單向性是不夠的,還需要稱之為 “ 抗碰撞 ” 的條件: 要找出兩個(gè)隨機(jī)的消息 M 和 M ,使 H(M) = H(M) 滿足很難。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 8 - 由于散列函數(shù)的這些特性,由于公開密碼算法的計(jì)算速度往往很慢,所以,在一些密碼協(xié)議中,它可以作為一個(gè)消息 M 的摘要,代替原始消息 M,讓發(fā)送者為 H(M) 簽名而不是對(duì) M 簽名 。 如 SHA 散列算法用于數(shù)字簽名協(xié)議 DSA中。 2.5 數(shù)字簽名 提到數(shù)字簽名就離不開公開密碼系統(tǒng)和散列技術(shù)。 有幾種公鑰算法能用作數(shù)字簽名。在一些算法中,例如 RSA,公鑰或者私鑰都可用作加密。用你的私鑰加密文件,你就擁有安全的數(shù)字簽名。在其它情況下,如DSA,算法便區(qū)分開來(lái)了 數(shù)字簽名算法不能用于加密。這種思想首先由 Diffie和 Hellman提出 。 基本協(xié)議是簡(jiǎn)單的 : (1) A 用她的私鑰對(duì)文件加密,從而對(duì)文件簽名。 (2) A 將簽名的文件傳給 B。 (3) B用 A的公鑰解密文件,從而驗(yàn)證簽名。 這個(gè)協(xié)議中,只需要證明 A的公鑰的確是她的。如果 B不能完成第( 3)步,那么他知道簽名是無(wú)效的。 這個(gè)協(xié)議也滿足以下特征: (1) 簽名是可信的。當(dāng) B用 A的公鑰驗(yàn)證信息時(shí),他知道是由 A簽名的。 (2) 簽名是不可偽造的。只有 A知道她的私鑰。 (3) 簽名是不可重用的。簽名是文件的函數(shù),并且不可能轉(zhuǎn)換成另外的文件。 (4) 被簽名的文件是不可改變的。如果文件有任何改變,文件就不可能用 A 的公鑰驗(yàn)證。 (5) 簽名是不可抵賴的。 B不用 A 的幫助就能驗(yàn)證 A的簽名。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 9 - 在實(shí)際應(yīng)用中,因?yàn)楣?密碼算法的速度太慢,簽名者往往是對(duì)消息的散列簽名而不是對(duì)消息本身簽名。這樣做并不會(huì)降低簽名的可信性。 本章僅對(duì)密碼學(xué)進(jìn)行了一些簡(jiǎn)要的介紹,更多的請(qǐng)參閱參考文獻(xiàn) 1。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 10 - 3 Windows 環(huán)境下 PE 文件簡(jiǎn)介 3.1 WIN32 與 PE 基本概念 只要用過(guò)電腦的人都知道什么是 Windows, Windows95 已經(jīng)是過(guò)時(shí)的昨日黃花了, Windows98 也已 推出 將近四年了。 2000 年又推出了 Windows2000,今年又推出了 WindowsXP,微軟的操作系統(tǒng)更新速度是如此的快,以至于昨天還在使用的東西,在 今天看來(lái)就已經(jīng)過(guò)時(shí)了。 Windows98 以后,微軟傳言不在推出 9x 內(nèi)核的操作系統(tǒng),但是 2000 年下半年卻正式推出了 WindowsMillennium,簡(jiǎn)稱 Win.Me 。然而從 WindowsXP 的推出,可以斷言,微軟不會(huì)在升級(jí) Win9x 操作系統(tǒng)了。 Windows2000 和 WindowsXP 都是基于 NT 內(nèi)核的。 所有這些操作系統(tǒng)都使用一種“可移植可執(zhí)行文件格式”( Portable Executable File Format),簡(jiǎn)稱 PE文件格式。 下面簡(jiǎn)短介紹一下 PE 文件的一 些概念。詳細(xì)內(nèi)容請(qǐng)參閱參考文獻(xiàn) 14。 Windows NT 繼承了 VAX VMS 和 UNIX 的傳統(tǒng)。許多 Windows NT 的創(chuàng)始人在進(jìn)入微軟前都在這些平臺(tái)上進(jìn)行設(shè)計(jì)和編碼。當(dāng)他們開始設(shè)計(jì) Windows NT 時(shí),很自然的,為了最小化 工程的 啟動(dòng)時(shí)間,他們會(huì)使用以前寫好的并且已經(jīng)測(cè)試過(guò)的工具。用這些工具生成并且工作的可執(zhí)行 文件 和 OBJ 文件格式叫做 COFF( Common Object File Format 的首字母縮寫)。 COFF 的年齡不超過(guò)八年。 COFF 本身是一個(gè) 很 好的起點(diǎn) ,但是需要擴(kuò)展到一個(gè)現(xiàn)代操作系統(tǒng)如 Windows 95 和 Windows NT 就要進(jìn)行一些更新 。 其 結(jié)果就是 產(chǎn)生了 ( PE格式)可移植可執(zhí)行文件格式。它被稱為 “ 可移植的 ” 是因?yàn)樵谒衅脚_(tái)(如 x86,Alpha,MIPS 等等)上實(shí)現(xiàn)的 WindowsNT 都使用相同的可執(zhí)行文件格式。當(dāng)然了,也有許多不同的東西如二進(jìn)制代碼的 CPU 指令。重要的是操作系統(tǒng)的裝入器和程序設(shè)計(jì)工具不需要為任何一種 CPU完全重寫就能達(dá)到目的。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 11 - 關(guān)于 PE文件最重要的是,磁盤上的可執(zhí)行文件和它被 WINDOWS載入 內(nèi)存之后 ( PE文件載入內(nèi)存之 后稱為 PE映像) 是非常相像的(如圖 3-1)。 WINDOWS載入器不必為從磁盤上載入一個(gè)文件而辛辛苦苦創(chuàng)建一個(gè)進(jìn)程。載入器使用內(nèi)存映射文件機(jī)制把文件中相似的塊映射到虛擬空間中。 構(gòu)造式的進(jìn)行分析 ,一個(gè) PE 文件類似一個(gè)預(yù)制的屋子。它本質(zhì)上開始于這樣一個(gè)空間,這個(gè)空間后面有幾個(gè)把它連到其余空間的機(jī)件(就是說(shuō),把它聯(lián)系到它的 DLL 上,等等)。這對(duì) PE 格式的 DLL式一樣容易應(yīng)用的。一旦這個(gè)模塊被載入, Windows 就可以有效的把它和其它內(nèi)存映射文件同等對(duì)待。 圖 3-1 PE文件和 PE 映像的布局很相似 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 12 - 對(duì) Win32 來(lái)講,模塊所使用的所有代碼,數(shù)據(jù),資源,導(dǎo)入表,和其它需要的模塊數(shù)據(jù)結(jié)構(gòu)都在一個(gè)連續(xù)的內(nèi)存塊中。在這種形勢(shì)下,你只需要知道載入器把可執(zhí)行文件映射到了什么地方 就可以了 。通過(guò)作為映像的一部分的指針,你可以很容易的找到這個(gè)模塊所有不同的塊。 另一個(gè)你需要知道的概念是相對(duì)虛擬地址( RVA)。 PE文件中的許多域都用術(shù)語(yǔ)RVA 來(lái)指定。一個(gè) RVA 只是一些項(xiàng)目相對(duì)于文件映射到內(nèi)存的偏移。比如說(shuō),載入器把一個(gè)文件映射到虛擬地址 0x10000 開始的內(nèi)存塊。如果映像中 一個(gè) 實(shí)際的表的首址是 0x10464,那么它的 RVA就是 0x464。 (虛擬地址 0x10464)(基地址 0x10000) RVA 0x00464 為了把一個(gè) RVA 轉(zhuǎn)化成一個(gè)有用的指針,只需要把 RVA 值加到模塊的基地址上即可?;刂肥?EXE 和 DLL 內(nèi)存映射文件的 基址 , 這個(gè)基址 在 Win32 中這是一個(gè)很重要的概念。為了方便起見(jiàn), WindowsNT 和 Windows9x用模塊的基址作為這個(gè)模塊的實(shí)例句柄( HINSTANCE)。可以對(duì)任何 DLL 調(diào)用 GetModuleHandle(dllname)得到一個(gè)指針去訪問(wèn)它的組件。如果 dllname 為 NULL,則得到執(zhí) 行體自己的模塊句柄。這是非常有用的 ,如通常編譯器產(chǎn)生的啟動(dòng)代碼將取得這個(gè)句柄并將它作為一個(gè)參數(shù) hInstance傳給 WinMain 。 3.2 PE首部 和其它可執(zhí)行文件格式一樣, PE 文件在眾所周知的地方有一些定義文件其余部分面貌的域。首部就包含這樣象代碼和數(shù)據(jù)的位置和尺寸的地方,操作系統(tǒng)要對(duì)它進(jìn)行干預(yù),比如初始堆棧大小,和其它重要的塊的信息。和微軟其它 執(zhí)行體的 格式相比, PE 格式的執(zhí)行體的 主要的首部不是在文件的最開始。典型的 PE 文件最開始的數(shù)百個(gè)字節(jié)被 DOS 殘留部分占用。這個(gè)殘留部分是一個(gè)打印如 “ 這個(gè)程序不能在DOS 下運(yùn)行! ” 這類信息的小程序。所以,你在一個(gè)不支持 Win32 的系統(tǒng)中運(yùn)行這個(gè)程序 ,會(huì) 得到這類錯(cuò)誤信息。當(dāng)載入器把一個(gè) Win32 程序映射到內(nèi)存,這個(gè)映射無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 13 - 文件的第一個(gè)字節(jié)對(duì)應(yīng)于 DOS 殘留部分的第一個(gè)字節(jié) ,這 是無(wú)疑的。 于是, 和你啟動(dòng)的任一個(gè)基于 Win32 的程序一起,都有一個(gè)基于 DOS的程序連帶被載入。 和微軟的其它可執(zhí)行格式一樣,你可以通過(guò)查找它的起始偏移來(lái)得到真實(shí)首部,這個(gè)偏移放在 DOS 殘留首部中。 WINNT.H 頭文件包含了 DOS 殘留程序的數(shù)據(jù)結(jié)構(gòu)定義 (注) ,使得很容易找到 PE 首部的起始位置。 e_lfanew 域是 PE 真實(shí)首部的偏移。為了得到 PE 首部在內(nèi)存中的指針,只需要把這個(gè)值加到映像的基址上即可。 / 忽略類型轉(zhuǎn)化和指針轉(zhuǎn)化 pNTHeader = dosHeader + dosHeader-e_lfanew; 注:為了不失簡(jiǎn)潔,這里未列出這些結(jié)構(gòu)體的完整定義就直接引用,這里直接引用的結(jié)構(gòu)體其定義都在 winnt.h 中,建議讀者在讀本章時(shí)參考 Winnt.h 。 一旦你有了 PE 主首部的指針,游戲就可以開始了! PE 主首部是一個(gè)IMAGE_NT_HEADERS 的結(jié)構(gòu),在 WINNT.H 中定義。這個(gè)結(jié)構(gòu)由一個(gè)雙字( DWORD)和兩個(gè)子結(jié)構(gòu)組成,布局如下: DWORD Signature; / 標(biāo)志域 IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; 標(biāo)志域用 ASCII表示就是 “PE 00” 。 標(biāo)志域 之 后的是結(jié)構(gòu) IMAGE_FILE_HEADER 。這個(gè)域只包含這個(gè)文件最基本的信息。這個(gè)結(jié)構(gòu) 看上去 并未從它的原始 COFF 實(shí)現(xiàn)更改過(guò)。除了是 PE 首部的一部分,它還表現(xiàn)在微軟 Win32編譯器生成的 COFF OBJ 文件的最開始 部分。 這個(gè)部分的詳細(xì)說(shuō)明請(qǐng)參閱參考文獻(xiàn) 14(本人已翻譯為中文)。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 14 - 3.3 PE文件的導(dǎo)入表 因?yàn)閷?dǎo)入表在該軟件的設(shè)計(jì)中很關(guān)鍵,后面殼程序?qū)氡淼臉?gòu)建,對(duì)客戶程序?qū)氡淼妮d入等,都牽涉到導(dǎo)入表 。所以,在這里有必要說(shuō)明一下,更詳細(xì)的說(shuō)明請(qǐng)參閱參考文獻(xiàn) 141516。 導(dǎo)入表,簡(jiǎn)單的說(shuō),導(dǎo)入表的作用相當(dāng)于 DOS 的系統(tǒng)中斷功能。兩者都是操作系統(tǒng) API 。只不過(guò) DOS 中斷不需要操作系統(tǒng)在載入每個(gè)執(zhí)行體時(shí)填入 API 的實(shí)際地址,并且,導(dǎo)入表還可以導(dǎo)入除操作系統(tǒng) API 之外的其它模塊中的函數(shù)。 在一 個(gè) PE 文件中,當(dāng)你調(diào)用另一模塊中 的 一個(gè)函數(shù)時(shí)(比如在 USER32.DLL 中的 GetMessage ),編譯器產(chǎn)生的 CALL 指令并不把控制直接轉(zhuǎn)移到在 DLL中的這個(gè)函數(shù)。代替的, CALL 指令把把控制轉(zhuǎn)移到一個(gè)也在 .text 中的 JMP DWORD PTR XXXXXXXX 指令處(如圖 3-2)。 這個(gè) JMP 指令通過(guò)一個(gè)在導(dǎo)入表中的 DWORD 變量間接的轉(zhuǎn)移控制。 導(dǎo)入表的這個(gè) DWORD包含操作系統(tǒng)函數(shù)入口的實(shí)際地址。為什么 DLL 調(diào)用用這種方式來(lái)實(shí)現(xiàn)呢?原來(lái),通過(guò)一個(gè)位置傳送所有的對(duì)一個(gè)給定的 DLL 函數(shù)的調(diào)用,載入器不需要改變每個(gè)調(diào)用 DLL的指令。所有的 PE載入器必須做的是把目標(biāo)函數(shù)的正確地址放到導(dǎo)入表的一個(gè) DWORD 中。不需要改變?nèi)魏?call指令本身。 如果你想通過(guò)函數(shù)指針調(diào)用一個(gè)函數(shù),事情也會(huì)如你所預(yù)料的一樣。但是,如果你想讀取 GetMessage 開始的字節(jié),你將不能如愿。后面講到反 API 斷點(diǎn)時(shí)會(huì)詳細(xì)說(shuō)明。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 15 - 圖 3-2 一個(gè)導(dǎo)入函數(shù)調(diào)用的圖示 前面描述了函數(shù)調(diào)用怎樣到一個(gè)外部 DLL 中而不直接調(diào)用這個(gè) DLL 。代替的,在執(zhí)行體中的 .text 塊中(如果你用 Borland C+ 就是 .icode 塊), CALL 指令到達(dá)一 個(gè) JMP DWORD PTR XXXXXXXX 指令處。 JMP 指令尋找的地址把控制轉(zhuǎn)移到實(shí)際的目標(biāo)地址。 PE 文件的導(dǎo)入表會(huì)包含一些必要的信息,這些信息是載入器用來(lái)確定目標(biāo)函數(shù)的地址以及在執(zhí)行體映像中修正他們的。 導(dǎo)入表開始于一個(gè) IMAGE_IMPORT_DESCRIPTOR數(shù)組。每個(gè) DLL都有一個(gè) PE文件隱含鏈接上的 IMAGE_IMPORT_DESCRIPTOR 。沒(méi)有指定這個(gè)數(shù)組中結(jié)構(gòu)的數(shù)目的域。代替的,這個(gè)數(shù)組的最后一個(gè)元素是一個(gè)全 NULL 的 IMAGE_IMPORT_DESCRIPTOR 。IMAGE_IMPORT_DESCRIPTOR 的格式顯示在表 3-1 。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 16 - 表 3-1 IMAGE_IMPORT_DESCRIPTOR 的格式 DWORD Characteristics 在一個(gè)時(shí)刻,這可能已是一個(gè)標(biāo)志集。然而,微軟改變了它的涵義并不 再糊涂地升級(jí) WINNT.H 。這個(gè)域?qū)嶋H上是一個(gè)指向指針數(shù)組的偏移( RVA)。其中每個(gè)指針都指向一個(gè) IMAGE_IMPORT_BY_NAME 結(jié)構(gòu)?,F(xiàn)在這個(gè)域的涵義是 OriginalFirstThunk 。 DWORD TimeDateStamp 表示 這個(gè)文件的創(chuàng)建時(shí)間。 DWORD ForwarderChain 這個(gè)域聯(lián)系到前向鏈。前向鏈包括一個(gè) DLL函數(shù)向另一個(gè) DLL轉(zhuǎn)送引用。比如,在 WindowsNT中, NTDLL.DLL就出現(xiàn)了的一些前向的它向 KERNEL32.DLL導(dǎo)出的函數(shù)。應(yīng)用程序可 能以為它調(diào)用的是 NTDLL.DLL 中的函數(shù),但它最終調(diào)用的是KERNEL32.DLL中的函數(shù)。這個(gè)域還包含一個(gè) FirstThunk數(shù)組的索引(即刻描述)。用這個(gè)域索引的函數(shù)會(huì)前向引用到另一個(gè) DLL 。不幸的是,函數(shù)怎樣前向引用的格式?jīng)]有文檔,并且前向函數(shù)的例子也很難找。 DWORD Name 這是導(dǎo)入 DLL 的名字,指向以 NULL 結(jié)尾的 ASCII 字符串。通用例子是KERNEL32.DLL和 USER32.DLL 。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 17 - PIMAGE_THUNK_DATA FirstThunk 這個(gè)域是指向 IMAGE_THUNK_DATA 聯(lián)合的偏移( RVA)。幾乎在任何情況下,這個(gè)域都解釋為一個(gè)指向的 IMAGE_IMPORT_BY_NAME結(jié)構(gòu)的指針。如果這個(gè)域不是這些指針中的一個(gè),那它就被當(dāng)作一個(gè)將從這個(gè)被導(dǎo)入的 DLL 的導(dǎo)出序數(shù)值。如果你實(shí)際上可以從序數(shù)導(dǎo)入一個(gè)函數(shù)而不是從名字導(dǎo)入,從文檔看,這是很含糊的。 IMAGE_IMPORT_DESCRIPTOR 的一個(gè)重要部分是導(dǎo)入的 DLL 的名字和兩個(gè)IMAGE_IMPORT_BY_NAME指針數(shù)組。在 EXE文件中,這兩個(gè)數(shù)組(由 Characteristics域和 FirstThunk 域指向)是相互平行的,都是以 NULL 指針作為數(shù)組的最后一個(gè)元素。兩個(gè)數(shù)組中的指針都指向 IMAGE_IMPORT_BY_NAME 結(jié)構(gòu)。圖 3-3 顯示了這種布局。 圖 3-3 導(dǎo)入表 中 一個(gè)項(xiàng) 的 結(jié)構(gòu)圖示 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 18 - PE 文件導(dǎo)入表 中 的每一個(gè)函數(shù)有一個(gè) IMAGE_IMPORT_BY_NAME 結(jié) 構(gòu)。IMAGE_IMPORT_BY_NAME結(jié)構(gòu)非常簡(jiǎn)單,看上去是這樣: WORD Hint; BYTE Name?; 第一個(gè)域是導(dǎo)入函數(shù)的導(dǎo)出序數(shù)的最佳猜測(cè) 值 。和 NE 文件不同,這個(gè)值不是必須正確的。于是,載入器指示把它當(dāng)作一個(gè)進(jìn)行二分查找的建議開始值。下一個(gè)是導(dǎo)入函數(shù)的名字的 ASCIIZ 字符串。 為什么有兩個(gè)平行的指針數(shù)組指向結(jié)構(gòu) IMAGE_IMPORT_BY_NAME ?第一個(gè)數(shù)組(由 Characteristics 域指向的)單獨(dú)的留下來(lái),并不被修改。經(jīng)常被稱作提名表。第二個(gè)數(shù)組(由 FirstThunk 域指向的)將被 PE 載入器覆蓋。載入器在這個(gè)數(shù)組中迭代每個(gè)指針,并查找每個(gè) IMAGE_IMPORT_BY_NAME結(jié)構(gòu)指向的函數(shù)的地址。載入器然后用找到的函數(shù)地址覆蓋這個(gè)指向 IMAGE_IMPORT_BY_NAME結(jié)構(gòu)的指針。 JMP DWORD PTR XXXXXXXX 中的 XXXXXXXX 指向 FirstThunk 數(shù)組的一個(gè)條目。因?yàn)橛奢d入器覆蓋的這個(gè)指針數(shù)組實(shí)際上保持所有導(dǎo)入函數(shù)的地址,叫做 “ 導(dǎo)入地址表 ” 。 在優(yōu)化上無(wú)止境的探索 中 ,微軟在 WindowsNT 中 “ 優(yōu)化 ” 了系統(tǒng) DLL( KERNEL32.DLL 等等)的 thunk數(shù)組。在這個(gè)優(yōu)化中,這個(gè)數(shù)組中的指針不再指向IMAGE_IMPORT_BY_NAME 結(jié)構(gòu) ,它們已經(jīng)包含了導(dǎo)入函數(shù)的地址。換句話說(shuō),載入器不需要去查找函數(shù)的地址并用導(dǎo)入函數(shù)的地址覆蓋 thunk數(shù)組 (譯注) 。 譯注:這就是 Bound Import,關(guān)于 Bound Import,參考文獻(xiàn) 1516,有詳細(xì)介紹。不過(guò),在我的軟件中,忽略了對(duì) Bound Import 的處理,這樣會(huì)造成一些程序載入速度的減小。但使問(wèn)題簡(jiǎn)化了許多。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 19 - 因?yàn)閷?dǎo)入地址表在一個(gè)可寫的塊中 ,攔截一個(gè) EXE 或 DLL 對(duì)另一個(gè) DLL 的調(diào)用就相對(duì)容易。只需要修改適當(dāng)?shù)貙?dǎo)入地址條目去指向希望攔截的函數(shù)。不需要修改調(diào)用者或被調(diào)者的任何代碼。 注意微軟產(chǎn)生的 PE文件的導(dǎo)入表并不是完全被連接器同步的,這一點(diǎn)很有趣。所有對(duì)另一個(gè) DLL 中的函數(shù)的調(diào)用的指令都在一個(gè)導(dǎo)入庫(kù)中。當(dāng)你連接一個(gè) DLL時(shí),庫(kù)管理器( LIB32.EXE 或 LIB.EXE)掃描將要被連接的 OBJ文件并且創(chuàng)建一個(gè)導(dǎo)入庫(kù)。這個(gè)導(dǎo)入庫(kù)完全不同于 16位 NE文件連接器使用的導(dǎo)入庫(kù)。 32位庫(kù)管理器產(chǎn)生的導(dǎo)入庫(kù)有一個(gè) .text 塊和幾個(gè) .idata$塊。導(dǎo)入庫(kù) 中的 .text塊包含 JMP XXXX 指令,這條指令的標(biāo)號(hào)在 OBJ 文件的符號(hào)表中用一個(gè)符號(hào)名來(lái)存儲(chǔ)。這個(gè)符號(hào)名對(duì)將要從DLL中導(dǎo)出的所有函數(shù)名講都是唯一的(例如: _Dispatch_Message4)。導(dǎo)入庫(kù)中的一個(gè) .idata$塊包含一個(gè)從導(dǎo)入庫(kù)中引用的地址,即導(dǎo)入庫(kù)的 .text 中的指令: JMP XXXX 中的 XXXX 。 另一個(gè) .idata$塊有一個(gè)提示序號(hào)( hint ordinal)的空間。這兩個(gè)域就組成了IMAGE_IMPORT_BY_NAME 結(jié)構(gòu)。當(dāng)你晚期連接一個(gè)使用導(dǎo)入庫(kù)的 PE 文件時(shí),導(dǎo)入庫(kù)的塊被加到連接器需要處理的塊的列表中,這個(gè)列表在你的 OBJ 文件中。一旦導(dǎo)入庫(kù)中的這個(gè) xxxx 的名字和和要導(dǎo)入的函數(shù)名相同,連接器就假定這條 jmp xxxx指令就是這個(gè)導(dǎo)入函數(shù),并修正其中的 xxxx ,使其指向這個(gè) .idata$中的一個(gè)存儲(chǔ)導(dǎo)入函數(shù)地址的空間。導(dǎo)入庫(kù)中的這條 jmp xxxx指令在本質(zhì)上就被當(dāng)作這個(gè)導(dǎo)入函數(shù)本身了。 除了提供一個(gè)導(dǎo)入函數(shù)的指令 jmp xxxx,導(dǎo)入庫(kù)還提供 PE文件的 .idata塊(或稱導(dǎo)入表)的片斷。這些片斷來(lái)自于庫(kù)管理器放入導(dǎo)入庫(kù)中的不同的 .idata$塊。簡(jiǎn)而言之,連接器實(shí)際上不知道出現(xiàn)在不同的 OBJ文件中的導(dǎo)入函數(shù)和普通函數(shù)之無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 20 - 間的不同。連接器只是按照它的內(nèi)部規(guī)則去建立并結(jié)合塊,于是,所有的事情就自然順理成章了。 本文有關(guān) 導(dǎo)入表的 內(nèi)容,基本上就這么多,要得到更多的信息,請(qǐng)參閱參考文獻(xiàn) 141516。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 21 - 4 當(dāng)前流行的一些軟件保護(hù)技術(shù) 4.1 序列號(hào)保護(hù) 數(shù)學(xué)算法一項(xiàng)都是密碼加密的核心,但在一般的軟件加密中,它似乎并不太為人們關(guān)心,因?yàn)榇蠖鄶?shù)時(shí)候軟件加密本身實(shí)現(xiàn)的都是一種編程的技巧。但近幾年來(lái)隨著序列號(hào)加密程序的普及,數(shù)學(xué)算法在軟件加密中的比重似乎是越來(lái)越 大了。 看看在網(wǎng)絡(luò)上大行其道的序列號(hào)加密的工作原理。當(dāng)用戶從網(wǎng)絡(luò)上下載某個(gè)shareware 共享軟件后,一般都有使用時(shí)間上的限制,當(dāng)過(guò)了共享軟件的試用期后,你必須到這個(gè)軟件的公司去注冊(cè)后方能繼續(xù)使用。注冊(cè)過(guò)程一般是用戶把自己的私人信息(一般主要指名字)連同信用卡號(hào)碼告訴給軟件公司,軟件公司會(huì)根據(jù)用戶的信息計(jì)算出一個(gè)序列碼,在用戶得到這個(gè)序列碼后,按照注冊(cè)需要的步驟在軟件中輸入注冊(cè)信息和注冊(cè)碼,其注冊(cè)信息的合法性由軟件驗(yàn)證通過(guò)后,軟件就會(huì)取消掉本身的各種限制,這種加密實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,不需要額外的成本, 用戶購(gòu)買也非常方便,在互聯(lián)網(wǎng)上的軟件 80%都是以這種方式來(lái)保護(hù)的。 軟件驗(yàn)證序列號(hào)的合法性過(guò)程,其實(shí)就是驗(yàn)證用戶名和序列號(hào)之間的換算關(guān)系是否正確的過(guò)程。其驗(yàn)證最基本的有兩種,一種是按用戶輸入的姓名來(lái)生成注冊(cè)碼,再同用戶輸入的注冊(cè)碼比較,公式表示如下: 序列號(hào) = F(用戶名) 但這種方法等于在用戶軟件中再現(xiàn)了軟件公司生成注冊(cè)碼的過(guò)程,實(shí)際上是非常不安全的,不論其換算過(guò)程多么復(fù)雜,解密者只需把你的換算過(guò)程從程序中提取出來(lái)就可以編制一個(gè)通用的注冊(cè)程序。 另外一 種是通過(guò)注冊(cè)碼來(lái)驗(yàn)證用戶名的正確性,公式表示如下: 用戶名稱 = F逆(序列號(hào)) (如 ACDSEE) 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 22 - 這其實(shí)是軟件公司注冊(cè)碼計(jì)算過(guò)程的反算法,如果正向算法與反向算法不是對(duì)稱算法的話,對(duì)于解密者來(lái)說(shuō),的確有些困難,但這種算法相當(dāng)不好設(shè)計(jì)。 于是有人考慮到以下的算法: F1(用戶名稱) = F2(序列號(hào)) F1、 F2是兩種完全不同的的算法,但用戶名通過(guò) F1算法計(jì)算出的特征字等于序列號(hào)通過(guò) F2 算法計(jì)算出的特征字,這種算法在設(shè)計(jì)上比較簡(jiǎn)單,保 密性相對(duì)以上兩種算法也要好的多。如果能夠把 F1、 F2 算法設(shè)計(jì)成不可逆算法的話,保密性相當(dāng)?shù)暮?;可一旦解密者找到其中之一的反算法的話,這種算法就不安全了。一元算法的設(shè)計(jì)看來(lái)再如何努力也很難有太大的突破,那么二元呢? 特定值 = F(用戶名,序列號(hào)) 這個(gè)算法看上去相當(dāng)不錯(cuò),用戶名稱與序列號(hào)之間的關(guān)系不再那么清晰了,但同時(shí)也失去了用戶名于序列號(hào)的一一對(duì)應(yīng)關(guān)系,軟件開發(fā)者必須自己維護(hù)用戶名稱與序列號(hào)之間的唯一性,但這似乎不是難以辦到的事,建個(gè)數(shù)據(jù)庫(kù)就可以了。當(dāng)然也可以把用戶名稱和序列號(hào) 分為幾個(gè)部分來(lái)構(gòu)造多元的算法。 特定值 = F(用戶名 1,用戶名 2, .序列號(hào) 1,序列號(hào) 2.) 現(xiàn)有的序列號(hào)加密算法大多是軟件開發(fā)者自行設(shè)計(jì)的,大部分相當(dāng)簡(jiǎn)單。而且有些算法作者雖然下了很大的功夫,效果卻往往得不到它所希望的結(jié)果。 4.2 時(shí)間限制 有些程序的試用版每次運(yùn)行都有時(shí)間限制,例如運(yùn)行 10分鐘或 20分鐘就停止工作,必須重新運(yùn)行該程序才能正常工作。這些程序里面自然有個(gè)定時(shí)器來(lái)統(tǒng)計(jì)程序運(yùn)行的時(shí)間。 這種方法使用的較少。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 23 - 4.3 Key File 保護(hù) Key File(注冊(cè)文件)是一種利用文件來(lái)注冊(cè)軟件的 保護(hù)方式。 Key File 一般是一個(gè)小文件,可以是純文本文件,也可以是包含不可顯示字符的二進(jìn)制文件,其內(nèi)容是一些加密過(guò)或未加密的數(shù)據(jù),其中可能有用戶名、注冊(cè)碼等信息。文件格式則由軟件作者自己定義。試用版軟件沒(méi)有注冊(cè)文件,當(dāng)用戶向作者付費(fèi)注冊(cè)之后,會(huì)收到作者寄來(lái)的注冊(cè)文件,其中可能包含用戶的個(gè)人信息。用戶只要將該文件放入指定的目錄,就可以讓軟件成為正式版。該文件一般是放在軟件的安裝目錄中或系統(tǒng)目錄下。軟件每次啟動(dòng)時(shí),從該文件中讀取數(shù)據(jù),然后利用某種算法進(jìn)行處理,根據(jù)處理的結(jié)果判斷是否為正確的注冊(cè)文件,如果正確 則以注冊(cè)版模式來(lái)運(yùn)行。 這種保護(hù)方法使用也不多,但是,我個(gè)人認(rèn)為,比時(shí)間限制要好。 4.4 CD-check 即光盤保護(hù)技術(shù)。程序在啟動(dòng)時(shí)判斷光驅(qū)中的光盤上是否存在特定的文件,如果不存在則認(rèn)為用戶沒(méi)有正版光盤,拒絕運(yùn)行。在程序運(yùn)行的過(guò)程當(dāng)中一般不再檢查 光 盤 的 存 在 與 否 。 Windows 下 的 具 體 實(shí) 現(xiàn) 一 般 是 這 樣 的 : 先 用GetLogicalDriveStrings( )或 GetLogicalDrives( )得到系統(tǒng)中安裝的所有驅(qū)動(dòng)器的列表,然后再用 GetDriveType( )檢查每一個(gè)驅(qū)動(dòng)器,如果是光驅(qū)則用CreateFileA( )或 FindFirstFileA( )等函數(shù)檢查特定的文件存在與否,并可能進(jìn)一步地檢查文件的屬性、大小、內(nèi)容等。 4.5 反跟蹤技術(shù)( Anti-Debug) 好的軟件保護(hù)都要和反跟蹤技術(shù)結(jié)合在一起。如果沒(méi)有反跟蹤技術(shù),軟件等于直接裸露在 Cracker 面前。這里說(shuō)的反跟蹤,指的是反動(dòng)態(tài)跟蹤。即防止 Cracker 用 SoftICE 之類的調(diào)試器動(dòng)態(tài)跟蹤,分析軟件。當(dāng)前的這類軟件還有如 TRW 、無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 24 - ICEDUMP 等等。反跟蹤技術(shù)一般是具有針對(duì)性的,即針對(duì)某種調(diào)試器的反跟蹤,而不能防止所有的調(diào)試器跟蹤, 如果有新的破解工具出現(xiàn),就需要相應(yīng)的反跟蹤技術(shù) 。 這種技術(shù)一般是檢測(cè)這些特定的調(diào)試器是否駐留內(nèi)存,如果駐留內(nèi)存,就認(rèn)為被跟蹤,從而拒絕執(zhí)行,或進(jìn)行一些懲罰性措施 。還有一些檢測(cè)方法,如假設(shè)這些調(diào)試器在內(nèi)存中,軟件和這些調(diào)試器通信,如果結(jié)果合乎這些調(diào)試器的輸出 。就認(rèn)為被跟蹤 。或者在內(nèi)存中搜尋這些調(diào)試器的特征串,如果找到,就認(rèn)為被跟蹤 。有的甚至用中斷鉤子、 SEH( Structural Exception Handle,即結(jié)構(gòu)化異常處理)檢測(cè)調(diào)試器。 4.6 反反匯編技術(shù)( Anti- Disassmbly) 即 Anti-Disassmbly ??舍槍?duì)專門的反匯編軟件設(shè)計(jì)的 “ 陷阱 ” ,讓反匯編器陷入死循環(huán),但這種方法沒(méi)有通用性。 一般是使用花指令 。這種方法有通用性,即所有的反匯編器都可以用這種方法來(lái)抵擋 。這種方法主要是利用不同的機(jī)器指令包含的字節(jié)數(shù)并不相同,有的是單字節(jié)指令,有的是多字節(jié)指令。對(duì)于多字節(jié)指令來(lái)說(shuō),反匯編軟件需要確定指令的第一個(gè)字節(jié)的起始位置,也就是操作碼的位置,這樣才能正確地反匯編這條指令,否則它就可能反匯編成另外一條指令了。并且,多字節(jié),指令長(zhǎng)度不定,使得反匯編器在錯(cuò)誤譯碼一條指令后,接下來(lái)的 許多條指令都會(huì)被錯(cuò)誤譯碼 。所以,這種方法是很有效的 。 實(shí)施方法:在程序中加入一些無(wú)用的字節(jié)來(lái)干擾反匯編軟件的判斷,從而使得它錯(cuò)誤地確定指令的起始位置,那么也就達(dá)到了干擾反匯編器工作的目的。一般形式如下: 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 25 - . . jmp L1 dd 012344578h ;這里是一些隨機(jī)數(shù),用來(lái)干擾反匯編器 ; 對(duì)指令的譯碼 L1: . . 4.7 軟件狗 軟件狗是一種智能型加密工具。它是一個(gè)安裝在并口、串口等接口上的硬件電路,同時(shí)有一套使用于各種語(yǔ)言的接口軟件和工具 軟件。當(dāng)被狗保護(hù)的軟件運(yùn)行時(shí),程序向插在計(jì)算機(jī)上的軟件狗發(fā)出查詢命令,軟件狗迅速計(jì)算查詢并給出響應(yīng),正確的響應(yīng)保證軟件繼續(xù)運(yùn)行。如果沒(méi)有軟件狗,程序?qū)⒉荒苓\(yùn)行,復(fù)雜的軟硬件技術(shù)結(jié)合在一起防止軟件盜版。真正有商業(yè)價(jià)值得軟件一般都用軟件狗來(lái)保護(hù)。 平時(shí)常見(jiàn)的狗主要有 “ 洋狗 ” (國(guó)外狗)和 “ 土狗 ” (國(guó)產(chǎn)狗)。這里 “ 洋狗 ”主要指美國(guó)的彩虹和以色列的 HASP, “ 土狗 ” 主要有金天地(現(xiàn)在與美國(guó)彩虹合資,叫 “ 彩虹天地 ” )、深思、尖石??偟恼f(shuō)來(lái), “ 洋狗 ” 在軟件接口、加殼、反跟蹤等“ 軟 ” 方面沒(méi)有 “ 土狗 ” 好,但在硬件上絕對(duì)無(wú)法破 解(應(yīng)當(dāng)說(shuō)破解難度非常大);而 “ 土狗 ” 在軟的方面做的很好,但在硬件上不如 “ 洋狗 ” ,稍有單片機(jī)功力的人,都可以復(fù)制。 4.8 Vbox 保護(hù)技術(shù) Vbox 是一個(gè)軟件 。它是用來(lái)保護(hù)其它軟件的 。凡被 Vbox 保護(hù)的軟件,一旦過(guò)了試用期,就不能再使用了,刪了重裝也沒(méi)用,除非刪除整個(gè)操作系統(tǒng)再重裝。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 26 - 4.9 SalesAgent 保護(hù)技術(shù) SalesAgent 保護(hù)的軟件一般具有 x 天試用再購(gòu)買的接口,是一種時(shí)間限制保護(hù)方式。才用這種保護(hù)方式的軟件主要有 Macromedia Flash 4 、 DreameWaver 等等 。 4.10 SecuROM 保護(hù)技術(shù) SecuROM ( )是 Sony 開發(fā)的一種商業(yè)光盤加密技術(shù),它可以阻止用戶對(duì)加密光盤的復(fù)制,被保護(hù)的光盤上有 CMS16.dll 、cms32_95.dll 、 cms32_nt.dll 這幾個(gè)文件。很多游戲光盤才用這種保護(hù)技術(shù)。 4.11 軟盤加密 通過(guò)在軟盤上格式化一些非標(biāo)準(zhǔn)磁道,在這些磁道上寫入一些數(shù)據(jù),如軟件的解密密鑰等等。這種軟盤成為 “ 鑰匙盤 ” 。軟件運(yùn)行時(shí)用戶 將軟盤插入,軟件讀取這些磁道中的數(shù)據(jù),判斷是否合法的 “ 鑰匙盤 ” 。 軟盤加密還有其它一些技術(shù),如弱位加密等等。 隨著近年來(lái)軟盤的沒(méi)落 , 這種方法基本上 退出 了歷史舞臺(tái)。 4.12 將軟件與機(jī)器硬件信息結(jié)合 用戶得到(買到或從網(wǎng)上下載)軟件后,安裝時(shí)軟件從用戶的機(jī)器上取得該機(jī)器的一些硬件信息(如硬盤序列號(hào)、 BOIS 序列號(hào)等等),然后把這些信息和用戶的序列號(hào)、用戶名等進(jìn)行計(jì)算,從而在一定程度上將軟件和硬件部分綁定。在我的加殼程序中將使用這種方法和其它方法的結(jié)合,后面會(huì)詳細(xì)說(shuō)明。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 27 - 4.13 加殼 就是在完整的軟件上 已編譯連接,可以運(yùn)行 的程序上,加上一個(gè) “ 殼 ” ,這個(gè) “ 殼 ” ,對(duì)軟件進(jìn)行保護(hù), 這些 殼一般綜合運(yùn)用了 4.1 4.6 節(jié)所述的軟件保護(hù)技術(shù)。因?yàn)槲业脑O(shè)計(jì)方案中使用了加殼技術(shù),后面將會(huì)詳細(xì)說(shuō)明,這里不再贅述。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 28 - 5 該軟件的設(shè)計(jì)思想 5.1 傳統(tǒng)保護(hù)的不足 上一章介紹了當(dāng)前流行的一些軟件保護(hù)技術(shù),其中有些工作 得 非常好,如序列號(hào)技術(shù),幾乎所有的軟件都使用了這種技術(shù)。 這里我不會(huì)指出這些技術(shù)如何會(huì)被破解,因?yàn)榍懊嬉呀?jīng)說(shuō)明了,軟件保護(hù)都可以被破解。只說(shuō)出這些方案的 “ 非技術(shù) ” 的缺點(diǎn)。 可以看出,這些技術(shù)中,軟件和硬件仍然是分離的。 在軟件狗保護(hù)中,軟件和硬件 有了一定的結(jié)合,但是,還沒(méi)有把軟件和一臺(tái)特定的機(jī)器綁定 。在軟盤保護(hù)中,軟件和硬件也有一定結(jié)合。但是用戶仍然可以在多臺(tái)機(jī)器上安裝同一套軟件。只在需要這些硬件的時(shí)候時(shí)候,如插上軟件狗,插入鑰匙盤,就可以在多臺(tái)機(jī)器上使用同一套軟件了 。并且,要正版用戶在使用軟件時(shí)要插上軟件狗,插入鑰匙盤,造成很多不必要的麻煩 。如用戶的并行口可能用戶打印機(jī) 還有,由于加入了硬件,這種保護(hù)方法的成本較高,對(duì)一些比較小的軟件,這種方法是不實(shí)用的。 而 CD-Check 等光盤加密技術(shù),有個(gè)缺點(diǎn)是使用中用戶必須插入光盤,而現(xiàn)在的硬 盤技術(shù)的發(fā)展,使得存儲(chǔ)容量不再是一個(gè)問(wèn)題,用戶往往把光盤上的所有東西都裝入硬盤,而要用戶在每次運(yùn)行軟件時(shí)都插入光盤,有點(diǎn)難以接受。 而比較看好的序列號(hào)保護(hù)技術(shù),則存在一個(gè)通病 算法要軟件開發(fā)者自己設(shè)計(jì),而且,如果一對(duì)(序列號(hào),用戶名)被 Craker 從 Internet 上發(fā)布出去,所有的用戶都可以用這對(duì)(序列號(hào),用戶名)來(lái) “ 注冊(cè) ” 軟件,從而非法使用。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 29 - 5.2 網(wǎng)絡(luò)的流行 現(xiàn)在, 我想沒(méi)有 哪一個(gè)使用過(guò)計(jì)算的人沒(méi)有使用過(guò) Internet。全世界有幾億人在使用 Internet,我們中國(guó)有幾千萬(wàn)萬(wàn)人在使用 Internet 。許多商業(yè)軟件也都有 Internet 試用版,共享軟件(這里不討論免費(fèi)軟件)甚至都是在 Internet 上發(fā)布的 。而幾乎所有的軟件在 Internet 上都有破解版 。于是,把軟件保護(hù)和 Internet 結(jié)合起來(lái)是自然而然的事 。 要把軟件保護(hù)和 Internet 結(jié)合起來(lái),就自然要保證安全 。要保證安全就離不開密碼學(xué),在第一章已經(jīng)簡(jiǎn)要介紹了密碼學(xué)的一些概念 。網(wǎng)絡(luò)上信息傳輸?shù)陌踩苤匾?,特別是一些敏感信息,如用戶資料,密碼等等 。 5.3 我的方案 針對(duì)前面的一些問(wèn)題,通過(guò)各方面比較,權(quán)衡,我提 出了這套軟件保護(hù)方案 。 這套方案集傳統(tǒng)的序列號(hào)保護(hù) 、利用硬件信息保護(hù) 、加殼保護(hù) 、反跟蹤 、反反匯編 、反 Dump 、反 API 斷點(diǎn)等于一身。又加入了密碼學(xué)中的數(shù)字簽名 、散列 、密鑰交換等等 。形成了我自己獨(dú)特的 、加密強(qiáng)度更高 、使用上更方便(現(xiàn)在只是作為一個(gè)演示,使用上還談不上方便)、更合用戶口味的反盜版 、電子注冊(cè)解決方案 。 該方案的具體細(xì)節(jié)將在接下來(lái)的兩章中進(jìn)行描述。 5.4 該方案的 可行性分析 可以 說(shuō),沒(méi)有密碼學(xué)和網(wǎng)絡(luò)的話,這個(gè)方案只能是紙上談兵 。我正是看到了這兩點(diǎn),才萌發(fā)了這個(gè)方案的設(shè) 計(jì)思想 。這個(gè)設(shè)想在 3 個(gè)月之前有了一個(gè)模糊的想法,在隨后, 經(jīng)過(guò)查閱大量相關(guān)資料,加上自己多方面的考慮, 逐漸地就在我的腦海里有了一個(gè)清晰的輪廓,這三個(gè)月的時(shí)間,只是要把這個(gè)設(shè)想變成現(xiàn)實(shí) 。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 30 - 現(xiàn)代 密碼學(xué)(特別是非對(duì)稱密碼學(xué)),是直到 70 年代才初現(xiàn)端倪的,但是發(fā)展很快,到現(xiàn)在,我們已經(jīng)可以使用許多現(xiàn)成的密碼算法 。這些算法甚至成為 Windows 不可分割的一部分,稱為 CryptoAPI,如果沒(méi)有 CryptoAPI,我將不得不把龐大的算法庫(kù)包括在我的源代碼內(nèi),甚至有許多算法要自己編寫代碼實(shí)現(xiàn) 。這對(duì)我 將是一個(gè)災(zāi)難 ! 為了簡(jiǎn)化設(shè)計(jì),并突出主要問(wèn)題,不拘泥于花俏的外表,我不會(huì)去做圖形用戶接口,而使用簡(jiǎn)單的 Consol 控制臺(tái)用戶接口 。 踩在巨人的肩膀上,將看的更高,更遠(yuǎn)。正是有了這么多前人的努力,我才能在此之上進(jìn)行自己的創(chuàng)新。 Internet 的流行,盜版軟件的泛濫,幾乎成為我們中國(guó)民族軟件企業(yè)的災(zāi)難 。使得該軟件具有很積極的現(xiàn)實(shí)意義 。 只需要極少的修改,增加圖形界面,本系統(tǒng)即可作為商業(yè)應(yīng)用。甚至不需要修改,只編寫一些簡(jiǎn)單的批處理文件,都可以讓軟件開發(fā)者和 普通用戶方便的使用 (后面的演示就是使用簡(jiǎn) 單的批處理文件來(lái)簡(jiǎn)化用戶界面的)。 正是基于這些原因, 比起傳統(tǒng)方案,本方案有以下優(yōu)點(diǎn): (1) 當(dāng)前許多軟件保護(hù)技術(shù),大多只求精于使用操作系統(tǒng)本身的特點(diǎn) 、沉溺于繁雜的技術(shù)細(xì)節(jié),而不考慮使用更好的密碼學(xué)協(xié)議 、算法。本方案不同,首要的是使用可靠的密碼學(xué)協(xié)議 、算法,使加密強(qiáng)度得到了保證 。 (2) 通過(guò)網(wǎng)絡(luò)對(duì)軟件授權(quán) 、是當(dāng)前流行軟件保護(hù)技術(shù)的一個(gè)盲點(diǎn),而綜合使用數(shù)字簽名 、散列技術(shù) 、密鑰交換等技術(shù)的,更是少之又少。據(jù)我所知,有一個(gè)俄羅斯人編寫的非常有名的加殼軟件,使用了很多的密碼算法 被人們戲稱:“ 用光 了世界上所有的密碼算法! ” 但是他仍然沒(méi)有 數(shù)字 簽名以及密鑰交換 ,并且也是單機(jī)的。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 31 - (3) 通過(guò)網(wǎng)絡(luò)實(shí)現(xiàn)軟件授權(quán),成本很低,用戶使用又非常方便,軟件開發(fā)者管理軟件的銷售 、代理 、等等也很方便 。 (4) 本方案不光在密碼算法 、協(xié)議上設(shè)計(jì)得很合理,而且,在最終受保護(hù)程序執(zhí)行時(shí),也比傳統(tǒng)方案要好,這些將在詳述殼程序主要技術(shù)時(shí)具體說(shuō)明 。 (5) 本方案有很強(qiáng)的可擴(kuò)展性,在軟件授權(quán) 、密碼協(xié)議的實(shí)現(xiàn)上使用了面向?qū)ο蠓椒?。 在 殼程序的開發(fā)中使用了結(jié)構(gòu)清晰 、分層次分明的分析、設(shè)計(jì) 。幾個(gè)模塊相對(duì)獨(dú)立,在此基礎(chǔ)上,各 個(gè)模塊在遵循一套規(guī)則的前提下可以相對(duì)獨(dú)立設(shè)計(jì),如相同的 Merge 、 Register 程序,可以用不同的 Shield 殼程序來(lái)保護(hù)客戶軟件 。 (6) 本軟件使用 VC 和匯編語(yǔ)言組合開發(fā),使得開發(fā)成本降低了許多,軟件的可靠性 、可用性 、可測(cè)試性 、可維護(hù)性都有很大的提高 。而當(dāng)前幾乎所有的同類軟件都是用匯編語(yǔ)言開發(fā),成本很高 。 如果本軟件完全使用匯編語(yǔ)言,在這短短的三個(gè)月之間是不可能完成的 。 (7) 使用 CryptoAPI,使該軟件的整體設(shè)計(jì)獨(dú)立于具體的密碼學(xué)算法,為了使用不同的算法,只需要 修改相關(guān)參數(shù)即可,而不需要重新編寫大量代碼;并且,使用 CryptoAPI,使得該軟件的體積大大縮小 如果自己編寫密碼算法,軟件的體積將異常龐大,至少是目前的 3倍以上 。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 32 - 6 該軟件的整體構(gòu)架、開發(fā)工具及方法 6.1 需求分析 本軟件的需求,就是一個(gè)軟件的授權(quán)協(xié)議,及保護(hù)殼應(yīng)該完成的保護(hù)功能,下面將簡(jiǎn)單說(shuō)明: (1) 角色說(shuō)明(軟件授權(quán)協(xié)議中的各個(gè)角色): P :是一個(gè)軟件產(chǎn)品; A :是 P 的開發(fā)者; B :是 A 的一個(gè)代理商(也可以是 A 自己) ; C :是 P的最終用戶。 (2) 軟件授權(quán)的協(xié)議執(zhí)行過(guò) 程 約定: (a) Server 、 Merge 、 Register 都運(yùn)行在不同的機(jī)器上 。 Server 運(yùn)行在 A 的機(jī)器上, Merge 運(yùn)行在 B 的機(jī)器上, Register 運(yùn)行在 C 的機(jī)器上 。 (b) 服務(wù)器對(duì)開發(fā)者賣出的軟件進(jìn)行授權(quán) -當(dāng)然他的軟件是用我的軟件保護(hù)過(guò)了的 。 (c) Server 是晝夜不停一直運(yùn)行著的,它接收來(lái)自 Merge 和 Register 的請(qǐng)求 。 (d) 在下面的協(xié)議敘述過(guò)程中, Server 和 A 、 Merge 和 B 、 Register 和 C 交疊使用 。它們多數(shù)時(shí)刻是同義詞 。 協(xié)議開始執(zhí)行: 這里對(duì)授權(quán)協(xié)議的說(shuō)明只是簡(jiǎn)單的說(shuō)明該軟件的需求 。后面章節(jié)將詳細(xì)地說(shuō)明軟件的授權(quán)過(guò)程,并給出協(xié)議所用的算法 。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 33 - (a) A把他的軟件 P 給 B, A 運(yùn)行 Server 。 (b) B 要賣出一套軟件 P,就運(yùn)行 Merge 程序。 Merge 程序產(chǎn)生一個(gè)隨機(jī)的 SN,將此 SN 發(fā)往 Server (即 A )。 (c) Server 收到 SN,從注冊(cè)數(shù)據(jù)庫(kù)中查找 SN,如果找到(能找到該 SN 的概率的數(shù)量級(jí)在 1002 以下),就發(fā)回信息給 Merge,它產(chǎn)生了重復(fù)的 SN,要它再重新計(jì)算一個(gè) SN 。如果未找到(幾乎總是找不到的),就把 SN 登進(jìn)注冊(cè)數(shù)據(jù)庫(kù),用自己的私人密鑰 ASK對(duì) SN 進(jìn)行數(shù)字簽名,得到 K1,把 K1 作為解密密碼發(fā)給 B , 同時(shí)也將自己的公鑰 APK 發(fā)給 B 。 B 用 K1 對(duì) P 進(jìn)行加密 。 (d) 軟件賣給 C 后, C 可以在本地主機(jī)(用戶自己的計(jì)算機(jī))上,通過(guò)網(wǎng)絡(luò)(撥號(hào)上網(wǎng),或 ADSL,或其它方式)向開發(fā)者的網(wǎng)絡(luò)服務(wù)器注冊(cè)軟件,然后才能使用 。 C 運(yùn)行注冊(cè)程序 Register, Register 從 Q 中取得序列號(hào) SN(serial number) , 再取得本地主機(jī)的硬件信息 ,計(jì)算并存儲(chǔ)該硬件信息 HD 的散列值 SAC (System Autentication Code)。 將它發(fā)送給服務(wù)器 Server 。服務(wù)器 Server 從數(shù)據(jù)庫(kù)中查找這個(gè) SN,如果找到 , 并且這個(gè)序列號(hào)的拷貝已經(jīng)注冊(cè) , 并且 它收到的 SAC 和以前注冊(cè)的 SAC 相同 相同 拷貝可以在 同 一臺(tái)被授權(quán)的計(jì)算機(jī)上多次安裝 /注冊(cè) 或者找到了 SN,但該 SN 還未注冊(cè),就將隨 SN 一起發(fā)來(lái)的 SAC 存入數(shù)據(jù)庫(kù) , 待以后再驗(yàn)證這臺(tái)計(jì)算機(jī)。 Server 把 SN 對(duì)應(yīng)的解密密碼 K1發(fā)給用戶 C, 同時(shí)將自己的公鑰 APK 也發(fā)給 C 。 (e) Register 程序用 K1 解密 Q,同時(shí)用本地主機(jī)硬件信息 HD 的另一個(gè)散列值 K2 作為密鑰加密 Q,最終得到 R 。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 34 - 現(xiàn)在,用戶 C 可以運(yùn)行軟件 R 了( R 就是經(jīng)過(guò)注冊(cè)的 P), R 具有了一些反Cracker 功能及其它保護(hù)功能。 (3) 最終受保護(hù)的軟件 P (即上面授權(quán)協(xié)議執(zhí)行到最后產(chǎn)生的可執(zhí)行程序 R )應(yīng)該具有的功能: (a) 只能在注冊(cè)的那太機(jī)器上運(yùn)行 (反非法使用) ; (b) 病毒檢測(cè)和 Cracker 更改檢測(cè)(保護(hù)功能) ; (c) 反跟蹤功能( Anti-Debug,或稱 Anti-Trace ); (d) 反 Dump 功能( Anti-Dump); (e) 反反匯編功能( Anit-Disassembler); (f) 其它反 Crack 功能 。 (4) 協(xié)議的圖示: 圖 6-1中方框表示處理的文件, Shield 是 “ 殼程序 ” , 橢圓表示 “ 處理過(guò)程 ” ,也即該軟件的模塊 。 該圖在后面的章節(jié)中還要引用到 。 K1,APK K1,APK Server Merge Register SN SN Shield P Q R +K2-K1 +K1 OutPut InPut InPut InPut OutPut 圖 6-1 軟件授權(quán)協(xié)議圖示 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 35 - 6.2 整體框架 從上一節(jié)的需求分析可以看到,本軟件至少要三個(gè)獨(dú)立的模塊: (1) Server 服務(wù)器模塊 。 (2) Merge 產(chǎn)生軟件拷貝的模塊 。 (3) Register 最終用戶注冊(cè)軟件的模塊 。 然而,還差一個(gè)模塊,即保護(hù)軟件的 “ 外殼 ” 模塊 。這個(gè)模塊就叫做 Shield,意思是保護(hù)殼 。 整個(gè)軟件就劃分為這四個(gè)模塊 ! 它們的關(guān)系如圖 6-1, 授權(quán) 協(xié)議 的 過(guò)程同時(shí)也指出了這四個(gè)模塊之間的關(guān)系。 6.3 各取所長(zhǎng)(匯編與 C/C+ 各取所長(zhǎng)) 從圖中可以看出, Server 、 Merge 、 Register 模塊都沒(méi)有涉及到底層的操作 。而 Shield 有沒(méi)有涉及到操作系統(tǒng)底層,由前面的圖形及協(xié)議過(guò)程還不能得出 。 但是,從需求可以知道: Shield 是將要附加到受保護(hù)的軟件上的,運(yùn)行受保護(hù)的軟件時(shí), Shield 程序?qū)⑹紫冗\(yùn)行,從文件中提取一些數(shù)據(jù),做一些必要的檢查,還要解密,還要進(jìn)行反跟蹤,反反匯編,最終還要在比較容易控制的情況下跳轉(zhuǎn)到原程序的入口等等 。 由于 Shield 程序要進(jìn)行這些 底層的 操作,使得它不適用高級(jí)語(yǔ)言開發(fā),甚至不可能用高級(jí)語(yǔ)言開發(fā) 。這時(shí),不得不使用匯編 語(yǔ)言 最強(qiáng)大 、最高效,同時(shí)也是最難使用的語(yǔ)言 。 但是,從需求中也可以看到, Shield 程序也要使用一些高級(jí)的算法,如密碼學(xué)算法, 檢驗(yàn)文件完整性算法 等等 。這使得如果 Shield 程序完全用匯編語(yǔ)言開發(fā),這么多復(fù)雜的,需要較高技巧的算法,可能都要用匯編語(yǔ)言寫 。而這些并不是匯編無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 36 - 語(yǔ)言所特長(zhǎng)的,用匯編語(yǔ)言寫 的結(jié)果只能是 :代價(jià)高昂, 并且 可擴(kuò)展性,可維護(hù)性都很差 ! 經(jīng)過(guò)認(rèn)真的考慮,閱讀大量的資料,我終于找到了一個(gè)折衷的辦法,把必須 用 、不得不用匯編語(yǔ)言寫的部分,如要從文件中提取數(shù)據(jù)的部分,以及反跟蹤,反 反匯編, 內(nèi)存布局設(shè)計(jì) 部分 , 用匯編語(yǔ)言寫,其余部分, 涉及 到復(fù)雜算法的,用 C+ 寫 。然后把兩部分結(jié)合編譯。 而 Server 、 Merge 、 Register,由于不涉及到這些底層的操作,可以 全部 用高級(jí)語(yǔ)言寫,我用的是 C+,主要是因?yàn)椋弘m然這三個(gè)模塊不涉及到最低層的操作,然而它們?nèi)砸?Shield 進(jìn)行通信( Server 不和 Shield 通信),有些算法它們( Merge 、 Register和 Shield) 還要共用,于是高級(jí)語(yǔ)言選擇 C+ 是理所當(dāng)然的 。 至于開發(fā)工具, C/C+ 開發(fā)工具我選 用 VC6.0,不用多說(shuō),匯編語(yǔ)言開發(fā)工具選用 MASM,版本是 7.0,這是程序員使用最多的匯編語(yǔ)言 。 6.4 C/C+ 與匯編語(yǔ)言混合編程時(shí)的互調(diào)協(xié)議 既然 Shield 是用 C+ 和匯編語(yǔ)言混合編寫的,那么它們之間通信(即互相調(diào)用)就是不可避免的。要通信,就要服從共同的協(xié)議,經(jīng)過(guò)查閱大量的資料 。我對(duì) C/C+ 和匯編語(yǔ)言之間的通信終于了如指掌 。下面將詳細(xì)說(shuō)明: (1) 命名約定: VC 編譯 C 文件(不是 C+文件),產(chǎn)生的目標(biāo)文件( .obj 文件,也即編譯器產(chǎn)生的 C 和可執(zhí)行文件 “ 之間 ” 的中間文件) 中,每個(gè)全局符號(hào)(函數(shù)名、全局變量名)前面都加了一個(gè)下劃線 “_” 。也就是說(shuō),如果 C 文件中有一個(gè)全局函數(shù)( C中也只有全局函數(shù)) “fun1” ,經(jīng)過(guò)編譯,在目標(biāo)文件中,該函數(shù)的符號(hào) 名 就是 “_fun1” 。全局變量也相同。 無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 37 - 對(duì) Cpp 文件( C+語(yǔ)言源文件,后面將稱為 C+文件 )中符號(hào)的處理要復(fù)雜的多,這里我不打算介紹對(duì)類名 、類變量(即類中定義的 static 變量)、類方法(類中的 static函數(shù)),對(duì)象名 、對(duì)象變量(類中定義的非 staitc 變量)、對(duì)象方法(類中的非 statioc 函數(shù)) ,這些 太多太多,不可能介紹完,并且因?yàn)槲业脑O(shè)計(jì)中也未牽涉到這些方面。下面僅對(duì) C+ 源程序中的全局非重載函數(shù)的命名約定進(jìn)行說(shuō)明 。 一般的說(shuō), C+ 源程序中一個(gè)完整的全局函數(shù)的聲明應(yīng)該是這樣的: extern “C” returntype calling_convension fun_name(paramtype1 param1 , paramtype2 param2 ,.); 函數(shù)的定義必須和聲明完全一致 。對(duì)這個(gè)函數(shù),定義應(yīng)該如下: extern “C” returntype call ing_convension fun_name(paramtype1 param1 , paramtype2 param2 ,.) . return v; / v 的類型應(yīng)是 returntype extern “C” 表示目標(biāo)文件中函數(shù)的命名將按 C 語(yǔ)言的協(xié)議 , 為求簡(jiǎn)化,我的代碼中所有 C+ 和匯編語(yǔ)言互相調(diào)用的函數(shù)都加了 extern “C” 。下面也是假定函數(shù)有 extern “C” 聲明的 。 對(duì)不同的 calling_convension,即調(diào)用 協(xié)議,在目標(biāo)文件中產(chǎn)生的函數(shù)名、以及參數(shù)傳遞的次序,一般都不同。 calling_convension 將在下面詳細(xì)說(shuō)明?,F(xiàn)在只說(shuō)函數(shù)名。 如果 calling_convension 是 _stdcall,產(chǎn)生的函數(shù)名,在源程序的函數(shù)名之前加一個(gè)下劃線,在函數(shù)名之后加一個(gè) “” ,后面在加上該函數(shù)形式參數(shù)區(qū)的字節(jié)數(shù)( 10 進(jìn)制表示)。如對(duì)該函數(shù),假設(shè)該函數(shù)有三個(gè) long 類型( C 語(yǔ)無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 38 - 言標(biāo)準(zhǔn)規(guī)定 long 類型在所有的機(jī)器中都必須是 32 位)的 形式參數(shù),目標(biāo)文件中的函數(shù)名將是 “_ fun_name12” 。 如果 calling_convension 是 _cdecl,產(chǎn)生的函數(shù)名,在源程序的函數(shù)名之前加一個(gè)下劃線,在函數(shù)名之后沒(méi)有 “” ,后面也沒(méi)有該函數(shù)形式參數(shù)區(qū)的字節(jié)數(shù)( 10 進(jìn)制表示)。如對(duì)該函數(shù),假設(shè)該函數(shù)有三個(gè) long形式參數(shù),目標(biāo)文件中的函數(shù)名將是 “_ fun_name” 。這個(gè)命名協(xié)議實(shí)際上就是 C 的標(biāo)準(zhǔn)命名協(xié)議 。 其它的 calling_convension,在后面的 一個(gè)表(表 6-1)中示出 。 (2) 參數(shù)傳遞協(xié)議 對(duì) extern “C” _cdecl 函數(shù),參數(shù)傳遞是從右向左壓入堆棧,并且堆棧的恢復(fù) 由調(diào)用者( caller)完成,即對(duì)上述函數(shù),如果有以下調(diào)用: fun_name(x,y,z); 產(chǎn)生的匯編指令將是: push z push y push x call _fun_name add esp , 12 fun_name 的函數(shù)體如下: _fun_name proc push ebp mov ebp , esp . ret ;這里未跳過(guò)參數(shù)區(qū)( 未 恢復(fù)堆棧) _fun_name endp 這里只舉這個(gè)例子 。這類函數(shù)由調(diào)用者恢復(fù)堆棧而不是由被調(diào)者( callee)恢 復(fù)堆棧的一個(gè)主要原因是 C 語(yǔ)言允許參數(shù)個(gè)數(shù)可變的函數(shù),如 printf 。這樣,無(wú)憂無(wú)慮畢設(shè)網(wǎng) ():畢業(yè)設(shè)計(jì)源碼下載 - 39 - callee將 “ 不知道 ” 傳遞給它的參數(shù)到底有幾個(gè),而 caller 知道 。這樣在一定程度上降低了效率 。后面你將看到 。 對(duì) extern “C” _stdcall 函數(shù),將有如下代碼: 函數(shù)調(diào)用 : fun_name(x,y,z); 產(chǎn)生的匯編指令將是: push z pu
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 保安隊(duì)長(zhǎng)工作計(jì)劃
- 會(huì)計(jì)勞動(dòng)合同
- 中學(xué)生校服管理規(guī)范
- 眼瞼癤腫的治療及護(hù)理
- 子宮粘連的健康宣教
- 機(jī)器人工程:四足機(jī)器人運(yùn)動(dòng)機(jī)構(gòu)優(yōu)化設(shè)計(jì)研究
- 慢性額竇炎個(gè)案護(hù)理
- TCP傳輸可靠性模擬軟件設(shè)計(jì)與實(shí)現(xiàn)
- 眼球疾患的護(hù)理查房
- 精囊周圍炎護(hù)理課件
- 創(chuàng)新人才小升初試題及答案
- 2025年行政管理期末試題及答案
- 胰島素筆的使用操作流程
- 九年級(jí)化學(xué)上冊(cè)(滬教版2024)新教材解讀課件大綱
- DB11T 1072-2025 城市橋梁工程施工質(zhì)量檢驗(yàn)標(biāo)準(zhǔn)
- 江山南方水泥有限公司浙江省江山市大陳鄉(xiāng)烏龍村鐵錘山水泥用灰?guī)r礦建設(shè)項(xiàng)目環(huán)境影響報(bào)告表
- 小學(xué)語(yǔ)文主題教學(xué)論:理論重塑與創(chuàng)新實(shí)踐
- 工程框架協(xié)議合同協(xié)議
- 電力合規(guī)管理培訓(xùn)
- AI基礎(chǔ)知識(shí)入門
- 2025年甘肅蘭州新區(qū)城投地產(chǎn)置業(yè)有限公司招聘筆試參考題庫(kù)附帶答案詳解
評(píng)論
0/150
提交評(píng)論