Todd

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            65 隨筆 :: 0 文章 :: 24 評論 :: 0 Trackbacks
          下載本節(jié)例子程序 (13.4 KB)
          (特別感謝匯編高手 dREAMtHEATER 對我的代碼作出了相當(dāng)好的優(yōu)化!請參觀他的主頁

          上一節(jié)里我們介紹了CRC-32的實現(xiàn)原理,可是原理不能當(dāng)飯吃吧?下面讓我們來看看CRC是怎么應(yīng)用到文件保護(hù)上的……

          (由于本文涉及到的源代碼比較多,so請各位讀者自行下載代碼進(jìn)行分析)

          在 《原理篇》里面,我們已經(jīng)知道,通過對一個字符串進(jìn)行CRC-32轉(zhuǎn)換,最后可以得到一個4個字節(jié)長的CRC-32值,而且無論該字符串有多長,最終生成 的CRC-32值都肯定是4個字節(jié)長。這就給了我們一個啟示:是否能夠在一個文件的某個地方儲存這個CRC-32值,然后在文件運(yùn)行的時候,再讀取這個 CRC-32值,進(jìn)行比較?

          答案是肯定的。讓我們先來看看PE文件的結(jié)構(gòu):(什么?你不懂PE文件結(jié)構(gòu)?!那……先去找點資料看看吧,到處都有的哦)

          在 PE的可選映像頭(IMAGE_OPTIONAL_HEADER)里面,有一個保留字段:Win32Version,根據(jù)MSDN的資料,它的值一般是 0,而且它的長度是4個DWORD。呵呵,你是不是已經(jīng)想到什么了呢?對了,它的長度和我們要儲存的CRC-32正好是相等的,而且它的值是不變的,一般 是0(別問我為什么啊,我也不知道)。這就給我們提供了一個儲存CRC-32空間的可能,而實際上,有很多Win32病毒也是利用這個 Win32Verion保留字段來儲存它們的感染標(biāo)志的。

          好了,明確了目標(biāo),我們來看看具體應(yīng)該怎么實現(xiàn):

          1、先寫一個 第三方的程序,我假設(shè)它叫“AddCRC32ToFile.exe”。我們可以利用這個程序,打開一個文件,假設(shè)這個文件叫做 “CRC32_Test.exe”,然后“AddCRC32ToFile.exe”就會計算出“CRC32_Test.exe”的CRC-32值,并把這 個CRC-32值寫入“CRC32_Test.exe”的Win32Version處。(其實這步要到最后才做的)

          2、寫好需要進(jìn)行保護(hù) 的程序,在這里我假設(shè)它叫做“CRC32_Test.exe”,記住一定要在這個程序里面加入CRC-32的校驗?zāi)K。這個校驗?zāi)K的工作過程是這樣 的:a、先讀取自身文件的所有內(nèi)容,儲存在一個字符串中,然后把這個字符串的Win32Version處的4個字節(jié)改成4個0,再把字符串進(jìn)行CRC- 32轉(zhuǎn)換,這時我們就得到了一個“原始”文件的CRC-32值;b、讀取自身文件的Win32Version處的值,這個值是我們通過 “AddCRC32ToFile.exe”寫進(jìn)去的。最后我們把步驟a和b中得到的兩個CRC-32值進(jìn)行比較,如果相等的話,說明文件沒有被修改過;反 之就說明文件已經(jīng)被修改了。

          很復(fù)雜是吧?其實好好想一想,沒啥困難的。關(guān)鍵是要按照以下步驟進(jìn)行:

          1、一定要先在 “CRC32_Test.exe”里面寫好所有的模塊,然后才用“AddCRC32ToFile.exe”把“CRC32_Test.exe”的CRC- 32值寫入“CRC32_Test.exe”的Win32Version處,否則最后得到的結(jié)果肯定是不正確的。順序一定不能搞錯!!!

          2、今后一旦修改了“CRC32_Test.exe”的內(nèi)容(比如重新編譯了一次),就一定要再用“AddCRC32ToFile.exe”重新把CRC-32值寫入“CRC32_Test.exe”中去,否則結(jié)果也是會不正確的。

          其實方案不止這一種,還有以下的幾種是可行的:
          1、把CRC-32的值寫入一個單獨(dú)的DLL文件中(或者別的什么亂七八糟的地方,隨你的便),然后在運(yùn)行的時候讀取DLL文件中儲存好的CRC-32值,進(jìn)行比較。
          2、把CRC-32的值追加到.exe文件的最后,在運(yùn)行的時候讀取這最后的4個字節(jié)的內(nèi)容,進(jìn)行比較。不過我覺得這樣做不太好,呵呵,因為增加了文件的長度。
          ……

          我的方案的缺點分析:
          CRC-32的值其實可以由Cracker自行計算得出后,重新寫入到Win32Version處。這樣的話,我們做的工作豈不是沒有意義了?
          其 實解決的方法還是有的,我們可以在計算CRC-32值之前,對需要進(jìn)行轉(zhuǎn)換的字符串加點手腳,例如對這個字符串進(jìn)行移位、xor等操作,或者把自己的生日 等信息加入到字符串中,隨你的便什么都行,總之不是單純的文件的內(nèi)容就行了,然后在最后比較的時候,也用同樣的方法反計算出CRC-32值。這樣得到的 CRC-32就不是由文件的內(nèi)容計算出來的,相信對Cracker的阻力也會加大不少。

          總結(jié):
          應(yīng)用CRC原理到文件的自校驗保護(hù)中,是一種很靈活的手段,可用的方法有很多種。本文只是拋磚引玉,希望高手能給出更好的解決方法,并請發(fā)信到lcother@163.net,我們共同研究,多謝!!!
          posted on 2010-05-20 01:47 Todd 閱讀(276) 評論(0)  編輯  收藏 所屬分類: 攻防c++
          主站蜘蛛池模板: 台东县| 青阳县| 策勒县| 潜江市| 武宣县| 巨鹿县| 法库县| 嘉鱼县| 雅安市| 罗甸县| 杂多县| 疏附县| 丰原市| 土默特左旗| 澎湖县| 长海县| 宝坻区| 疏附县| 成都市| 依兰县| 昌邑市| 江源县| 库尔勒市| 深水埗区| 岚皋县| 济阳县| 壤塘县| 阿拉善左旗| 奉化市| 彩票| 沙洋县| 叶城县| 靖江市| 什邡市| 买车| 和顺县| 泗阳县| 秭归县| 龙里县| 马龙县| 崇左市|