




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