【.net程序破解】實戰之標志位破解繞過注冊法


今天有時間玩了下一個不錯的軟件Advanced System Cleaner,可惜要注冊
於是想辦法給破解了,這是跟之前不同的地方,屬於.NET破解教程:
軟件地址 - http://www.crsky.com/soft/9213.html

對於我們來說,.net最大的特點就是可以“跨平台”。大多數運行在Windows下的軟件都不能很好地支持Linux,也就是說在Windows下能夠正常使用的軟件在Linux下不能正常運行,這樣就很不方便日常的學習和交流。但是有了.net,這一切就發生變化,不管我們的操作系統是什么,只要裝有.net,這個系統就可以運行.net的所有語言。
.net包含很多語言,對於破解來說,我們只需要了解.net的開發語言就可以了。.net的開發語言主要包括C#.net、VB.net、C++.net、J#.net等,這些也是最常見的。最重要的一點是,雖然VB和VB.net語言看起來類似,但是其內部運作是完全不同的。這一點一定要注意。關於.net就先介紹到這里,更多的細節大家會慢慢體會到的。
目標篇
我們的目標軟件是Advanced System Cleaner,一個功能很強大的系統清理軟件,可以方便地清理系統中的垃圾文件和注冊表。
按照破解的一般步驟,照例用PEiD檢查一下,看到了嗎?檢查結果是“Microsoft Visual C# / Basic .net”,如圖1所示。很明顯,這是一個.net系列的軟件,一般的破解工具拿它是沒有辦法的,所以必須有合適的工具才能完成我們的任務。
21928814_1
圖1
工具篇
.net程序對於破解而言,可以算是一個嶄新的領域,不論從破解的手段還是方法來說,都是一個全新的挑戰。破解手段需要改變,破解方法也需要更新。僅從使用工具這個方面來看,我們就可以發現不小的變化。對付普通的軟件,主要用OllyDBG或者是W32dASM就可以輕松搞定了;但是對於.net程序,這兩個工具就顯得力不從心了,基本無從下手。那破解.net程序的工具有哪些呢?破解的第一步依然是檢測軟件的基本信息,如何對.net程序進行檢測呢?這個很簡單,就像對待一般的程序一樣,用PEiD就可以搞定了,使用的方法也沒有任何變化。
要繼續破解.net程序,我們就得認識兩個新朋友:Reflector和UltraEdit32。Reflector是對付.net程序的殺手鐧,它可以輕易地將.net程序進行反編譯,就好像是OD或W32dASM一樣,幫助我們完成分析程序的任務。當使用Reflector反編譯一個程序之后,我們就可以根據反編譯的結果進行進一步的分析了,比如說尋找注冊信息、定位關鍵代碼等。這里要說明的是,在Reflector中我們是不能修改程序的代碼的(不像使用OD可以任意修改程序的代碼),這樣一來問題就出現了,怎樣修改.net程序中的代碼呢?這時就要用到UltraEdit32了,其用處就是用來修改關鍵代碼的,與在OD中修改跳轉或是標志位來達到破解程序的效果一樣。
總的來說,對於.net程序,目前還不能只憑一個工具打天下,必須把不同的工具結合起來使用才能達到目的,正如這里的Reflector與UltraEdit32。如果把破解軟件比作是用導彈炸毀一個目標,那么Reflector的作用就是這個導彈的導航系統,用來尋找方向和定位目標,UltraEdit32則是導彈的戰斗部,肩負炸毀目標的重任。
操作篇
用Reflector打開我們的目標軟件,稍等片刻Reflector就幫我們把程序分析完畢了,但Reflector似乎沒有什么明顯的反應,如圖2所示,沒有像OD那樣出現一大片的代碼。如何在Reflector中看到分析的結果呢?此時注意Reflector主界面上的變化,比打開目標程序之前相比多了一項“ASC”,它是什么呢?它就是我們的目標程序了,只要單擊這一項就可以看到Reflector為我們分析的結果了。
21928814_2
圖2
打開之后會發現這里有兩個選項,一項是“ASC.exe”,另一項是“Resources”。第一項“ASC.exe”中的內容是Reflector為我們分析好的信息,而“Resources”中包含的內容則是程序用到的一些資源文件,比如圖標、圖片等。我們關心的當然是分析好的程序信息了,所以打開“ASC.exe”一探究竟。很明顯,又現了四個不同的子項,這里我們選擇“AdvancedSystemCleaner”這一項打開,如圖3所示,更多的內容又出現了。在新出現的幾個選項里,我們選擇“Module2”打開,有沒有發現打開這一項后出現的選項里有一個內容與“Register”有關?經過層層的選擇,總算出現了與注冊有關的內容,當然要提高警惕了,如圖4所示。我們打開這一項看看,看到了嗎?“GetRegCodeValue”、“GetRegName” 這些非常有用的內容已經擺在我們面前了,如圖5所示。選擇“Registed”這一項打開,發現並沒有出現新的子項,而是在旁邊新開了一個窗口,里面有一些很讓人迷茫的代碼,如圖6所示。不過現在我們已經可以肯定了,這些代碼與軟件的注冊必然存在一些關系。既然可以肯定這一點,那么目前的主要問題就是如何去看懂這段代碼了,如果可以成功地理解這段代碼的含義,那么最少也可以尋找到一些與軟件注冊有關的信息,幸運的話,也許這段代碼就是軟件注冊的核心代碼。若找到了核心代碼,剩下的工作就會像在OD中破解軟件一樣,痛痛快快地修改代碼了。
21928814_3
圖3

