作者:星痕
e-mail:jrg1982@163.com
破解步驟:
1. 用softice載入windows(通過CTRL+D來檢查softice是否已經準備好,按F5退出softice);
2. 運行winzip,選擇“help”下的“Enter Registration Code...”;
3. 在“Name:”中輸入:KraneXH(隨意),“Registration #:”中輸入:12345678(隨意);
4. 用CTRL+D呼出softice,下萬能斷點:bpx hmemcpy,按F5返回到winzip;
5. 在winzip中選擇“OK”,很快程序就被softice攔截下來(因為我們設置了斷點bpx hmemcpy,當在winzip中選擇“OK”時,winzip會通過hmemcpy這個功能去取我們輸入的名字“KraneXH”和注冊碼“12345678”,softice檢測到hmemcpy被調用,于是就中斷winzip的運行,停留在winzip中調用hmemcpy的地方);
6. 用 bd * 暫停剛才設置的斷點 bpx hmemcpy (為什么要暫停斷點bpx hmemcpy呢?因為我們的目的是要在winzip取名字和注冊碼的時候中斷它的運行,但是 bpx hmemcpy 這個斷點并不是針對winzip才有效的,計算機里運行的程序都可能會隨時調用它。由于我們在winzip中剛輸入名字和注冊碼后設置斷點 bpx hmemcpy ,此時winzip會馬上去取我們輸入的名字和注冊碼,所以我們能確保是中斷在winzip程序中,通過 bd * 這個命令暫停斷點 bpx hmemcpy ,能夠防止解密時被其它不相干的程序中斷,影響解密的正常進行);
7. 按F12鍵9次,返回到winzip的領空(因為剛才softice中斷在hmemcpy中,這是windows系統區域,不能更改的,winzip僅僅是調用這個功能而已,所以我們必須要返回到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. 我們從調用hmemcpy的系統區域中返回到winzip領空時,程序停留在0167:00407F73 PUSH EDI上,看看它上面的那條指令0167:00407F6D CALL [USER32!GetDlgItemTextA],這個CALL就是取我們輸入數據的程序,也就是這個CALL讓我們用 bpx hmemcpy 將winzip攔截了下來。既然winzip用這個CALL去取輸入的東西,那么調用之后肯定會返回結果的,讓我們來看看:用 D EDI ,觀察softice的數據區,你會看到EDI指向的內存區域的內容是我們輸入的名字“KraneXH”;
9. 從程序中可看出,下面不遠的地方還有一個同樣的地方調用USER32!GetDlgItemTextA,既0167:00407F8F CALL [USER32!GetDlgItemTextA]這一行。按F10鍵多次,走到這個CALL的下一句停下,既程序停在0167:00407F95 PUSH ESI這條指令上,用 D ESI ,同樣的我們可以看到ESI指向的內存區域的內容是我們輸入的注冊碼“12345678”?,F在winzip已經將我們輸入的名字和注冊碼都取到,讓我們來看看它下一步要做什么?
10. 繼續按F10多次,當程序走到0167:00407FA1 CMP BYTE PTR [0048CD78]00時停下來,這條指令將內存0048CD78中的數據和00比較,然后根據比較結果判斷程序走向。用 D 0048CD78,觀察softice的數據區,我們可以看到0048CD78中的數據是“KraneXH”,現在我們知道這條指令的作用是判斷我們輸入的名字是否為空,如果沒有輸入任何東西,程序將會跳到00408005去;同樣的,按F10走到0407FAC CMP BYTE PTR [0048CDA4]00這行停下,然后用 D 0048CDA4,可以看到0048CDA4中的數據是“12345678”。因為我們輸入了名字和注冊碼,所以程序不會跳到 00408005去,程序檢查輸入的名字和注冊碼,如果任何一個沒有輸入(既其值為00),程序都會跳到00408005去,由此我們應該想到00408005很可能就是顯示出錯的地方,即當程序走到00408005 的時候,表示輸入的名字和注冊碼是錯誤的;
11. 按F10兩次來到下面的那個CALL 00407905(因為程序剛才停在0167:00407FAC CMP BYTE PTR [0048CDA4]00上):
......
0167:00407FB5 CALL 00407905 ←- 程序停留在這里
0167:00407FBA TEST EAXEAX
0167:00407FC3 JZ 00408005
......
程序判斷輸入的名字和注冊碼是否為空后調用CALL 00407905,這個CALL將結果返回到EAX中,程序根據EAX值判斷走向。從程序可以知道,如果EAX的返回值是0,則程序會跳到00408005,就是剛才我們判斷是有問題的地方。那么這個CALL倒底藏著什么貓膩呀?現在還不是很清楚,接著按F10兩次來到JZ 00408005停下。現在看看softice中的零(即Z)標志位,其值是零,所以程序將會跳到00408005去,我們姑且按F10跳到00408005去看個究竟:
......
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 ←- 出現錯誤框
0167:0040801D ADD ESP10
0167:00408020 INC DWORD PTR [00487AF8]
0167:00408026 CMP DWORD PTR [00487AF8]03 ←- 判斷錯誤次數是否到了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,這是程序蹦出一個窗口,警告:Incomplete or incorrect information(不完整或不正確的信息),程序走到這里就已經很明朗了:如果程序在前面的時候跳到00408005來,就表示輸入的名字和注冊碼是錯誤的,所以剛才的那個0167:00407FB5 CALL 00407905一定是比較輸入的注冊碼是否正確的地方,也就是里面肯定有將我們輸入的注冊碼和正確的注冊碼相比較的地方,所以我們要進入CALL 00430025里去看看。如果繼續往CALL 00430025下面的語句看的話,你會看到下面的幾句:
0167:00408020 INC DWORD PTR [00487AF8]
0167:00408026 CMP DWORD PTR [00487AF8]03
0167:0040802D JNZ 0040812C
程序先將內存00487AF8處的值加1(其初始值為0,可以在這條語句前用 D 00487AF8 查看),然后比較是否是3,如果不是就跳到0040812C,如果是則執行后面的0167:00408036 CALL [USER32!EndDialog],其作用就是關閉對話框,也就是我們輸入名字和注冊碼的窗口。由此我們可以看出此處程序的作用是檢查錯誤輸入名字、注冊碼的錯誤次數是否已經到了3次,如果到了3次,則關閉對話框,不允許再輸入;如果少于3次,可有機會再次輸入名字和注冊碼。
13. 重復前面的步驟1到11,讓程序停在0167:00407FB5 CALL 00407905上,然后按F8進入這個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次(我也不知道幾次,你自己數一數吧^_^),一直來到下面的地方停下:
......
0167:00407A91 LEA EAX[EBP-0140] ←- 程序停留在這里
0167:00407A97 PUSH EAX
0167:00407A98 PUSH EDI ←- EDI指向輸入的名字“KraneXH”
0167:00407A99 CALL 00407B47 ←- 計算注冊碼
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 ←- 計算注冊碼
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. 大家一定會問:為什么會在這里停下,而不是其它地方呢?因為我在前面的程序中已經用 D *** 看過了,沒有發現什么可疑的呀^_^!
按F10走到0167:00407A99 CALL 00407B47處,用 D EAX 和 D EDI 觀察其里面是什么?可以看到EDI指向我們輸入的名字“KraneXH”,EAX指向的內存區域沒有什么特別的數據;緊接著下面的CALL 00407B47 會對“KraneXH”進行一些處理,具體的 我們還不知道,繼續往后走;
16. 按F10走到0167:00407AAB CALL 004692D0這一句,然后用 D ESI 和 D EAX 查看內存中的數據,可以看到ESI指向我們輸入的注冊碼“12345678”,而EAX指向另外一串字符“5CFC0875”。不用說,十有八九這就是正確的注冊碼了,趕緊把它寫在紙上吧^_^!繼續往下走,我們會在下面的地方緊接著發現另外一個類似程序段,從而得到另外一串碼“23804216”;
17. 驗證注冊碼:按F5返回winzip,選擇注冊,輸入名字“KraneXH”和注冊碼“5CFC0875”或“23804216”。然后你看到了什么?注冊成功的畫面出現,直接確認就搞定了,哈哈哈。。。!
18. 現在我們知道CALL 00407B47這條語句的作用是根據我們輸入的名字來計算正確的注冊碼,然后和我們輸入的注冊碼比較,看兩者是否相等。處理后事:最后別忘了用CTRL+D呼出softice,然后下命令 BC * 清除所有斷點?。?!
(編輯:天命孤獨)
新聞熱點
疑難解答
圖片精選