|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-11, 08:14 PM | #1 |
榮譽會員
|
Quickness 3.1 註冊算法分析 + 註冊機來源碼
Quickness 3.1 註冊算法分析 + 註冊機來源碼(tc2)
破解目標:Quickness 3.1 官方主頁:http://www.qwertysoft.com/ 軟體簡介:Quickness 是一個方便用戶輸入的小工具。如果有些文本內容是我們經常要用到的,就可以利用 Quickness 將其儲存起來,並為其指定熱鍵,這樣,當我們需要用的時候,直接按熱鍵就可以調出內容了。特別是在我們聊天的時候,有了 Quickness 的相助,可是會大大提高速度的喲。 下載頁面:http://www.hanzify.org/detail.asp?SOFT_ID=6938 (漢化版) 使用工具:PEiD 0.8、W32Dasm、Ollydbg 1.09b 漢化版、Windows 自帶的計算器、32bit Calculator 1.6 by cybult、UltraEdit,另外還要儲存大腦清醒^^ 作者:炎之川[BCG] 時間:2003.4.13 主頁:http://skipli.yeah.net/ 宣告:此文僅用於學習及交流,若要轉載請保持文章完整。 首先說明,我下載的是漢化版,官方主頁上不去,天空軟體站好像也沒有,所以英文原版沒有辦法找到,下面的分析都是關於漢化版的,當然從分析的角度說,無論漢化版還是英文版都是一樣的。 其實頭腦清醒的話,軟體的算法並不是很難,只是在一個循環中要同時考慮三個暫存器中的數字的變化,以及其他一些變化的量,稍不留神就會亂掉。最好在分析的時候,隨時紀錄一下值的變化。 用 PEiD 0.8 征測可知軟體無殼,使用 W32Dasm 分析,可以找到註冊成功、失敗等提示信息,稍作分析後用 OD 裝入程序,在 4029A7 處下斷點,然後 Ctrl+F2 重新載入程序,F9 執行,輸入註冊名及假註冊碼並點擊「註冊」: Name: lovefire[BCG] Serial: 123-456-789 004029A7 > 8B7C24 14 MOV EDI,DWORD PTR SS:[ESP+14] ; Case 1 of switch 00402965 /在這裡下斷點 004029AB . 68 1A040000 PUSH 41A ; /ControlID = 41A (1050.) 004029B0 . 57 PUSH EDI ; |hWnd 004029B1 . FF15 5C654100 CALL DWORD PTR DS:[<&USER32.GetDlgItem>] ; \GetDlgItem 004029B7 . 8BD8 MOV EBX,EAX 004029B9 . 53 PUSH EBX ; /hWnd 004029BA . FF15 AC644100 CALL DWORD PTR DS:[<&USER32.GetWindowTex>; \GetWindowTextLengthA 004029C0 . 8BE8 MOV EBP,EAX 004029C2 . 8D45 01 LEA EAX,DWORD PTR SS:[EBP+1] 004029C5 . 50 PUSH EAX 004029C6 . E8 35500000 CALL qns31chs.00407A00 004029CB . 83C4 04 ADD ESP,4 004029CE . 8BF0 MOV ESI,EAX 004029D0 . 8D45 01 LEA EAX,DWORD PTR SS:[EBP+1] 004029D3 . 50 PUSH EAX ; /Count 004029D4 . 56 PUSH ESI ; |Buffer 004029D5 . 53 PUSH EBX ; |hWnd 004029D6 . FF15 B4644100 CALL DWORD PTR DS:[<&USER32.GetWindowTex>; \GetWindowTextA 004029DC . 56 PUSH ESI 004029DD . 68 BC0C4100 PUSH qns31chs.00410CBC ; ASCII "user_name" 004029E2 . C6042E 00 MOV BYTE PTR DS:[ESI+EBP],0 004029E6 . E8 C5E9FFFF CALL qns31chs.004013B0 004029EB . 83C4 08 ADD ESP,8 004029EE . 56 PUSH ESI 004029EF . E8 FC4F0000 CALL qns31chs.004079F0 004029F4 . 83C4 04 ADD ESP,4 004029F7 . B9 743F4100 MOV ECX,qns31chs.00413F74 004029FC . 57 PUSH EDI 004029FD . E8 6E000000 CALL qns31chs.00402A70 00402A02 . E8 C9FDFFFF CALL qns31chs.004027D0 //關鍵call!F7 跟進 00402A07 . 85C0 TEST EAX,EAX //比較eax是否為0,為0則註冊失敗 00402A09 . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 00402A0B . 68 A00B4100 PUSH qns31chs.00410BA0 ; |Title = "Quickness" 00402A10 . 74 28 JE SHORT qns31chs.00402A3A ; | //這裡不能跳!! 00402A12 . 68 E80C4100 PUSH qns31chs.00410CE8 ; |Text = "正確。感謝。" 00402A17 . 57 PUSH EDI ; |hOwner 00402A18 . FF15 84644100 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA 00402A1E . 6A 01 PUSH 1 ; /Result = 1 00402A20 . 57 PUSH EDI ; |hWnd 00402A21 . C705 50084100 >MOV DWORD PTR DS:[410850],0 ; | 00402A2B . FF15 58654100 CALL DWORD PTR DS:[<&USER32.EndDialog>] ; \EndDialog 00402A31 . 33C0 XOR EAX,EAX 00402A33 . 5F POP EDI 00402A34 . 5E POP ESI 00402A35 . 5D POP EBP 00402A36 . 5B POP EBX 00402A37 . C2 1000 RETN 10 00402A3A > 68 C80C4100 PUSH qns31chs.00410CC8 ; |Text = "註冊失敗。繼續試用。" 00402A3F . 57 PUSH EDI ; |hOwner 00402A40 . FF15 84644100 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA 00402A46 . 33C0 XOR EAX,EAX 00402A48 . 5F POP EDI 00402A49 . 5E POP ESI 00402A4A . 5D POP EBP 00402A4B . 5B POP EBX 00402A4C . C2 1000 RETN 10 00402A4F > 8B5424 14 MOV EDX,DWORD PTR SS:[ESP+14] 00402A53 . 68 F80C4100 PUSH qns31chs.00410CF8 ; ASCII "a_register.htm" 00402A58 . 52 PUSH EDX 00402A59 . E8 92420000 CALL qns31chs.00406CF0 00402A5E . 83C4 08 ADD ESP,8 00402A61 > 5F POP EDI ; Default case of switch 00402965 00402A62 . 5E POP ESI 00402A63 . 5D POP EBP 00402A64 . 33C0 XOR EAX,EAX 00402A66 . 5B POP EBX 00402A67 . C2 1000 RETN 10 ---------------------------------------------------------- 跟進 402A02 的關鍵call: 004027D0 /$ 81EC 94010000 SUB ESP,194 004027D6 |. 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] 004027DA |. 53 PUSH EBX 004027DB |. 55 PUSH EBP 004027DC |. 56 PUSH ESI 004027DD |. 57 PUSH EDI 004027DE |. 68 C8000000 PUSH 0C8 004027E3 |. 50 PUSH EAX 004027E4 |. 68 BC0C4100 PUSH qns31chs.00410CBC ; ASCII "user_name" 004027E9 |. E8 32EBFFFF CALL qns31chs.00401320 004027EE |. 83C4 0C ADD ESP,0C 004027F1 |. 85C0 TEST EAX,EAX 004027F3 |. 75 0B JNZ SHORT qns31chs.00402800 004027F5 |. 5F POP EDI 004027F6 |. 5E POP ESI 004027F7 |. 5D POP EBP 004027F8 |. 5B POP EBX 004027F9 |. 81C4 94010000 ADD ESP,194 004027FF |. C3 RETN 00402800 |> 8D8C24 DC00000>LEA ECX,DWORD PTR SS:[ESP+DC] 00402807 |. 68 C8000000 PUSH 0C8 0040280C |. 51 PUSH ECX 0040280D |. 68 B40C4100 PUSH qns31chs.00410CB4 ; ASCII "reg_key" 00402812 |. E8 09EBFFFF CALL qns31chs.00401320 00402817 |. 83C4 0C ADD ESP,0C 0040281A |. 85C0 TEST EAX,EAX 0040281C |. 75 0B JNZ SHORT qns31chs.00402829 0040281E |. 5F POP EDI 0040281F |. 5E POP ESI 00402820 |. 5D POP EBP 00402821 |. 5B POP EBX 00402822 |. 81C4 94010000 ADD ESP,194 00402828 |. C3 RETN 00402829 |> 8D7C24 14 LEA EDI,DWORD PTR SS:[ESP+14] 0040282D |. 83C9 FF OR ECX,FFFFFFFF 00402830 |. 33C0 XOR EAX,EAX 00402832 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 00402834 |. F7D1 NOT ECX 00402836 |. 49 DEC ECX //得到註冊名長度 00402837 |. 8BC1 MOV EAX,ECX //長度放入eax 00402839 |. 83F8 01 CMP EAX,1 //比較是否大於1 0040283C |. 894424 10 MOV DWORD PTR SS:[ESP+10],EAX 00402840 |. 73 0D JNB SHORT qns31chs.0040284F //大於1則繼續 00402842 |. 33C0 XOR EAX,EAX 00402844 |. 5F POP EDI 00402845 |. 5E POP ESI 00402846 |. 5D POP EBP 00402847 |. 5B POP EBX 00402848 |. 81C4 94010000 ADD ESP,194 0040284E |. C3 RETN 0040284F |> 33C9 XOR ECX,ECX //ecx 清零,做計數器 00402851 |. BE 01000000 MOV ESI,1 //esi 賦值 1 00402856 |. 85C0 TEST EAX,EAX 00402858 |. BD 03000000 MOV EBP,3 //ebp 賦值 3 0040285D |. BF 05000000 MOV EDI,5 //edi 賦值 5 00402862 |. 76 4F JBE SHORT qns31chs.004028B3 下面開始就是計算註冊碼的循環了,開始的時候我沒有理清思路,在這裡轉來轉去,頭都大了(汗…典型的菜鳥-_-b),後來經過仔細分析,發現這個循環的工作實際上是在計算三個值,並儲存到不同的三個暫存器中,所以其他值都是無關緊要的中間變數,分析的時候,只要注意三個值的變化情況即可。 為了便於理解,我把這個循環分成三個部分,每一部分都寫出了這一部分重要的中間變數和重要的暫存器的具體變化和算法。 下面均使用C語言的運算符表述,記住 ESI、EBP、EDI 這三個暫存器的值是我們需要掌握的,EAX 和 EDX 是關鍵的中間變數,name[i] 指用戶名的 ASCII 值。 另外,從C語言運算符的優先級角度講,其實並不需要用那麼多的括號,但是我為了自己不看亂掉,所以每一運算均使用括號來分隔,不要數錯了^_^ (最後差點數錯的好像是我自己…狂汗-_-bbb) 00402864 |> 0FBE5C0C 14 /MOVSX EBX,BYTE PTR SS:[ESP+ECX+14] //逐位取註冊名的ASCII值放入ebx 00402869 |. 8D0476 |LEA EAX,DWORD PTR DS:[ESI+ESI*2] //eax=esi*2+esi=esi*3 0040286C |. 33D2 |XOR EDX,EDX //edx清零 0040286E |. C1E0 04 |SHL EAX,4 //eax 左移4,等於4次*2運算 00402871 |. 2BC6 |SUB EAX,ESI //eax=eax-esi 00402873 |. BE E8030000 |MOV ESI,3E8 //給 esi 賦值為 3E8 00402878 |. 03C3 |ADD EAX,EBX //eax=eax+ebx,ebx中是註冊名的ASCII值 0040287A |. F7F6 |DIV ESI //eax/esi=eax/3E8,餘數放入edx eax=(((esi*3)<<4-esi)+name[i])/0x3E8 edx=(((esi*3)<<4-esi)+name[i])%0x3E8 = 值1 0040287C |. 8BC5 |MOV EAX,EBP //eax=ebp 0040287E |. C1E0 04 |SHL EAX,4 //eax再次左移4 00402881 |. 03C5 |ADD EAX,EBP //eax=eax+ebp 00402883 |. BD E8030000 |MOV EBP,3E8 //ebp=3E8,為下面的計算再次賦值 00402888 |. 8BF2 |MOV ESI,EDX //esi=edx,edx是上面 eax mod 3E8 得到的值 0040288A |. 8D1443 |LEA EDX,DWORD PTR DS:[EBX+EAX*2] //edx=ebx+eax*2,ebx是註冊名ASCII 0040288D |. 03C2 |ADD EAX,EDX //eax=eax+edx 0040288F |. 33D2 |XOR EDX,EDX //edx 清零 00402891 |. F7F5 |DIV EBP //eax=eax/ebp=eax/3E8,餘數放入edx eax=((((ebp<<4)+ebp)*2)+name[i])+((ebp<<4)+ebp) edx=(((ebp<<4)+ebp)+(name[i]+(((ebp<<4)+ebp)*2)))%0x3E8 = 值2 esi=值1 (!) 00402893 |. 8D04FF |LEA EAX,DWORD PTR DS:[EDI+EDI*8] //eax=edi+edi*8=edi*9 00402896 |. C1E0 03 |SHL EAX,3 //eax 左移3 00402899 |. 2BC7 |SUB EAX,EDI //eax=eax-edi 0040289B |. BF E8030000 |MOV EDI,3E8 //edi=3E8 004028A0 |. 03C3 |ADD EAX,EBX //eax=eax+ebx 004028A2 |. 8BEA |MOV EBP,EDX //ebp=edx,edx是上面 eax mod 3E8 得到的值 004028A4 |. 33D2 |XOR EDX,EDX //edx 清零 004028A6 |. F7F7 |DIV EDI //eax=eax/edi eax=(edi*8<<3-edi+name[i])/0x3E8 ebp=值2 (!) edx=(edi*8<<3-edi+name[i])%3E8 = 值3 004028A8 |. 8B4424 10 |MOV EAX,DWORD PTR SS:[ESP+10] //註冊名長度放入eax 004028AC |. 41 |INC ECX //計數器+1 004028AD |. 3BC8 |CMP ECX,EAX //比較計數器與註冊名長度 004028AF |. 8BFA |MOV EDI,EDX //edi=edx 004028B1 |.^72 B1 \JB SHORT qns31chs.00402864 //沒有取完就跳回去繼續循環 edi=值3 (!) 004028B3 |> 57 PUSH EDI 004028B4 |. 55 PUSH EBP 004028B5 |. 56 PUSH ESI 004028B6 |. 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+20] 004028BA |. 68 A40C4100 PUSH qns31chs.00410CA4 ; ASCII "%03d-%03d-%03d" //註冊碼格式,十進制輸出,寬度為3 004028BF |. 50 PUSH EAX 004028C0 |. E8 BB500000 CALL qns31chs.00407980 //將 esi、ebp、edi 分別作為註冊碼的第一、二、三部分,合併起來成為完整的註冊碼。 004028C5 |. 83C4 14 ADD ESP,14 004028C8 |. 8DB424 DC00000>LEA ESI,DWORD PTR SS:[ESP+DC] //假碼放入esi 004028CF |. 8D4424 14 LEA EAX,DWORD PTR SS:[ESP+14] //真碼放入eax 004028D3 |> 8A10 /MOV DL,BYTE PTR DS:[EAX] //下面開始比較註冊碼 004028D5 |. 8A1E |MOV BL,BYTE PTR DS:[ESI] 004028D7 |. 8ACA |MOV CL,DL 004028D9 |. 3AD3 |CMP DL,BL 004028DB |. 75 30 |JNZ SHORT qns31chs.0040290D 004028DD |. 84C9 |TEST CL,CL 004028DF |. 74 16 |JE SHORT qns31chs.004028F7 004028E1 |. 8A50 01 |MOV DL,BYTE PTR DS:[EAX+1] 004028E4 |. 8A5E 01 |MOV BL,BYTE PTR DS:[ESI+1] 004028E7 |. 8ACA |MOV CL,DL 004028E9 |. 3AD3 |CMP DL,BL 004028EB |. 75 20 |JNZ SHORT qns31chs.0040290D 004028ED |. 83C0 02 |ADD EAX,2 004028F0 |. 83C6 02 |ADD ESI,2 004028F3 |. 84C9 |TEST CL,CL 004028F5 |.^75 DC \JNZ SHORT qns31chs.004028D3 004028F7 |> 33C0 XOR EAX,EAX 004028F9 |. 33C9 XOR ECX,ECX 004028FB |. 85C0 TEST EAX,EAX 004028FD |. 0F94C1 SETE CL 00402900 |. 8BC1 MOV EAX,ECX 00402902 |. 5F POP EDI 00402903 |. 5E POP ESI 00402904 |. 5D POP EBP 00402905 |. 5B POP EBX 00402906 |. 81C4 94010000 ADD ESP,194 0040290C |. C3 RETN 算法總結如下: 註冊碼分三個部分,分別用 esi、ebp、edi 代表。每個部分為三位十進制數字,中間用「-」分隔。 設初始值:esi=1、ebp=3、edi=5,name[i]為取得的註冊用戶名的 ASCII 值: 第一部分算法: esi=((((esi*3)<<4)-esi)+name[i])%0x3E8 第二部分算法: ebp=(((((ebp<<4)+ebp)*2)+name[i])+((ebp<<4)+ebp))%0x3E8 第三部分算法: edi=((((edi*9)<<3)-edi)+name[i])%0x3E8 至此 Quickness 3.1 註冊算法分析完成,一組可用的註冊碼:Name: lovefire[BCG] Serial: 409-351-613 註冊信息儲存: 軟體安裝目錄下的 qns31.ini 文件中,註冊信息儲存如下: [x] user_name=lovefire[BCG] reg_key=409-351-613 ---------------------------------------------------------- 註冊機來源碼(TC 2.0) 順便再寫一下註冊機,TC 2.0 編譯通過。 /* KeyGen by 炎之川[BCG],2003.4.12 */ #include <stdio.h> #include <string.h> main() { char name[255]; int name_len,i; unsigned long int esi=1; unsigned long int ebp=3; unsigned long int edi=5; clrscr(); printf("\n _/_/_/ _/_/_/ _/_/_/\n _/ _/ _/ _/\n _/_/_/ _/ _/ _/_/\n _/ _/ _/ _/ _/\n_/_/_/ _/_/_/ _/_/_/\n\n -= Quickness v3.1 KeyGen by lovefire[BCG] =-\n\n\nPlease enter your name: "); gets(name); name_len=strlen(name); if (name_len>0) { for (i=0;i<name_len;i++) { esi=((((esi*3)<<4)-esi)+name[i])%0x3E8; ebp=(((((ebp<<4)+ebp)*2)+name[i])+((ebp<<4)+ebp))%0x3E8; edi=((((edi*9)<<3)-edi)+name[i])%0x3E8; } printf("\nok, try this serial: %03ld-%03ld-%03ld\n",esi,ebp,edi); printf("\n\nNOTE: serial only for test!"); printf("\nIf you like it, buy it to support the soft's author!"); } else { printf("\nI think you should tell me your name first \n"); } printf("\n\nhave fun^^\nwelcome to http://skipli.yeah.net/"); getch(); } ---------------------------------------------------------- 炎之川 屬於中國破解組織BCG(Beginner's Cracking Group) _/_/_/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/_/_/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/_/_/ _/_/_/ _/_/_/ |
送花文章: 3,
|