21928814_4
圖4

21928814_5
圖6
於是,現在的主要問題就是如何去看懂這段代碼了。想要看懂這段代碼,先得把它轉換一下。我們再一次關注Reflector的主界面,看到有一個下拉菜單,目前顯示的是“IL”,打開菜單,在選項里選擇“C#”,如圖7所示。為什么要這樣做呢?簡單地給大家解釋一下。回憶一下用OD破解的過程,當我們用OD載入准備破解的軟件之后,OD會把分析的結果顯示出來,這個分析的結果是以匯編語言的形式顯示的。類似的道理,Reflector也需要通過一種方式把分析結果表示出來,於是我們就在Reflector中看到了上面提到的代碼。但是與OD不同的是,OD是通過匯編語言來顯示結果的,而Reflector則是用“IL”語言顯示出來的。 
21928814_6
圖7
小提示
MSIL是將.Net代碼轉化為機器語言的一個中間過程,它是一種介於高級語言和基於Intel的匯編語言的偽匯編語言。這里的“IL”語言我們是不容易看懂的,所以就要轉換成一種比較容易理解的語言。相比較“IL”而言,“C#”代碼更容易被我們接受。
選擇“C#”之后會彈出一個對話框,我們不用關心里面的內容,單擊“OK”就可以了,如圖8所示。之后Reflector窗口中的內容會發生變化,“IL”語言已經被轉換成標准的“C#”代碼了,清晰多了。到了這一步,我們就可以仔細地分析一下這些代碼了。21928814_7
圖8
分析篇
我們就從第一部分代碼開始看吧,完整的代碼如圖9所示。稍微有點編程基礎的朋友可以很容易地發現,這是一個“IF條件語句”,我們試着來把這段代碼翻譯一下。 
21928814_8
圖9
首先,程序在這里給兩個變量賦了值,代碼如下。意思是將“GetRegName()”里的值賦給“left”這個變量,將“GetRegCodeValue()”里的值賦給“regCodeValue”。
string left = GetRegName();
string regCodeValue = GetRegCodeValue();
接着,程序開始對變量的值進行判斷,代碼如下。意思是如果“regCodeValue”這個變量的值等於0,並且“left”這個變量的值也等於0,那么“blnRegistered”這一項的值就是“false”。有編程基礎的朋友可能已經看懂了,可是對於小菜們來說還是很生澀,怎樣理解這句代碼的含義呢?其實我們可以這樣簡單的理解。如果注冊名的內容等於0,而且注冊碼的內容也等於0,那么就提示使用者“軟件未注冊”。
if ((Operators.CompareString(regCodeValue, "", false) == 0) | (Operators.CompareString(left, "", false) == 0))
{
Module1.blnRegistered = false;
}
小提示
簡單理解“Module1.blnRegistered = false”的意思就是,軟件的注冊狀態為“假”,那就是軟件“未注冊”嘍!
理解了這句代碼的含義,新的問題又出現了!這段代碼里沒有具體的注冊信息收集過程,也沒有明顯的算法計算,程序為什么要做這樣的一個檢驗呢?這就要從軟件的“注冊檢驗流程”開始說起了(為了方便說明問題,暫且把這個過程叫做軟件的“注冊檢驗流程”)。“注冊檢驗流程”是一個怎樣的過程呢?我們一起來想象一下這個過程。
首先,軟件運行起來了,由於是共享軟件,所以在使用上就會有注冊版和未注冊版之分,兩者有很大的區別。比如未注冊的版本不能使用軟件的全部功能,或者在使用時會有時間限制等情況。於是在剛運行的時候,軟件就會判斷當前的使用者是不是注冊用戶。如果是“未注冊”的用戶,那么就有各種各樣的限制;如果是已經“注冊”的用戶,那么就可以正常的使用軟件。到此就出現了兩種情況,一是發現使用者是注冊用戶,就會顯示“軟件已經注冊”等之類的信息;二是發現使用者是未注冊用戶,就會顯示“軟件試用期是××天”等這樣的信息,並且會要求使用者輸入注冊名以及相應的注冊碼來注冊軟件。
如果是第一種情況,就沒有接下來的過程了。如果是第二種情況,在用戶輸入了注冊名及注冊碼后,程序還會對注冊碼的有效性進行檢驗(這就是以前所說的算法過程)。如果注冊碼合法就注冊成功,用戶就變成了注冊用戶,進而可以正常的使用軟件。如果注冊碼不合法就注冊失敗,用戶依然處於未注冊狀態。
軟件的“注冊檢驗流程”簡單的來說就是如上所述的一個過程。大家可以很容易地看出,如果軟件在運行時發現當前的使用者是一個已經注冊的用戶,那么后面諸如“提示軟件試用期”、“要求輸入注冊碼”就不會出現了。
回到我們所分析的軟件中來,大家是不是發現剛才所解釋的那一段代碼,似乎正是這個作用呢?這段代碼的作用就是檢驗當前的用戶是否是注冊用戶,當然了,這段代碼也正是在軟件開始運行時就起作用了。這段代碼就先分析到這里,我們來看看后面的代碼。
else
{
string text3;
string text4;
string strValue;
string text6;
try
{
text3 = regCodeValue.Substring(1, 5);
text4 = regCodeValue.Substring(6, 5);
strValue = regCodeValue.Substring(12, 5);
text6 = regCodeValue.Substring(0x12, 5);
}
catch (Exception exception1)
{
ProjectData.SetProjectError(exception1);
Module1.blnRegistered = false;
ProjectData.ClearProjectError();
return;
ProjectData.ClearProjectError();
}
if (Operators.CompareString(text6, GetRegisterCode(text3 + text4 + Module1.ainfo.Version.Substring(0, 4), strValue), false) != 0)
{
Module1.blnRegistered = false;
}
else
{
Module1.blnRegistered = true;
}
}
}
開頭的“else”是與上一段的“if”相對應的,我們把注意力放在最后幾句的“if”代碼上。這段代碼的意思就更明顯了,有一點編程基礎的朋友已經很清楚它的意思了,不過還是給大家翻譯一下吧。如果“括號”里面的條件成立,那么軟件就注冊失敗,否則軟件就注冊成功。
我們可以看出這是一個很經典的注冊驗證過程,當檢驗完畢注冊碼的有效性之后,就根據檢驗的結果做出不同的反應,如果注冊碼有效就注冊成功,如果注冊碼錯誤就注冊失敗。由於這種注冊驗證的方法十分容易被破解,所以在一般的軟件中已經很難見到了,但由於這是一個.net程序,所以破解起來就會有一定的難度了。如果是一個普通軟件,下一步該如何去做,大家肯定都知道了,只需要在OD里修改相應的跳轉就可以了。這樣一個有着明顯的注冊判斷的程序,最簡單的辦法就是“暴破”。一般軟件的暴破我們都已經很熟悉了,那.net程序又該如何去暴破呢?
修改篇
找到了關鍵的代碼,我們如何去修改它呢?現在還不能直接用UltraEdit32,因為目前我們還不能在UltraEdit32中找到這一段關鍵的代碼,繼續注意Reflector中的內容。
還記得開始的時候,我們為了讀懂Reflector反編譯出來的代碼,特意把“反編譯選項”中的“IL”改成了“C#”,進而根據代碼的提示找到了注冊驗證的關鍵部分,但是現在的任務是想辦法在UltraEdit32定位這一段關鍵代碼,如何做到這一點呢?
首先要把分析時調整的選項再次調整一下。具體來說就是在“反編譯選項”中將“C#”再一次調整為“IL”,這樣反編譯的代碼又發生變化了,就在這代碼的海洋里尋找吧!這里就以注冊驗證的那一段代碼為例吧。轉換之后的代碼如下所示。
L_00b8: stloc.s flag
L_00ba: ldloc.s flag
L_00bc: brfalse.s L_00c9
L_00be: ldc.i4.0
L_00bf: stsfld bool AdvancedSystemCleaner.Module1::blnRegistered
L_00c4: nop
L_00c5: br.s L_00d2
L_00c7: br.s L_00d0
L_00c9: nop
L_00ca: ldc.i4.1
L_00cb: stsfld bool AdvancedSystemCleaner.Module1::blnRegistered
我們都知道,這里只是代碼的表現形式發生了變化,代碼的作用和含義是不變的。我們看看這兩段截然不同的代碼有什么樣的聯系!找來找去只發現有一個共同的標志“:blnRegistered”。繼續仔細觀察,在兩段代碼中“:blnRegistered”都出現了兩次,從C#代碼可以看出,第一次出現“:blnRegistered”對應的是注冊失敗的情況,因為“Module1.blnRegistered = false”意思就是注冊為“假”;第二處則是“ Module1.blnRegistered = true”,應該就是注冊成功了。這段代碼經過轉換之后,注冊成功與否的標志又是什么呢?我們來觀察這幾句代碼。
第一次出現“:blnRegistered”的情況是這樣的:
L_00be: ldc.i4.0
L_00bf: stsfld bool AdvancedSystemCleaner.Module1::blnRegistered
第二次則是這樣的:
L_00ca: ldc.i4.1
L_00cb: stsfld bool AdvancedSystemCleaner.Module1::blnRegistered
這兩段代碼基本相同,不同點就是第一段中“ldc.i4.0”出現的是“0”,而第二個則變成了“ldc.i4.1”。因為代碼經過轉換表現形式發生了變化,但意思是不會變的,所以我們就可以確定程序是通過不同的標志位賦值來區分注冊成功與否的。標志位的值等於“0”則注冊失敗,等於“1”則注冊成功。在這其中,“i4”就充當了一個標志位的作用(相當於一般的EAX、EBX等)。
小知識
什么是標志位?以前提到過這個概念,在暴力破解中還有一種方法叫做“標志位暴破法”。“標志位”可以這樣來理解,做一個簡單的比喻,大家都經歷過無數的考試,60分以上就是及格,60分以下就是掛課。那么60就是掛課與否的一個標志。程序檢驗軟件是否已經注冊時會對標志位中的值進行檢查,如果標志位中的值為0,那么就顯示“軟件未注冊”;如果標志位中的值等於1,就提示“軟件已注冊”。好比我們看到了自己的考試成績,一看是55分,完咯,低於60分,很不幸,掛課了!
在軟件的代碼中,標志位本身只是一個寄存器,可以是EAX也可以是EBX,還可以是ECX等。簡單地說,常用的寄存器都可以被用作“標志位”,具體使用哪個就要看軟件作者的選擇了。標志位中最核心的內容就是標志位的賦值情況,具體來說就是選擇一個什么樣的值來作為“標志”。它的重要性就像是老師在選擇60分以上算做及格還是50分以上算做及格一樣,這個分數線直接關系到我們的命運。同樣,標志位的賦值也直接關系到了最后的結果。一般來說,大多數軟件都以1和0這兩個數作為標志位的值,如果注冊成功,標志位的值就自動為1,反之則為0。這里一定要注意,這個值不是一定的,也可以是注冊成功時標志位的值等於0,這全看軟件作者如何設計了。
現在我們的思路就出來了,只需要修改標志位的值欺騙程序,就可以達到破解軟件的目的了。思路有了,下面就要確定修改的位置了,修改哪一段代碼能夠達到我們的目的呢?重新分析一下這個軟件的注冊流程,看看哪個部分可以作為“突破口”。
整理一下思路,軟件的注冊驗證流程是這樣的:輸入注冊碼,注冊碼不正確,標志位就賦值為0,並提示注冊失敗;注冊碼正確,就給標志位賦值為1,進一步提示注冊成功。因為軟件在運行時就會對標志位進行檢驗,所以只要在這里修改標志的值,程序就會一直認為軟件已經注冊了。沒錯,就把程序運行時檢測的那個“標志位”作為修改的目標。
我們回到Reflector中,找到第一處出現“:blnRegistered”的地方,如圖10所示,代碼如下。 
21928814_9
圖10
L_0032: ldc.i4.0
L_0033: stsfld bool AdvancedSystemCleaner.Module1::blnRegistered
很明顯,此時標志位的值為0。如何使得程序認為軟件已注冊了呢?把“ldc.i4.0”修改成“ldc.i4.1”就可以了(改變標志位的值)。現在,修改的地方已經找到了,接下來就要看看如何修改標志位的值了。把鼠標放在“L_0032: ldc.i4.0”這句代碼上停頓1秒鍾,Reflector就會給我們彈出一個提示“0x0016”;同理,把鼠標放在“L_0033: stsfld bool AdvancedSystemCleaner.Module1::blnRegistered”上的時候,Reflector給出的提示是“0x0080”,也就是說,這兩句指令的機器碼是16和80。而我們是要讓“ldc.i4.0”變成“dc.i4.1”,任意找一句“ldc.i4.1”,按同樣的方法,Reflector給出的提示是“0x0017”。現在,我們的任務就更加明確了,就是要把“16”改成“17”,這樣對應的“ldc.i4.0”就改為“ldc.i4.1”了。那么如何修改呢?
至此,Reflector的任務就光榮完成了,下面該UltraEdit32出場了。運行UltraEdit32,打開目標軟件,會發現UltraEdit32給我們的也是一篇代碼的海洋,這時該如何下手呢?還記得上面我們找到的兩個代碼指令“0x0016”和“0x0080”嗎?現在它們可是我們的“指南針”哦。打開UltraEdit32的查找功能(單擊“Search->Find”),在“Find what”欄中填寫要尋找的內容。我們要尋找什么呢?沒錯,就是“0x0016”和“0x0080”,所以我們輸入“16 80”,如圖11所示。 
21928814_10
圖11
小提示
大家要注意查找時輸入的格式。這里要尋找的代碼是0x0016,在輸入的時候只需要輸入16就可以了。依此類推,查找0x0080只用輸入80就可以了。雖然我們要找的是0x0016和0x0080,也只用輸入16和 80就可以了。
輸入完畢后,單擊“Find Next”,UltraEdit32就可以幫我們尋找目標了。當找到滿足代碼為“16 80”的內容時,會自動停在目標代碼上,如果當前找到的內容不是我們所需要的,繼續單擊“Find Next”即可。經過測試,第一次尋找到的代碼並不是我們所要的,所以還要尋找,稍后第二處滿足條件的代碼也被找到了。這里就要提高警惕了,關鍵的代碼很可能就在這里了。仔細觀察這一行代碼,會發現“16”這個數字出現了兩次。不用管它,堅定我們的想法,把這里的兩處“16”都改成“17”,如圖12所示,保存修改后的文件。
21928814_11
圖12
運行我們修改后的程序,把系統的日期調整到一年之后。在正常情況下,軟件的試用期只有20天,一年之后肯定過期了。但是經過修改之后再看看,呵呵,軟件依然可以使用,而且已經是注冊版了。是不是很成功呢?
總結篇
與以往的軟件破解相比,.net程序的破解可以說是翻天覆地的變化。從使用的工具到破解的思路,再到破解的方法,都是前所未見的。但是.net的流行只是時間的問題,所以我們必須要時刻面對新事物的挑戰才能完善自我。

有相關有價值的軟件需要破解可以發我郵箱godisgs@vip.qq.com,注明1軟件官網2軟件價值3破解目標。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM