天天看點

防爆破 轉貼

從未公開過的方法:軟體防爆破之絕招

http://www.cnsw.org/bbs/viewthread.php?tid=2056

從未公開過的方法:軟體防爆破之絕招

假設A為驗證代碼段,爆破一般為找到A代碼段中某處然後修改,可以這樣做:

取随機數X為 1 或者 2

if X=1 then

再次取随機數X為 1 或者 2

    if X=1 then

    再次取随機數X為 1 或者 2

        if X=1 then

                插入代碼A

        else

                插入代碼A

        end if

    else

    再次取随機數X為 1 或者 2

        if X=1 then

                插入代碼A

        else

                插入代碼A

        end if

    end if

else

再次取随機數X為 1 或者 2

    if X=1 then

    再次取随機數X為 1 或者 2

        if X=1 then

                插入代碼A

        else

                插入代碼A

        end if

    else

    再次取随機數X為 1 或者 2

        if X=1 then

                插入代碼A

        else

                插入代碼A

        end if

    end if

end if

目的:由于取了随機數,破解者每次調試找到的代碼A都不是同一處,很難全部Path8處代碼A,甚至可以再多寫一層随機,那就是16處。

最後說一下,這個方法是否有效我也不曉得,請哪位熟悉破解的朋友看過以後評價一下是否有效~~

種方法是有效的,但是要注意代碼A本身的變形,是以重點是:

  代碼A本身的變形 + 随機調用變形後的代碼A

我曾經使用過,對于防止PATCH類的爆破是非常有效的。

因為我們知道,很多所謂的CRACKER都是連CRACKER本身的職業道德都缺乏,往往是拿過軟體,修改幾下,看起來正常就去釋出了,根本不會仔細認真地測試,向上面的那種随機陷阱是可以用來讓這些CRACKER出醜用的,呵呵,當然,同時再加上不定期的随機驗證,可以讓這個CRACKER在以後的日子裡不再輕易釋出你的軟體的爆破産品--為什麼?因為經常出醜,會害得他在解密圈裡名聲很臭,呵呵。。。。。

防爆破法術一則

http://www.cnsw.org/bbs/viewthread.php?tid=2088

設A為驗證代碼段

判斷計算機cpu序列号(反正計算機唯一标示,随便取個什麼),取其中一位指派 X

select case X

case 0

    A

case 1

    A

case 2

    A

......

case 9

    A

end select

這樣就ok啦,出來的爆破有十分之九的計算機上是不能用的~~

不使用CRC進行exe自校驗的程式設計辦法(轉帖)

原文: http://skyfire.dns0755.net/newweb/list.asp?id=201

可執行檔案的自身檢測

nowcan.yeah.net  2003-9-1  老侃第一站

當我們完成一個工程,編譯成可執行檔案後,一般是不希望這個可執行檔案被人改動的,那麼這裡就講述一下這是如何做到的。

其實這并不難,隻要一個API函數就可以完成,這就是MapFileAndCheckSum。這個函數的作用是1)映象檔案,2)從映象檔案中接受原始的校驗和,它是在編譯時有編譯器寫入檔案的,3)計算檔案的校驗和。如果檔案在編譯後被改動,那麼原始的校驗和就會和計算得出的校驗和不同,由此可知檔案被改動。下面的程式中,HeadChksum是原始的校驗和,Chksum是計算得出的校驗和,最後比較他們是否相同來判斷檔案是否被改動。

程式是BCB5寫的,要加上imagehlp.lib這個庫,并且Project->Options->Advance Linker中要選中Calculate Checksum。這樣編譯器才會計算校驗和并寫入檔案。例子程式在這裡。

在VC6裡又有不同,同樣要連上imagehlp.lib這個庫,然後在Project->Settings->Link中去掉Generate debug info和Link incrementlly選項,再選擇Category組合框的Customize,去掉Use program database選項,最後在Project Options中加入"/release",一切OK!

//---------------------------------------------------------------------------

#pragma hdrstop

#include

#include

//---------------------------------------------------------------------------

#pragma argsused

int main(int argc, char* argv[])

{

DWORD HeadChksum=1,Chksum=0;

char Fn[512];

GetModuleFileName(GetModuleHandle(NULL),Fn,512);

if(MapFileAndCheckSum(Fn,&HeadChksum,&Chksum)!=CHECKSUM_SUCCESS)

{

MessageBox(NULL,"Check error!","Error",MB_OK);

}

else

{

if(HeadChksum!=Chksum)

MessageBox(NULL,"File changed.","Warning",MB_OK);

}

return 0;

}

//---------------------------------------------------------------------------

但是如果用了VCL,編譯時居然說有沖突,主要是Imagehlp.h這個頭檔案的問題。我想最簡單的解決方法是動态調用這個函數,LoadLibrary/GetProcAddress/FreeLibrary等,相信大家都會的,我就不寫代碼了。

防破解問答集(zt)

http://www.cnsw.org/bbs/viewthread.php?tid=1429

當發現自己為之工作了好幾個月,甚至幾年的程式被人破解的時候,所受的傷害是難以形容

的。

我作為一個共享軟體作者,并不是因為我在乎那幾塊錢而已(我不想在這裡做具體的計算,

那會使我更加難過...),不,我總是使我的程式盡可能的便宜,使包括學生和自由軟體作

者在内的每個人都能用得起。

然而,我知道破解軟體的魅力(如果你對程式破解者(Cracker)和黑客(Hacker)抱絕對

的不寬容态度,那麼請原諒。但是我的一位同學是心理學家,我們一直在尋找其原因)。破

解一個受限制的軟體程式就像解一個(有時是很狡猾)的謎語,而你可能沉迷于這種解迷的

感覺(當我發現我祖母在幾個月裡整天沉迷在玩字謎遊戲時想起這些的)。問題是(我們現

在涉及到這種“遊戲”的非法部分):程式破解者不會僅僅滿足于隻讓自己了解他的“天賦

”。他必須傳播消息,釋出他的“破解” (Cracker)(看一下破解包,多數是由以下部分

組成:1、破解工具;2、簡短的說明;3、一個巨大的檔案,包含有似乎作者不亞于世界上

任何偉人,或者被破解的程式像所有其它程式一樣無法用那脆弱的保護方式來阻止破解者破

解程式的程序的資訊)。

但是現在,玩笑徹底結束了。釋出這些破解包(讓我們公正些:“研究其可能性“)給其他

人,散布到網站上,新聞討論區,郵件清單,匿名FTP,CD光牒,"abonnements"以及任何其它地方

,他們明顯地破壞了所有那些花時間和精力在他們軟體産品上的收益。雖然沒有人可以說,

所有收到或者下載下傳破解程式的人永遠也不會購買。但是散布破解程式的确是犯罪,就像有人

在商場分發你車鑰匙的拷貝——他是否以此賺錢又有何分别呢?

早些日子,我沒有真正去花時間保護我的産品以防止被破解,但發現周圍有它們的數個破解

之後。我對自己說:為什麼讓它如此簡單? 作為一個程式員,我當然知道,不,決不!—

—程式不可能是破解不了的,而且我知道,每個有吸引力的程式都遲早會有破解(至少是盜

版或非法複制品)出現,但至少,我可以避免最糟糕的錯誤。

多數的進階語言程式員不再懂得彙編語言了,是以,他們使用的“保護措施“多數是很脆弱

的。我對彙編懂得也不多,是以我決定開始仔細收集防破解(Anti-Crack)的技巧。我也努

力“從另一方面努力學習”,你在這裡看到的許多技巧我都是從典型的破解技術中捉摸出來

的,包括網上各種各樣的破解指南和閱讀甚至是由專業破解者給出程式保護技巧(他們給我

們這些技巧以給自己更大的挑戰),我希望自己學得足夠好,也想把我的經驗在此與大家分

享,有些技巧可能已經在其它文章中有所提及,但在此列出的最為完整。許多技巧都是針對W

indows的,但他們可以被移植到其它作業系統中去。

這篇問答集是全新的,如果你覺得我遺漏了一些要點或者有用的、一個典型的Delphi程式員

可以簡單的加入其程式,以加強對程式保護的技巧,請告訴我,如果你允許,我會把它加到

這裡,否則我會告訴你我對它的體驗。

不要問我問題,我可能無法回答:

1) 我已經提到,我對底層的東西沒有什麼研究;

2) 我不會把範例檔案發給你,因為我沒有準備過釋出任何東西,如果我有一些,那麼都在

這裡了;

3) 最後,我不會提供任何人我發現這些技巧的連接配接,請記注,這是一個專注于程式設計的站點

,而非提供可利用的破解程式。需要更多的保護程式的資訊,可以看我的DELPHI技巧頁。

--------------------------------------------------------------------------------

最後,這裡是:

如何使破解你程式的人感到頭疼

(技巧未按其重要性排列)

--------------------------------------------------------------------------------

不要用有意義的過程名字,例如: function RegistrationOK: Boolean;//譯者按:注冊确

無論你在函數中編碼多麼奧妙和複雜,無論你相信于否一個有經驗的破解者都會在10-20秒

内删除之。

作為一種選擇,你可以把程式中需要的一部分代碼置入其内,如果破解者禁止了這個函數,

你的程式将産生錯誤的結果。

不要用有意義的檔案名比如License.Dat.。

用類似Asymetric(美國軟體公司,代表軟體Toolbook)的加密. 僅僅不尋常的檔案名常常

是不夠的,好的加密(編碼)可以讓破解者忙幾個月(如果他願意)

加上長時間延遲,當發現被自身被損壞時,不要發出警告,随後開始等待,也許是一或兩天

(破解者讨厭者東西)。

加入短暫延遲,當輸入密碼或做其它檢測時,停一到兩秒鐘,使窮舉無法繼續。簡單易行,

但用處不大。

使用互相檢查,在DLL和EXE中互相檢查,這遠談不上安全,但可以使破解變得更困難。

在軟體中使用自我修複,你知道就像糾錯Modem和容錯硬碟,這技術已經有許多年了,怎麼

沒人用在保護軟體上?這方法最大的優點是:如果破解者使用反編譯工具,它會見到一串無

用的清單。

修補你的軟體!把代碼變為每次調用不同的确認程式段,用“其人之道還治其人之身”。

把序列号放在不尋常的地方,比如資料庫字段的屬性中,經常聽到或讀到,“用一個DLL的

名字,然後把它放到系統目錄裡”,聽的太多了,不要用哦

防爆破 轉貼

把序列号放到不同的地方。

不要依靠系統時間,從一些檔案取得時間,比如SYSTEM.DAT,SYSTEM.DA0和BOOTLOG.TXT,

把它們和系統時間進行比較,要求它們比上次運作的時間晚(但是記住,許多使用者近來在捉

千年蟲)。

不要用明文字元串告訴使用者:"對不起,不過...(或類似的東西)"這些是首先尋找的目标,

動态建立字元串或者加密它們。

用僞造的程式調用和字元串來灌水。

不要使用一個确認函數,每次你确認使用者,把确認代碼寫在目前過程中。這樣隻是讓破解者

做更多的破解工作。

使用“保留字”,當使用硬密鑰或密碼時,使它們看來像程式代碼或者函數調用 (比如., "

73AF" 或 "GetWindowText"

防爆破 轉貼

。這确實工作的很不錯,可以迷惑一些反編譯工具。

沒有“禁止”特征,如果你的程式有不儲存資料版本(Crapware Version),不要包含“灰”

色菜單項。沒有儲存項等于沒有儲存,就那麼簡單。

避免不必要的提示資訊,唯一提醒使用者他尚未注冊的隻是“關于”對話盒,此對話盒要動态

建立,以便保密。這有兩個原因:許多程式員有這樣的觀點:多餘的提示資訊會在他們的顧

客中産生敵人,這是愚蠢的。一個可能是更重要的原因是:多餘提示資訊會引導對你代碼的

反向工程而且經常直接引導至你的程式保護代碼。

經常更新,頻繁的更新指:經常更換代碼,典型(簡單)的破解隻修改你的硬位元組代碼位置

,這可能當它還未面市已經過期了。并且保證上載礿iao蔔衿鳎鼓憧梢願玫目刂瞥縧?br /> ,人們無法找到破解所針對的舊版本。是的,這樣無法防止包括舊版本和破解包盜版,如果

他們那麼做了,你至少可以為把他們的硬碟擠滿而做點貢獻。

最後,花點時間考慮保護你自己的軟體。它是否值得保護?它是否更應該改進你的軟體?如

果沒人用你的軟體,保護也就沒有意義了,不要過高估計你軟體“對世界的重要性”。

--------------------------------------------------------------------------------

你可以考慮到的更多技巧

--------------------------------------------------------------------------------

用一個連續的幾KB長的數學公式使任何想破解它的人精神崩潰。這使用一個密碼生成器幾乎

無效——阻止窮舉攻擊也是有效的。

小心運作時刻庫!當寫BETA版時,完全使用之,在正式版中重寫部分函數,這至少可以使破

解者的生活更艱苦些。

毀壞結果,毀壞結果有時是保護程式的有效措施。

例如:想象一個圖表程式,或者類似的程式,隻是禁止列印然後根據一些注冊碼恢複列印是

最常見的毀壞結果的程式。允許你列印。當産生要列印資料結構時,用某種方式破壞之,在

列印前根據注冊碼或其它東西恢複。甚至,讓破壞更奧妙,假設你有一個餅形圖要列印,不

改變任何東西,但加入一些不大的随機數值在你的資料中——這樣就破壞了。圖表看上去“

不是很糟”,但是無論如何将無法使用(比如,如果是按20%的随機次序改變的)發現這樣

的保護,如果這和注冊碼相關聯,無疑會使破解需要更對的時間,一是必須深入你内部的數

據結構并找到可怕的破壞和恢複資料代碼。

陷阱,一個我不太肯定,但聽說有程式使用的方法:用CRC校驗你的EXE檔案,如果它被改變

了,不要顯示典型錯誤資訊,等一天,然後用意思含糊的錯誤代碼通知使用者,當他們和你聯

系并告之錯誤代碼時,你知道,是因為被破解了。記注:這樣的陷阱可能被病毒或下載下傳錯誤

所觸發,當你譴責可能是你未來的客戶前,先考慮所有可能性。

不要依賴EXE壓縮程式,幾乎任何EXE壓縮程式(Shrinker, WWPack32, NeoLite ——和所有

著名的壓縮軟體)都有反壓縮程式,是以,壓縮程式的保護能力至少支援可配置的編碼。以

上(和其它)壓縮程式的反壓縮軟體并未廣泛流傳,但是,不要依賴那些軟體作為你程式僅

有的一個“保護”。

--------------------------------------------------------------------------------

進階技巧——從彙編來的奇想

--------------------------------------------------------------------------------

rcr/rcl 把戲

如果RCR/RCL執行某值,對于破解者來說是痛苦的——在不知道最初操作時轉送标志(Carry

Flag)的值的情況下,你無法逆轉之或否定其作用,如果轉送标志是由一些其它煩瑣的關

鍵操作所産生的話,那麼你幾乎勝利了。

到處貼條件轉移

條件跳轉對于反向工程來說并不有趣。沒有循環,隻是跳轉,作為有條件的路障,包括你那

些可愛的KEY處理代碼。這樣,沒有簡單的反向操作可以執行。

使用部分代碼作為奇妙的數字表。

(更适合評論部分)如果你像多數的破解者或喜歡用SOFT-ICE(一個流行的破解工具)改東

西,你無法想象這會有多惱人,

和破解者鬥智

這部分很有趣:-) 貼上連續的NOP,就像你在做自我代碼修改(天啊,什麼亂七八糟的,NOP

?哈!自我代碼修改!白癡會花三年去捉摸那些本來該是什麼東西)。混亂的注釋代碼。把

代碼分成小塊,把它們遍布在可執行代碼中,在它們中間使用(最好是有條件的)跳轉。

提早發現SoftIce.。

現在搞垮計算機,你可以搞垮奔騰或奔騰MMX計算機甚至不需要VXD,可以用操作碼: F0 0F

C7 C8 (非法的帶鎖定字首的 cmpxchg8b 指令). 處此之外, 我們必須采取真正的措施:使

用VXD把CPU帶出保護模式。Windows 不喜歡那樣,奇迹?另一方面,不要浪費太多的時間去

寫破壞反彙程式設計式或調試的代碼。那沒用,相信我,有人寫了那些東西,另一些人立刻會有

