作者:星痕
e-mail:jrg1982@163.com
破解步驟:
1. 用softice載入windows(通過CTRL+D來檢查softice是否已經(jīng)準(zhǔn)備好,按F5退出softice);
2. 運(yùn)行winzip,選擇“help”下的“Enter Registration Code...”;
3. 在“Name:”中輸入:KraneXH(隨意),“Registration #:”中輸入:12345678(隨意);
4. 用CTRL+D呼出softice,下萬能斷點(diǎn):bpx hmemcpy,按F5返回到winzip;
5. 在winzip中選擇“OK”,很快程序就被softice攔截下來(因?yàn)槲覀冊O(shè)置了斷點(diǎn)bpx hmemcpy,當(dāng)在winzip中選擇“OK”時(shí),winzip會(huì)通過hmemcpy這個(gè)功能去取我們輸入的名字“KraneXH”和注冊碼“12345678”,softice檢測到hmemcpy被調(diào)用,于是就中斷winzip的運(yùn)行,停留在winzip中調(diào)用hmemcpy的地方);
6. 用 bd * 暫停剛才設(shè)置的斷點(diǎn) bpx hmemcpy (為什么要暫停斷點(diǎn)bpx hmemcpy呢?因?yàn)槲覀兊哪康氖且趙inzip取名字和注冊碼的時(shí)候中斷它的運(yùn)行,但是 bpx hmemcpy 這個(gè)斷點(diǎn)并不是針對winzip才有效的,計(jì)算機(jī)里運(yùn)行的程序都可能會(huì)隨時(shí)調(diào)用它。由于我們在winzip中剛輸入名字和注冊碼后設(shè)置斷點(diǎn) bpx hmemcpy ,此時(shí)winzip會(huì)馬上去取我們輸入的名字和注冊碼,所以我們能確保是中斷在winzip程序中,通過 bd * 這個(gè)命令暫停斷點(diǎn) bpx hmemcpy ,能夠防止解密時(shí)被其它不相干的程序中斷,影響解密的正常進(jìn)行);
7. 按F12鍵9次,返回到winzip的領(lǐng)空(因?yàn)閯偛舠oftice中斷在hmemcpy中,這是windows系統(tǒng)區(qū)域,不能更改的,winzip僅僅是調(diào)用這個(gè)功能而已,所以我們必須要返回到winzip程序中才有用),來到下面的地方:
......
0167:00407F6D CALL [USER32!GetDlgItemTextA]
0167:00407F73 PUSH EDI ←- 程序停留在這里,EDI指向“KraneXH”
0167:00407F74 CALL 0043F89A
0167:00407F79 PUSH EDI
0167:00407F7A CALL 0043F8C3
0167:00407F7F POP ECX
0167:00407F80 MOV ESI 0048CDA4
0167:00407F85 POP ECX
0167:00407F86 PUSH 0B
0167:00407F88 PUSH ESI
0167:00407F89 PUSH 00000C81
0167:00407F8E PUSH EBX
0167:00407F8F CALL [USER32!GetDlgItemTextA]
0167:00407F95 PUSH ESI ←- ESI指向“12345678”
0167:00407F96 CALL 0043F89A
0167:00407F9B PUSH ESI
0167:00407F9C CALL 0043F8C3
0167:00407FA1 CMP BYTE PTR [0048CD78]00 ←- [0048CD78]指向“KraneXH”
0167:00407FA8 POP ECX
0167:00407FA9 POP ECX
0167:00407FAA JZ 00408005
0167:00407FAC CMP BYTE PTR [0048CDA4]00 ←- [0048CDA4]指向“12345678”
0167:00407FB3 JZ 00408005
0167:00407FB5 CALL 00407905
0167:00407FBA TEST EAXEAX
0167:00407FC3 JZ 00408005
......
8. 我們從調(diào)用hmemcpy的系統(tǒng)區(qū)域中返回到winzip領(lǐng)空時(shí),程序停留在0167:00407F73 PUSH EDI上,看看它上面的那條指令0167:00407F6D CALL [USER32!GetDlgItemTextA],這個(gè)CALL就是取我們輸入數(shù)據(jù)的程序,也就是這個(gè)CALL讓我們用 bpx hmemcpy 將winzip攔截了下來。既然winzip用這個(gè)CALL去取輸入的東西,那么調(diào)用之后肯定會(huì)返回結(jié)果的,讓我們來看看:用 D EDI ,觀察softice的數(shù)據(jù)區(qū),你會(huì)看到EDI指向的內(nèi)存區(qū)域的內(nèi)容是我們輸入的名字“KraneXH”;
9. 從程序中可看出,下面不遠(yuǎn)的地方還有一個(gè)同樣的地方調(diào)用USER32!GetDlgItemTextA,既0167:00407F8F CALL [USER32!GetDlgItemTextA]這一行。按F10鍵多次,走到這個(gè)CALL的下一句停下,既程序停在0167:00407F95 PUSH ESI這條指令上,用 D ESI ,同樣的我們可以看到ESI指向的內(nèi)存區(qū)域的內(nèi)容是我們輸入的注冊碼“12345678”。現(xiàn)在winzip已經(jīng)將我們輸入的名字和注冊碼都取到,讓我們來看看它下一步要做什么?
10. 繼續(xù)按F10多次,當(dāng)程序走到0167:00407FA1 CMP BYTE PTR [0048CD78]00時(shí)停下來,這條指令將內(nèi)存0048CD78中的數(shù)據(jù)和00比較,然后根據(jù)比較結(jié)果判斷程序走向。用 D 0048CD78,觀察softice的數(shù)據(jù)區(qū),我們可以看到0048CD78中的數(shù)據(jù)是“KraneXH”,現(xiàn)在我們知道這條指令的作用是判斷我們輸入的名字是否為空,如果沒有輸入任何東西,程序?qū)?huì)跳到00408005去;同樣的,按F10走到0407FAC CMP BYTE PTR [0048CDA4]00這行停下,然后用 D 0048CDA4,可以看到0048CDA4中的數(shù)據(jù)是“12345678”。因?yàn)槲覀冚斎肓嗣趾妥源a,所以程序不會(huì)跳到 00408005去,程序檢查輸入的名字和注冊碼,如果任何一個(gè)沒有輸入(既其值為00),程序都會(huì)跳到00408005去,由此我們應(yīng)該想到00408005很可能就是顯示出錯(cuò)的地方,即當(dāng)程序走到00408005 的時(shí)候,表示輸入的名字和注冊碼是錯(cuò)誤的;
11. 按F10兩次來到下面的那個(gè)CALL 00407905(因?yàn)槌绦騽偛磐T?167:00407FAC CMP BYTE PTR [0048CDA4]00上):
......
0167:00407FB5 CALL 00407905 ←- 程序停留在這里
0167:00407FBA TEST EAXEAX
0167:00407FC3 JZ 00408005
......
程序判斷輸入的名字和注冊碼是否為空后調(diào)用CALL 00407905,這個(gè)CALL將結(jié)果返回到EAX中,程序根據(jù)EAX值判斷走向。從程序可以知道,如果EAX的返回值是0,則程序會(huì)跳到00408005,就是剛才我們判斷是有問題的地方。那么這個(gè)CALL倒底藏著什么貓膩呀?現(xiàn)在還不是很清楚,接著按F10兩次來到JZ 00408005停下。現(xiàn)在看看softice中的零(即Z)標(biāo)志位,其值是零,所以程序?qū)?huì)跳到00408005去,我們姑且按F10跳到00408005去看個(gè)究竟:
......
0167:00408005 CALL 004082A6 ←- 程序停留在這里
0167:0040800A PUSH 0000028E
0167:0040800F CALL 0043F5ED
0167:00408014 PUSH EAX
0167:00408015 PUSH EBX
0167:00408016 PUSH 3D
0167:00408018 CALL 00430025 ←- 出現(xiàn)錯(cuò)誤框
0167:0040801D ADD ESP10
0167:00408020 INC DWORD PTR [00487AF8]
0167:00408026 CMP DWORD PTR [00487AF8]03 ←- 判斷錯(cuò)誤次數(shù)是否到了3次?
0167:0040802D JNZ 0040812C
0167:00408033 PUSH 00
0167:00408035 PUSH EBX
0167:00408036 CALL [USER32!EndDialog]
0167:0040803C JMP 0040812C
......
12. 一直按F10走過0167:00408018 CALL 00430025,這是程序蹦出一個(gè)窗口,警告:Incomplete or incorrect information(不完整或不正確的信息),程序走到這里就已經(jīng)很明朗了:如果程序在前面的時(shí)候跳到00408005來,就表示輸入的名字和注冊碼是錯(cuò)誤的,所以剛才的那個(gè)0167:00407FB5 CALL 00407905一定是比較輸入的注冊碼是否正確的地方,也就是里面肯定有將我們輸入的注冊碼和正確的注冊碼相比較的地方,所以我們要進(jìn)入CALL 00430025里去看看。如果繼續(xù)往CALL 00430025下面的語句看的話,你會(huì)看到下面的幾句:
0167:00408020 INC DWORD PTR [00487AF8]
0167:00408026 CMP DWORD PTR [00487AF8]03
0167:0040802D JNZ 0040812C
程序先將內(nèi)存00487AF8處的值加1(其初始值為0,可以在這條語句前用 D 00487AF8 查看),然后比較是否是3,如果不是就跳到0040812C,如果是則執(zhí)行后面的0167:00408036 CALL [USER32!EndDialog],其作用就是關(guān)閉對話框,也就是我們輸入名字和注冊碼的窗口。由此我們可以看出此處程序的作用是檢查錯(cuò)誤輸入名字、注冊碼的錯(cuò)誤次數(shù)是否已經(jīng)到了3次,如果到了3次,則關(guān)閉對話框,不允許再輸入;如果少于3次,可有機(jī)會(huì)再次輸入名字和注冊碼。
13. 重復(fù)前面的步驟1到11,讓程序停在0167:00407FB5 CALL 00407905上,然后按F8進(jìn)入這個(gè)CALL里面去:
......
0167:004079D5 PUSH EBP
0167:004079D6 PUSH EBPESP
0167:004079D8 SUB ESP00000208
0167:004079DE PUSH EBX
0167:004079DF PUSH ESI
0167:004079E0 XOR ESIESI
0167:004079E2 CMP BYTE PTR [0048CD78]00
0167:004079E9 PUSH EDI
0167:004079EA JZ 00407A8A
......
14. 按F10鍵N次(我也不知道幾次,你自己數(shù)一數(shù)吧^_^),一直來到下面的地方停下:
......
0167:00407A91 LEA EAX[EBP-0140] ←- 程序停留在這里
0167:00407A97 PUSH EAX
0167:00407A98 PUSH EDI ←- EDI指向輸入的名字“KraneXH”
0167:00407A99 CALL 00407B47 ←- 計(jì)算注冊碼
0167:00407A9E MOV ESI0048CDA4
0167:00407AA3 LEA EAX[EBP-0140]
0167:00407AA9 PUSH ESI ←- ESI指向輸入的注冊碼“12345678”
0167:00407AAA PUSH EAX ←- EAX指向正確的注冊碼“5CFC0875”
0167:00407AAB CALL 004692D0
0167:00407AB0 ADD ESP10
0167:00407AB3 NEG EAX
0167:00407AB5 SBB EAXEAX
0167:00407AB7 INC EAX
0167:00407AB8 MOV [00489FDC]EAX
0167:00407ABD JNZ 00407B27
0167:00407ABF LEA EAX[EBP-0140]
0167:00407AC5 PUSH EAX
0167:00407AC6 PUSH EDI ←- EDI指向輸入的名字“KraneXH”
0167:00407AC7 CALL 00407BE4 ←- 計(jì)算注冊碼
0167:00407ACC LEA EAX[EBP-0140]
0167:00407AD2 PUSH ESI ←- ESI指向輸入的注冊碼“12345678”
0167:00407AD3 PUSH EAX ←- EAX指向正確的注冊碼“23804216”
0167:00407AD4 CALL 004692D0
0167:00407AD9 ADD ESP10
0167:00407ADC NEG EAX
0167:00407ADE SBB EAXEAX
0167:00407AE0 INC EAX
0167:00407AE1 MOV [00489FDC]EAX
0167:00407AE6 JNZ 00407B27
......
15. 大家一定會(huì)問:為什么會(huì)在這里停下,而不是其它地方呢?因?yàn)槲以谇懊娴某绦蛑幸呀?jīng)用 D *** 看過了,沒有發(fā)現(xiàn)什么可疑的呀^_^!
按F10走到0167:00407A99 CALL 00407B47處,用 D EAX 和 D EDI 觀察其里面是什么?可以看到EDI指向我們輸入的名字“KraneXH”,EAX指向的內(nèi)存區(qū)域沒有什么特別的數(shù)據(jù);緊接著下面的CALL 00407B47 會(huì)對“KraneXH”進(jìn)行一些處理,具體的 我們還不知道,繼續(xù)往后走;
16. 按F10走到0167:00407AAB CALL 004692D0這一句,然后用 D ESI 和 D EAX 查看內(nèi)存中的數(shù)據(jù),可以看到ESI指向我們輸入的注冊碼“12345678”,而EAX指向另外一串字符“5CFC0875”。不用說,十有八九這就是正確的注冊碼了,趕緊把它寫在紙上吧^_^!繼續(xù)往下走,我們會(huì)在下面的地方緊接著發(fā)現(xiàn)另外一個(gè)類似程序段,從而得到另外一串碼“23804216”;
17. 驗(yàn)證注冊碼:按F5返回winzip,選擇注冊,輸入名字“KraneXH”和注冊碼“5CFC0875”或“23804216”。然后你看到了什么?注冊成功的畫面出現(xiàn),直接確認(rèn)就搞定了,哈哈哈。。。!
18. 現(xiàn)在我們知道CALL 00407B47這條語句的作用是根據(jù)我們輸入的名字來計(jì)算正確的注冊碼,然后和我們輸入的注冊碼比較,看兩者是否相等。處理后事:最后別忘了用CTRL+D呼出softice,然后下命令 BC * 清除所有斷點(diǎn)!!!
(編輯:天命孤獨(dú))
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注