下載本節(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,我們共同研究,多謝!!!
(特別感謝匯編高手 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,我們共同研究,多謝!!!