辦法繞過它,是以,把你的興趣轉移到更重要的地方——那些容易且很快見效的措施,就像

上面的技巧。

--------------------------------------------------------------------------------

針對DELPHI控件的破解

--------------------------------------------------------------------------------

讓我們了解一些關于Borland公司新開發工具的核心吧。這些知識會使我們加快破解的速度

,當然也使那些共享軟體程式員更小心的使用Delphi,輕易的把他們的“秘密”暴露在那些

好奇的目光下。

VCL是指Visual Component Library(可視化元件庫),它近來被Borland的可視化程式設計工具

所使用,比如Delphi和C++Builder。

這些環境使用特有的資源格式,在Resource Workshop(Borland編輯資源的一個工具)中顯

示為“RCDATA'”。這些資源中含有Delphi所謂的窗體(Forms),窗體是程式的視窗(Wind

ows)。所有對視窗的設計的資訊都包含内,當一個典型的Delphi程式開始運作時,其初始

化代碼建立這種窗體,并從資源中讀取所需要的資訊。有時,這種讀取會被推遲——不常用

的窗體在需要時才被建立和删除。這樣的機制是Delphi的最大優勢也是其最大的缺點。它大

大提高了程式設計的速度,但是對于整個應用程式,它減慢了程式被調用時的速度

這部分中真正有趣的是:例程(被用來響應使用者界面的窗體的元素)的位址是按名字邦定的

。是以隻要知道這些名字,我們就可以知道所需要的位址。

如果你曾經破解過我的Delphi程式,你一定對那些煩瑣的庫之間的調用,比如API調用斷點

(breakpoint)和類似“do xx”的代碼。

[讨論一個十分有名的用Delphi寫的應用程式] 就像你将見到的那樣,我徹底的破解了它,

而且十分輕松。我第一次安裝以後一個星期後,我發現了一條令人厭惡的資訊——“你的測

試已經過期”。

首先要做的是使用資源或窗體探測(SPY)工具收集有關目标EXE檔案的有關資訊。你也許會

想到去檢視TVALIDATORDLG——很明顯,使用者名和注冊碼是由此輸入的。但是你會發現那隻

是一個簡單的對話盒,真正的工作是由其調用者TSPLASHFORM來完成的。這是個惱人的視窗

,它在程式關閉、按“關于”按鈕和程式開始部分不斷出現。

你可以選擇TsplashForm并且以文本格蔶iao鄄熘9赜诎磁ィ˙utton)和标簽(Label)的許

多資訊都将被很清楚的顯示。讓我們注意以下部分(接近最後):

object RegButton: TButton

Left = 200

Top = 176

Width = 97

Height = 25

Caption = 'Register'

TabOrder = 1

OnClick = RegButtonClick

end

這是什麼?這是帶有“注冊”标題的按鈕。你可以看到它的大小,位置......和一個有啟發

性的名字——“OnClick”。 “OnClick”告訴我們當使用者按注冊按鈕時所調用的例程,當

我們有了名字(Name),我們可以搜尋例程的位址。這是因為例程是和按鈕以名字(Name)邦定

的。

使用一個十六進制編輯器觀察"RegButtonClick",我發現了兩次,第二個是資源本身,第一個

是在位址表(Address Table)中的。

000A4990 ____ ____ ____ BC57 4A00 0E52 6567 4275 ______.WJ..RegBu

000A49A0 7474 6F6E 436C 6963 6B__ ____ ____ ____ ttonClick_______

現在,觀察名字(Name)前那寫神奇的數字,有一個位元組('0E')指出了"RegButtonClick"

的長度(14 個字元)。而且,在此之前有其位址:004ABC57。

有的反彙程式設計式會以為檔案太長,并且不能正确反彙編這部分——然而,使用特殊的工具,

我們可以在此停止,對了,就停在我們按按鈕的部分。

這些會使你發現一個調用(CALL)。跟蹤之,你會在44ECC8發現一個“标準棧架構(standa

rd stack frame)”:

0044ECC8 55 push ebp

0044ECC9 8BEC mov ebp, esp

這是一種程式員所寫的,在進階例程開始部分所需要的東西。我們已經避開了一長串由Wind

