|
論壇說明 | 標記討論區已讀 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-12, 01:08 PM | #1 |
榮譽會員
|
XX2003 V3.0 註冊碼分析
幻影2003 V3.0是一個很有特色的圖像處理軟體,使用圖像的處理變得簡單易用,效果很不錯.安裝完該軟體後發現它是用ASPACK壓縮的,就使用PE-SCAN對其解壓縮,然後用TRW2000開始跟蹤,很快就發現,軟體對註冊碼的比較程序非常原始,就是兩個真假註冊碼直接進行對比,所以很容易就找到了有效的註冊碼,而且真假註冊碼的位置也很接近,所以用WINHEX的記憶體編輯功能就可以很快找到註冊碼,但是分析它的註冊碼的產生程序,卻花了我很長時間,因為軟體的註冊碼並不是由軟體編號直接變化而來的,而是有一個註冊的關鍵值,軟體編號也是由此值變化而來(這個變化程序是可逆的),在註冊對話視窗出現時,註冊碼其實已經產生了.
0167:004100F1 MOV EAX,[ESI+D0]<----此值就是註冊碼產生的關鍵值,以下記為reg 0167:004100F7 CMP EAX,EBX 0167:004100F9 JNZ 0041015A 0167:004100FB LEA ECX,[ESP+38] 0167:004100FF MOV BYTE [ESP+B8],03 0167:00410107 CALL `MFC42!ord_00000320` 0167:0041010C LEA ECX,[ESP+30] 0167:00410110 MOV BYTE [ESP+B8],02 0167:00410118 CALL `MFC42!ord_00000320` 0167:0041011D LEA ECX,[ESP+18] 0167:00410121 MOV BYTE [ESP+B8],01 0167:00410129 CALL `MFC42!ord_00000320` 0167:0041012E LEA ECX,[ESP+24] 0167:00410132 MOV BYTE [ESP+B8],00 0167:0041013A CALL `MFC42!ord_00000320` 0167:0041013F LEA ECX,[ESP+1C] 0167:00410143 MOV DWORD [ESP+B8],FFFFFFFF 0167:0041014E CALL `MFC42!ord_00000320` 0167:00410153 XOR EAX,EAX 0167:00410155 JMP 00410504 0167:0041015A ADD EAX,000BCC09 <----將reg+BCC09,這是第一次變化. 0167:0041015F PUSH EAX 0167:00410160 LEA EAX,[ESP+1C] 0167:00410164 PUSH DWORD 004394C4<----指向一字串,"%8d" 0167:00410169 PUSH EAX 0167:0041016A CALL `MFC42!ord_00000B02`<----相當於printf("%8d",reg); 0167:0041016F MOV EAX,[ESP+24]<----EAX指向產生的字串串的首位址,以下記為[字串1] 0167:00410173 ADD ESP,BYTE +0C 0167:00410176 MOV DL,[EAX+01]<----將第2個字元取出到DL 0167:00410179 MOV CL,[EAX]<----將第1個字元取出到CL 0167:0041017B MOVSX EAX,BYTE [EAX+02]<----取第3字元到EAX 0167:0041017F MOVSX EDX,DL 0167:00410182 MOVSX ECX,CL 0167:00410185 ADD EAX,EDX 0167:00410187 LEA EAX,[EAX+ECX-90]<----EAX = 第1字元+ 第2字元 + 第3字元 - 90 0167:0041018E MOV ECX,07 0167:00410193 CDQ 0167:00410194 IDIV ECX 0167:00410196 LEA ECX,[ESP+18] 0167:0041019A ADD DL,30 <----DL 這是EAX除7後的餘數,加上30後轉化為ASCII碼的婁數字 0167:0041019D PUSH EDX 0167:0041019E PUSH BYTE +03 0167:004101A0 CALL `MFC42!ord_000016E0`<----此CALL將DL的值寫入字串串的第4字元處,即替換[字串1]第4字元 0167:004101A5 MOV EAX,[ESP+18] 0167:004101A9 MOV DL,[EAX+05]<----取出第6字元 0167:004101AC MOV CL,[EAX+04]<----取出第5字元 0167:004101AF MOVSX EAX,BYTE [EAX+06]<----取出第7字元 0167:004101B3 MOVSX EDX,DL 0167:004101B6 MOVSX ECX,CL 0167:004101B9 ADD EAX,EDX 0167:004101BB LEA EAX,[EAX+ECX-90]<----與上面一樣處理 0167:004101C2 MOV ECX,07 0167:004101C7 CDQ 0167:004101C8 IDIV ECX 0167:004101CA ADD DL,30<----這裡也與上面一樣處理 0167:004101CD PUSH EDX 0167:004101CE PUSH ECX 0167:004101CF LEA ECX,[ESP+20] 0167:004101D3 CALL `MFC42!ord_000016E0`<----替換[字串1]中的第8字元 0167:004101D8 MOV EAX,[ESP+18] 0167:004101DC MOV CL,[EAX+02] 0167:004101DF MOV BL,[EAX+01] 0167:004101E2 MOV DL,[EAX+07] 0167:004101E5 MOV [ESP+13],CL 0167:004101E9 MOV CL,[EAX+03] 0167:004101EC MOV [ESP+17],BL 0167:004101F0 MOV BL,[EAX+04] 0167:004101F3 MOV [ESP+15],CL 0167:004101F7 MOV CL,[EAX+06] 0167:004101FA MOV [ESP+16],BL 0167:004101FE MOV BL,[EAX] 0167:00410200 MOV AL,[EAX+05] 0167:00410203 MOV [ESP+14],AL 0167:00410207 MOVSX EAX,DL 0167:0041020A PUSH EAX<----到這裡註冊碼計算完成,這是最後一位註冊碼,第16位,[字串1]中的第8位 0167:0041020B MOVSX EAX,BYTE [ESP+17] 0167:00410210 ADD EAX,BYTE +15 0167:00410213 PUSH EAX <----第15位,[字串1]中第3位+15 0167:00410214 MOVSX EAX,BYTE [ESP+1D] 0167:00410219 PUSH EAX <----第14位,[字串1]中第4位 0167:0041021A MOVSX EAX,CL 0167:0041021D ADD EAX,BYTE +17 0167:00410220 PUSH EAX <----第13位,[字串1]中第7位+17 0167:00410221 MOVSX EAX,BYTE [ESP+27] 0167:00410226 PUSH EAX <----第12位,[字串1]中第2位 0167:00410227 MOVSX EAX,BYTE [ESP+2A] 0167:0041022C ADD EAX,BYTE +11 0167:0041022F PUSH EAX <----第11位,[字串1]中第5位+11 0167:00410230 MOVSX EAX,BL 0167:00410233 PUSH EAX <----第10位,[字串1]中第1位 0167:00410234 MOVSX EAX,BYTE [ESP+30] 0167:00410239 ADD EAX,BYTE +11 0167:0041023C PUSH EAX <----第9位,[字串1]中第6位+11 0167:0041023D MOVSX EAX,CL 0167:00410240 PUSH EAX <----第8位,[字串1]中第7位 0167:00410241 MOVSX EAX,BYTE [ESP+39] 0167:00410246 ADD EAX,BYTE +13 0167:00410249 PUSH EAX <----第7位,[字串1]中第4位+13 0167:0041024A MOVSX EAX,BYTE [ESP+3E] 0167:0041024F PUSH EAX <----第6位,[字串1]中第5位 0167:00410250 MOVSX EDX,DL 0167:00410253 MOVSX EAX,BYTE [ESP+40] 0167:00410258 ADD EDX,BYTE +12 0167:0041025B PUSH EDX <----第5位,[字串1]中第8位+12 0167:0041025C PUSH EAX <----第4位,[字串1]中第6位 0167:0041025D MOVSX EDX,BYTE [ESP+47] 0167:00410262 MOVSX EAX,CL 0167:00410265 MOVSX ECX,BL 0167:00410268 ADD EDX,BYTE +1B 0167:0041026B ADD ECX,BYTE +11 0167:0041026E PUSH EDX <----第3位,[字串1]中第3位+1B 0167:0041026F PUSH EAX <----第2位,[字串1]中第7位 0167:00410270 PUSH ECX <----第1位,[字串1]中第1位+11 0167:00410271 LEA EDX,[ESP+70] 0167:00410275 PUSH DWORD 004394A0<----指向一字串串"%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c" 0167:0041027A PUSH EDX 0167:0041027B CALL `MFC42!ord_00000B02`<----相當於printf(""%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c",...),返回時ECX指向產生的註冊碼 0167:00410280 MOV EAX,[ESP+64] 0167:00410284 ADD ESP,BYTE +48 0167:00410287 CMP DWORD [EAX-08],BYTE +13 0167:0041028B JNG 004102C0 0167:0041028D LEA ECX,[ESP+28] 0167:00410291 PUSH BYTE +13 0167:00410293 PUSH ECX 0167:00410294 LEA ECX,[ESP+24] 0167:00410298 CALL `MFC42!ord_0000164E` 0167:0041029D PUSH EAX 0167:0041029E LEA ECX,[ESP+20] 0167:004102A2 MOV BYTE [ESP+BC],06 0167:004102AA CALL `MFC42!ord_0000035A` 0167:004102AF LEA ECX,[ESP+28] 0167:004102B3 MOV BYTE [ESP+B8],04 0167:004102BB CALL `MFC42!ord_00000320` 0167:004102C0 MOV EDX,[ESP+30] 0167:004102C4 MOV EAX,[ESP+1C] 0167:004102C8 PUSH EDX 0167:004102C9 PUSH EAX 0167:004102CA CALL EBP 0167:004102CC ADD ESP,BYTE +08 0167:004102CF TEST EAX,EAX 0167:004102D1 JNZ 004102E0 0167:004102D3 MOV DWORD [ESP+2C],01 0167:004102DB JMP 004104A8 0167:004102E0 XOR EBX,EBX 0167:004102E2 PUSH EBX 0167:004102E3 LEA ECX,[ESP+44] 0167:004102E7 CALL 00408CE0 0167:004102EC LEA ECX,[ESP+20] 0167:004102F0 MOV BYTE [ESP+B8],07 0167:004102F8 CALL `MFC42!ord_0000021C` 0167:004102FD MOV ECX,[ESI+D0]<----取出註冊常數 0167:00410303 LEA EDX,[ESP+20] 0167:00410307 ADD ECX,000B4E9D<----將其加上B4E9D,所到結果以十六進位顯示後,就是軟體編號的後面部分(這一部分從第4字元開始) 0167:0041030D MOV BYTE [ESP+B8],08 0167:00410315 PUSH ECX 0167:00410316 PUSH DWORD 00439494 0167:0041031B PUSH EDX 0167:0041031C CALL `MFC42!ord_00000B02` 0167:00410321 ADD ESP,BYTE +0C 0167:00410324 LEA EAX,[ESP+34] 0167:00410328 LEA ECX,[ESP+24] 0167:0041032C MOV DWORD [ESP+34],0104 0167:00410334 PUSH EAX 0167:00410335 PUSH DWORD 0104 0167:0041033A CALL `MFC42!ord_00000B63` 0167:0041033F PUSH EAX 0167:00410340 CALL `KERNEL32!GetComputerNameA`<----取機器名 0167:00410346 PUSH BYTE -01 0167:00410348 LEA ECX,[ESP+28] 0167:0041034C CALL `MFC42!ord_000015C4` 0167:00410351 MOV ECX,[ESP+24] 0167:00410355 PUSH BYTE +03 0167:00410357 CMP DWORD [ECX-08],BYTE +03 <----如果機器名大於3字元,則軟體編號的前3位由機器名中取得,如果小於3位,則取軟體編號的3位. 0167:0041035B JNL 0041038B 0167:0041035D LEA EDX,[ESP+2C] 0167:00410361 LEA ECX,[ESP+24] 0167:00410365 PUSH EDX 0167:00410366 CALL `MFC42!ord_0000164E` 0167:0041036B PUSH EAX 0167:0041036C LEA ECX,[ESP+28] 0167:00410370 MOV BYTE [ESP+BC],09 0167:00410378 CALL `MFC42!ord_0000035A` 0167:0041037D MOV BYTE [ESP+B8],08 0167:00410385 LEA ECX,[ESP+28] 0167:00410389 JMP SHORT 004103B9 0167:0041038B LEA EAX,[ESP+2C] 0167:0041038F PUSH BYTE +01 0167:00410391 PUSH EAX 0167:00410392 LEA ECX,[ESP+30] 0167:00410396 CALL `MFC42!ord_000010B6` 0167:0041039B PUSH EAX 0167:0041039C LEA ECX,[ESP+28] 0167:004103A0 MOV BYTE [ESP+BC],0A 0167:004103A8 CALL `MFC42!ord_0000035A` 0167:004103AD MOV BYTE [ESP+B8],08 0167:004103B5 LEA ECX,[ESP+28] 0167:004103B9 CALL `MFC42!ord_00000320` 0167:004103BE LEA ECX,[ESP+24] 0167:004103C2 CALL `MFC42!ord_0000106A` 0167:004103C7 LEA ECX,[ESP+20] 0167:004103CB LEA EDX,[ESP+24] 0167:004103CF PUSH ECX 0167:004103D0 LEA EAX,[ESP+40] 0167:004103D4 PUSH EDX 0167:004103D5 PUSH EAX 0167:004103D6 CALL `MFC42!ord_0000039A` 0167:004103DB PUSH EAX 0167:004103DC LEA ECX,[ESP+AC] 0167:004103E3 MOV BYTE [ESP+BC],0B 0167:004103EB CALL `MFC42!ord_0000035A` 0167:004103F0 LEA ECX,[ESP+3C] 0167:004103F4 MOV BYTE [ESP+B8],08 0167:004103FC CALL `MFC42!ord_00000320` 0167:00410401 LEA ECX,[ESP+30] 0167:00410405 PUSH ECX 0167:00410406 LEA ECX,[ESP+A4] 0167:0041040D CALL `MFC42!ord_0000035A` 0167:00410412 LEA ECX,[ESP+40] 0167:00410416 MOV [ESP+A4],EDI 0167:0041041D CALL `MFC42!ord_000009D2`<----這裡彈出"註冊"對話視窗. --------------------------VC 註冊機程式碼---------------------------- void CKeyGenDlg::OnOK() { // TODO: Add extra validation here this->UpdateData(true); if(this->m_input == "") { this->m_output = "請輸入註冊用戶名"; this->m_edit2.SetWindowText(this->m_output); return; } //this->m_input 是輸入的用戶名,this->m_output 是輸出用的註冊碼。 char buf[50]; char regcode[20]; unsigned long reg; strcpy(buf,this->m_input); reg = hextoi(buf+3); reg -= 0xb4e9d; reg+= 0xbcc09; sprintf(buf,"%8lu",reg); buf[3]= ((buf[0]+buf[1]+buf[2]-0x90) % 7)+0x30; buf[7]= ((buf[4]+buf[5]+buf[6]-0x90) % 7)+0x30; sprintf(regcode,"%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c", buf[0]+0x11, buf[6], buf[2]+0x1b, buf[5], buf[7]+0x12, buf[4], buf[3]+0x13, buf[6], buf[5]+0x11, buf[0], buf[4]+0x11, buf[1], buf[6]+0x17, buf[3], buf[2]+0x15, buf[7]); this->m_output = regcode; //-------------------------------------------- this->m_edit2.SetWindowText(this->m_output); //*以下程式碼是將註冊碼寫入剪下板中。 if(OpenClipboard()) { HGLOBAL clipbuffer; char * buffer; EmptyClipboard(); clipbuffer = GlobalAlloc(GMEM_DDESHARE, this->m_output.GetLength()+1); buffer = (char*)GlobalLock(clipbuffer); strcpy(buffer, LPCSTR(this->m_output)); GlobalUnlock(clipbuffer); SetClipboardData(CF_TEXT,clipbuffer); CloseClipboard(); } //*/ } unsigned long CKeyGenDlg::hextoi(char *str) //將十六進位字串轉為LONG型。 { char n; int i,len; unsigned long sum,sum1; len = strlen(str); sum =0; sum1 =1; for(i=0;i<len;i++) { n = str[len-i-1]; if( n >='0' && n<='9' ) { n -= '0'; //轉為數字 } else { if(n >='a' && n <='f') { n-= 87; //轉為數字 } else { if(n>='A' && n <='F') { n-=55; //轉為數字 } else { //如果都不是,則返回 break; } } } sum += n * sum1; sum1*=16; } return sum; } |
送花文章: 3,
|