ows通知(Notification)所産生的VCL庫調用,來到了正确的位置。

在此,你可以友善的用設定斷點的方法來測試一些調用——你會發現它們是用來顯示要求輸

入使用者名和密碼的對話盒。然後,注冊碼是由使用者名和使用者的輸入比較所産生的。你可以輸

入你所選擇的使用者名,和任何東西作為注冊碼,在BPX到44ED69之後,一個調用一個例程用

來比較兩個字元串。D EDX會顯示你輸入(冒牌)的注冊碼,EAX會顯示正确的注冊碼,簡單

吧?初學者隻需10分鐘就可以完成,

如何避免被類似的程式破解?

閱讀我以上的技巧。最基本的是不要用由輕按兩下按鈕或有屬性螢幕(Object inspector.)

生成預設的方法,在程式的其它部分寫代碼,最好是在另外的模闆中,然後用類似以下的代

碼與按鈕關聯:

RegButton.OnClick := RegButtonClick;

當然你需要在窗體建立時(被調用前)執行這段代碼,最好是被一些無關的例程所調用,當

然這遠遠不能防止你的程式被破解,但至少不會像你剛才看到的那樣容易。

--------------------------------------------------------------------------------

關于注冊碼的提示

(如果你無法避免它)

--------------------------------------------------------------------------------

在安全,可行性,可程式設計性和最終使用者的頭痛間尋求平衡。

太長的,無字母的注冊碼可能造成連續的輸入錯誤。考慮要求輸入确認域(多數是密碼),

或者至少提供一個“不固定”的注冊碼輸入域,以便使用者可以每次重寫注冊碼,也許最後正

确的輸入了。許多人會僅僅“瞥一眼”以比較輸入的注冊碼和他們所收到E-Mail裡的注冊好

,他們最終認為,他們輸入了正确的注冊碼。但是字型太小或者他們懶得注意到底“I”和

“1”被交換了位置(就像'l83jjd_0)pH1lTe' )。

根據不同使用者的回報,注冊碼輸入區必須無限制的接受任何長度的資訊。不要讓破解者了解

你的注冊碼的類型——如果你采取“線上确認(online-verification)”并顯示它有10個

字元長或隻接受大寫字母将給予他們幫助——不要這樣做!

計算潛在使用者的數量!沒有比這樣的事更壞的了:你把使用者數限制在9,999,你不希望有第

10,000個使用者,因為如此你就必須更新你的注冊碼以滿足這第1,000個使用者。

如果你的注冊碼有10位,可能有10^10個注冊碼。但是,你的應用程式可能隻允許10^4(10

,000)個使用者,你必須采取某種算法使10^4個使用者每人一個得到10^10個注冊碼中一個。這

保護了使用者和你的應用程式本身受到窮舉攻擊(就像一個使用VXD的宏播放器那樣)。如果

隻有10^4個使用者,而你定義了10^9個合法的注冊碼,那麼平均每試10次,就會有一個“合法

”的注冊碼。然而,在預期隻有10^4的情況下,平均每10^6次才會成功。即使是使用高速的

計算機和極快的宏播放器(擊鍵模拟輸入注冊碼),要在10^6中尋找到需要的注冊碼所花費

的時間也是無法計算的。

從使用者名(User name)到注冊碼(Registeration code)不應該隻有簡單的運算,它必須

是有既精通數學又精通彙編語言的人用彙編語言實作(記注,Delphi仍然允許你直接使用彙

編(ASM)代碼)!然後,檢查你的操作,繪制流程圖,了解它是如何工作的。要徹底了解

你自己的工作,特别是它的不足之處。

要有創新意識,不要用任何看起來簡單、迅速、有效的東西,除非你信奉類似愛因斯坦的相

對論的學說。你的方法的确是簡單,也的确是迅速,但是絕對不是有效,的确是容易被破解

。我十分抱歉,我并非天才,沒有找到一種行之有效的保護方案能維持太長時間。

隻是些想法

防爆破 轉貼

Richey

摘自《hubdog未經證明的葵花寶典

傳回:

ElGamal算法

  ElGamal算法既能用于資料加密也能用于數字簽名,其安全性依賴于計算有限域上離散對數這一難題。

密鑰對産生辦法。首先選擇一個素數p,兩個随機數, g 和x,g, x < p, 計算 y = g^x ( m

od p ),則其公鑰為 y, g 和p。私鑰是x。g和p可由一組使用者共享。

ElGamal用于數字簽名。被簽資訊為M,首先選擇一個随機數k, k與 p - 1互質,計算

a = g^k ( mod p )

再用擴充 Euclidean 算法對下面方程求解b:

M = xa + kb ( mod p - 1 )

簽名就是( a, b )。随機數k須丢棄。

驗證時要驗證下式:

y^a * a^b ( mod p ) = g^M ( mod p )

同時一定要檢驗是否滿足1<= a < p。否則簽名容易僞造。

ElGamal用于加密。被加密資訊為M,首先選擇一個随機數k,k與 p - 1互質,計算

a = g^k ( mod p )

b = y^k M ( mod p )

( a, b )為密文,是明文的兩倍長。解密時計算

M = b / a^x ( mod p )

ElGamal簽名的安全性依賴于乘法群(IFp)* 上的離散對數計算。素數p必須足夠大,且p-1至

少包含一個大素數

因子以抵抗Pohlig & Hellman算法的攻擊。M一般都應采用資訊的HASH值(如SHA算法)。ElGa

mal的安全性主要依賴于p和g,若選取不當則簽名容易僞造,應保證g對于p-1的大素數因子

不可約。D.Bleichenbache“GeneratingElGamal Signatures Without Knowing the Secret

Key”中提到了一些攻擊方法和對策。ElGamal的一個不足之處是它的密文成倍擴張。

美國的DSS(Digital Signature Standard)的DSA(Digital Signature Algorithm)算法是經E

lGamal算法演

變而來。

防爆破 轉貼

如何用簡單方法防止破解

http://www.cnsw.org/bbs/viewthread.php?tid=1063

在Debug的手冊裡可以看到Debug工具的局限. 第一個局限是隻能下4個記憶體區域的斷點,每個斷點不能控制超過兩個位元組,這樣記憶體斷點不能控制超過16個位元組的區域. 第二個局限是對多線程隻能同時跟蹤一個線程.

假設你的注冊部分有300行,你可以分成30個inline函數調用或MACRO(一定要inline),func1(),func2()... func30(). 将他們随意放到程式的各個部分,一定不能放在一起(自己能找到就行了)。不要用Memcpy等常用系統調用拷貝注冊碼,近可能自己寫,像Memcpy很好寫,性能差點無所謂。經過編譯後inline函數展開,注冊部分和其他代碼混在一起,他要寫出注冊機就像大海裡撈針,在幾十萬甚至上百萬彙編代碼裡找出有用的注冊部分。

利用Debug的第一個局限最重要的一點是:注冊碼也不要放在一起,假設你的注冊碼是12位,千萬不要用一個12位的數組放注冊碼,你可以在程式的不同位置定義12個全局字元變量,每個放一位,這樣注冊碼在記憶體就不連續了。最好再加密處理一下(簡單的字元異或就可以),驗證時再解密。也不要用連續記憶體儲存驗證用到的變量,盡量将用到的驗證臨時變量分散定義在程式的不同處,再在驗證中,不斷轉移一些值到其他變量中,對付暴力和Loader會比較有效。

沒有必要用複雜的加密算法,更容易成為追蹤的目标。隻要你将注冊部分隐藏的足夠好,也沒有漏洞,你花1天寫的加密算法,破解者可能會花100-1000倍的時間破解。大部分人都會放棄。

你将注冊做在一起,就像将你的财寶放在現代保險箱裡,雖然非常堅固難以解密,對于開鎖高手兩分鐘就打開了。

而古代海盜用的方法是将财寶埋在海島上,這樣沒有藏寶圖,對應高手和低手都隻有一條路,拿一把鐵撬挖,可能要挖一生。程式有那麼多代碼,反編譯出來可能超過百萬行,你将注冊部分藏在裡面,藏的好就如同将财寶埋在海島裡。那些所謂的Crackme隻是給高手玩兒的現代保險箱而已,用原始的方法可以達到同樣效果。

1. 讀完注冊碼後不要立刻檢查注冊碼,因為讀注冊碼肯定用到系統調用,系統調用附近很容易下斷點。先放到記憶體作為全局變量,然後你可以在程式的任何部分,任何時候,讀注冊碼,讀記憶體是沒有任何系統調用的.

2. 兩種辦法處理在記憶體的注冊碼,

  一種方法是在檢查前分散隐藏注冊碼,這樣他們無法從記憶體中搜尋到注冊碼出現的位置,因為他們會在注冊碼出現位置附近下斷點。

  還有一種方法是正好相反,你可以在讀到注冊碼後,多次将注冊碼在記憶體(用Malloc配置設定多處)的各個位置做大量拷貝,這最多浪費一些記憶體。16Bits的注冊碼做10000份拷貝也隻用160K記憶體。如果不用Malloc配置設定這些記憶體,那麼最好和其他程式使用的全局變量互動混在一起(這樣即使破解者用HEX 編輯器打開并搜尋你的程式中使用那部分記憶體的代碼,也無法将正常程式資料和注冊碼區分出來). 你不要立刻檢查注冊碼,10000份拷貝你隻要以後随機找一份用就行了,破解的人不知道你正在用的是那一個. 同時你可以不斷生成一些假的讀取記憶體注冊碼的調用幹擾破解者。這種方法對程式的性能影響微不足到,隻是浪費一點記憶體。因為Debug對記憶體下斷點的局限,這種情況他要下斷點,累死的就是破解的人了.

3. 程式多處做CRC校驗檔案大小檢查,發現不對就退出。一定要多處檢查,不能隻檢查一次。

4. 用inline函數将注冊部分分成許多小塊,分散到程式各處運作。最好能放在不同的線程中運作. 檢查結束不要給任何提示,在程式中的記憶體中做一個标志即可,提示資訊要延遲一段時間出現,不要讓破解者通過提示資訊找到标志位置或檢查結束位置,否則前功盡棄。當然也可以象上面那樣做10000個标記,随機用一個,這時你不用擔心破解者知道标記的位置.而且标記最好不要用0或1,可以用一個貌似随機的值作為注冊成功的标記,如何産生這個随即值隻有你自己知道.

什麼算法無所謂,最終目的就是讓破解者的作用發揮不出來。和古代海島藏寶一樣,你隻要把檢查痕迹很好擦掉分散,破解高手的用處就發揮不出來。破解者玩的Crackme就是保險箱,如果是開鎖高手,目标明确總能打開,不行還可以用炸藥。但到海盜的藏寶地點,任何開鎖高手都沒有用。

這種方法用的好的結果是你容易創造檢查注冊碼的方法,自我創造發揮的餘地很大,而對破解者會很麻煩,他搞不清楚你在幹什麼,你隻要讓破解者感覺象是蒙着眼睛走迷宮或者在猜沒有謎題的謎語就行了. 而且對你來說更換算法也很容易,因為可能根本沒有算法,隻有謎語和迷宮。要充分利用程式反彙編後代碼多這個特點,除了讀注冊碼的時刻,其他時候根本沒有系統調用,除了記憶體,根本無處下斷點. 而你使用複雜的加密算法通常的結果是你麻煩,破解者很容易,因為各種加密算法都已經研究透了,而且用複雜的加密算法的調用或系統調用立刻暴露你檢查注冊碼的位置,為暴力破解提供了友善。

我和很多人一樣,也是不會彙編語言,而且程式一出來就被0day破解,而且幾乎每一個版本它們都要破解. 苦于不會彙編,也不太了解破解流程,隻好去看SOFTICE的手冊,想了這麼一個簡單的方法. 0day雖然它們經驗豐富也能破解,而且似乎也逐漸了解和改進對我的程式的破解. 但許多破解是壞的,根本不能用. 而且就是被破解後,隻要将這些inline調用和全局記憶體變量的位置稍微變一變(大概隻需要2-3個小時),它們下一次的破解又是壞的. 而且我還沒有完全使用上面的方法,例如我還沒有做10000份的記憶體拷貝或10000份的标記. 因為隻是簡單的用inline和将注冊資訊與其他全局變量混在一起,現在就已經夠了,0day的暴力破解就經常會破壞正常程式資料.

繼續閱讀