【原創】手把手系列之二―Axman 3.12r的註冊演算法詳解及序號產生器

看雪資料發表於2004-12-15

手把手系列之二―Axman 3.12rGB的註冊演算法詳解及序號產生器

【破解作者】 jackily
【作者郵箱】 jackily_zhang@msn.com;jackily_zhang@yahoo.com.cn
【作者主頁】 http://estudy.ys168.com
【使用工具】 ollydbg 1.10
【破解平臺】 Win9x/NT/2000/XP
【軟體名稱】 axman 3.12rGB
【下載地址】 http://www.pc123.cn/SoftView/SoftView_5625.html
【軟體簡介】 一個非常不錯的檔案分割工具,該工具的主要作用是可以將大檔案切成幾個小檔案便於複製到軟盤或作為電子郵件附件傳送。對於分割的檔案,程式提供自動合併功能,同時該工具也提供非常簡單的操作介面和操作方式以方便使用者使用。未註冊版本有30天的使用限制,並在開始程式時有nag視窗。
【破解宣告】 本破解純屬以學習為目的,偶得一點心得,願與大家分享:) xiA Qin 曾破解過3.10版(具體參見看雪精華II),但只是給了一個註冊碼而已,並沒有給出演算法和序號產生器,3.12版程式稍有變化,我們的目的是要找到演算法並寫出序號產生器。 
--------------------------------------------------------------------------------
【破解內容】
    安裝完畢後主檔案為axman.exe,用peid檢查無殼。用ollydbg載入,執行,出現提示註冊視窗,點選註冊,要求輸入name、company和註冊碼。這裡我們分別輸入jackily,http://estudy.ys168.com和123456。點確定,彈出“Invalid RegisterInformation”。好了,重新載入,點右鍵―“搜尋”―“字元參考”,找到剛才的ASCII碼,地址為00406933,向上看,00406923處有一call,為典型的註冊關鍵呼叫。在此處下斷,跟進。程式碼分析如下:
004068DA    .  8D45 F0           lea eax,dword ptr ss:[ebp-10]
004068DD    .  8D8E C8020000     lea ecx,dword ptr ds:[esi+2C8]
004068E3    .  50                push eax
004068E4    .  C645 FC 02        mov byte ptr ss:[ebp-4],2
004068E8    .  E8 B5B00000       call <jmp.&MFC42.#3874>          ;將"jackily"放入地址00674660
004068ED    .  8D45 E8           lea eax,dword ptr ss:[ebp-18]
004068F0    .  8D8E 08030000     lea ecx,dword ptr ds:[esi+308]
004068F6    .  50                push eax
004068F7    .  E8 A6B00000       call <jmp.&MFC42.#3874>          ; 將"http://estudy.ys168.com"放入地址006747a0
004068FC    .  8D45 EC           lea eax,dword ptr ss:[ebp-14]
004068FF    .  8D8E 88020000     lea ecx,dword ptr ds:[esi+288]
00406905    .  50                push eax
00406906    .  E8 97B00000       call <jmp.&MFC42.#3874>          ; 將ASCII "123456")放入地址00674840
0040690B    .  8D4D E4           lea ecx,dword ptr ss:[ebp-1C]
0040690E    .  E8 25FBFFFF       call AXMAN.00406438
00406913    .  FF75 EC           push dword ptr ss:[ebp-14]       ; /Arg3 = 00674840 ASCII "123456"
00406916    .  8D4D E4           lea ecx,dword ptr ss:[ebp-1C]    ; |
00406919    .  C645 FC 03        mov byte ptr ss:[ebp-4],3        ; |
0040691D    .  FF75 E8           push dword ptr ss:[ebp-18]       ; |Arg2 = 006747A0 ASCII "http://estudy.ys168.com"
00406920    .  FF75 F0           push dword ptr ss:[ebp-10]       ; |Arg1 = 00674660 ASCII "jackily"
00406923    .  E8 3CFBFFFF       call AXMAN.00406464                  ;典型的註冊模式,有點意思,跟進
00406928    .  84C0              test al,al                                  ; 檢驗註冊標誌,這裡成功應是非0
0040692A    .  75 18             jnz short AXMAN.00406944            ; 成功則到00406944 
0040692C    .  6A 30             push 30
0040692E    .  68 10AC4100       push AXMAN.0041AC10              ;  ASCII "AxMan - Error 400"
00406933    .  68 ECAB4100       push AXMAN.0041ABEC              ;  ASCII "Invalid Registration Information"
00406938    .  8BCE              mov ecx,esi
0040693A    .  E8 21B00000       call <jmp.&MFC42.#4224>
0040693F    .  E9 8E000000       jmp AXMAN.004069D2
00406944    >  8D85 54FEFFFF     lea eax,dword ptr ss:[ebp-1AC]
0040694A    .  68 BCAB4100       push AXMAN.0041ABBC              ; /src = "Thank you for registering your copy of AxMan
"
0040694F    .  50                push eax                         ; |dest
00406950    .  E8 CBB50000       call <jmp.&MSVCRT.strcpy>        ; \strcpy
00406955    .  8D85 54FEFFFF     lea eax,dword ptr ss:[ebp-1AC]
0040695B    .  68 68AB4100       push AXMAN.0041AB68              ; /src = "You will need to stop and restart AxMan to remove  the banner ads from displaying."
00406960    .  50                push eax                         ; |dest
00406961    .  E8 C0B50000       call <jmp.&MSVCRT.strcat>        ; \strcat
00406966    .  83C4 10           add esp,10
00406969    .  8D85 54FEFFFF     lea eax,dword ptr ss:[ebp-1AC]
0040696F    .  8BCE              mov ecx,esi
00406971    .  6A 30             push 30
00406973    .  68 D8A64100       push AXMAN.0041A6D8              ;  ASCII "AxMan"
00406978    .  50                push eax
00406979    .  E8 E2AF0000       call <jmp.&MFC42.#4224>          ; 解除程式限制,以下省略
                .
                .
                .
------------------------------------------------------------
由00406923跟進,一級呼叫
00406464   /$  55                push ebp
00406465   |.  8BEC              mov ebp,esp
00406467   |.  83EC 18           sub esp,18
0040646A   |.  8D45 E8           lea eax,dword ptr ss:[ebp-18]
0040646D   |.  50                push eax
0040646E   |.  FF75 0C           push dword ptr ss:[ebp+C]       ; (ASCII "http://estudy.ys168.com")
00406471   |.  FF75 08           push dword ptr ss:[ebp+8]       ; (ASCII "jackily")
00406474   |.  E8 18000000       call AXMAN.00406491             ;關鍵call,資料處理,為計算做準備,跟進
00406479   |.  FF75 10           push dword ptr ss:[ebp+10]           ; /s2 = "123456" 我們輸入的假碼
0040647C   |.  8D45 E8           lea eax,dword ptr ss:[ebp-18]        ; |
0040647F   |.  50                push eax                             ; |s1 = "156-936-773" ,真實的註冊碼,但不要忘記我們的目                                                                      ;的是找演算法,不應滿足在找到註冊碼的水平上
00406480   |.  E8 51BA0000       call <jmp.&MSVCRT.strcmp>            ; \strcmp 比較
00406485   |.  F7D8              neg eax
00406487   |.  59                pop ecx
00406488   |.  1AC0              sbb al,al
0040648A   |.  59                pop ecx
0040648B   |.  FEC0              inc al
0040648D   |.  C9                leave
0040648E   \.  C2 0C00           retn 0C

-----------------------------------------------------------------------------
由00406474跟進,以下為資料處理,為計算做準備,把name和company字串小寫,再將"My Love"(注意大小寫和空格)strcat在一起,也就是連線在一起。
00406491   /$  B8 C42B4100       mov eax,AXMAN.00412BC4
00406496   |.  E8 15BA0000       call AXMAN.00411EB0
0040649B   |.  81EC F8000000     sub esp,0F8
004064A1   |.  53                push ebx
004064A2   |.  56                push esi
004064A3   |.  57                push edi
004064A4   |.  8BF9              mov edi,ecx
004064A6   |.  FF75 08           push dword ptr ss:[ebp+8]            ; /s = "jackily"
004064A9   |.  E8 22BA0000       call <jmp.&MSVCRT.strlen>            ; \strlen  取字串長度
004064AE   |.  8B35 10464100     mov esi,dword ptr ds:[<&MSVCRT.mallo>;  MSVCRT.malloc
004064B4   |.  40                inc eax
004064B5   |.  50                push eax                             ; /size
004064B6   |.  FFD6              call esi                             ; \malloc
004064B8   |.  59                pop ecx
004064B9   |.  8BD8              mov ebx,eax
004064BB   |.  59                pop ecx
004064BC   |.  53                push ebx
004064BD   |.  8BCF              mov ecx,edi
004064BF   |.  FF75 08           push dword ptr ss:[ebp+8]
004064C2   |.  E8 63020000       call AXMAN.0040672A
004064C7   |.  FF75 0C           push dword ptr ss:[ebp+C]            ; /s = "http://estudy.ys168.com"
004064CA   |.  E8 01BA0000       call <jmp.&MSVCRT.strlen>            ; \strlen 取字串長度
            .
            .                                                         ;004064CF至0040651A非關鍵部分省略
            .
0040651F   |.  FF75 EC           push dword ptr ss:[ebp-14]           ; /src = "jackily"
00406522   |.  8D85 FCFEFFFF     lea eax,dword ptr ss:[ebp-104]       ; |(ASCII "http://estudy.ys168.com")
00406528   |.  50                push eax                             ; |dest = 0065EB98
00406529   |.  E8 F2B90000       call <jmp.&MSVCRT.strcpy>            ; \strcpy
0040652E   |.  FF75 F0           push dword ptr ss:[ebp-10]           ; /src = "http://estudy.ys168.com"
00406531   |.  8D85 FCFEFFFF     lea eax,dword ptr ss:[ebp-104]       ; | (ASCII "jackily")
00406537   |.  50                push eax                             ; |dest "jackily"
00406538   |.  E8 E9B90000       call <jmp.&MSVCRT.strcat>            ; \strcat
0040653D   |.  8D85 FCFEFFFF     lea eax,dword ptr ss:[ebp-104]
00406543   |.  68 60AB4100       push AXMAN.0041AB60                  ; /src = "My Love"
00406548   |.  50                push eax                             ; |dest
00406549   |.  E8 D8B90000       call <jmp.&MSVCRT.strcat>            ; \strcat
0040654E   |.  83C4 18           add esp,18
00406551   |.  8D45 E8           lea eax,dword ptr ss:[ebp-18]        ; (ASCII "jackilyhttp://estudy.ys168.comMy Love")
00406554   |.  8BCF              mov ecx,edi                          ;以上為 把name和company字串所有字元小寫並把“My Love”連線在一起  
00406556   |.  50                push eax
00406557   |.  8D85 FCFEFFFF     lea eax,dword ptr ss:[ebp-104]
0040655D   |.  50                push eax
0040655E   |.  E8 8D010000       call AXMAN.004066F0                   ;關鍵之關鍵,演算法,跟進 
00406563   |.  FF75 E8           push dword ptr ss:[ebp-18]           ; /<%u> = 95AAA45(註冊碼的HEX值,十進位制為156936773) 
00406566   |.  8D45 D0           lea eax,dword ptr ss:[ebp-30]        ; |
00406569   |.  68 40A04100       push AXMAN.0041A040                  ; |format = "%u" (c語言中代表無符號十進位制值)
0040656E   |.  50                push eax                             ; |s
0040656F   |.  FF15 30464100     call dword ptr ds:[<&MSVCRT.sprintf>>; \sprintf
00406575   |.  83C4 0C           add esp,0C
00406578   |.  8D45 D0           lea eax,dword ptr ss:[ebp-30]
0040657B   |.  8BCF              mov ecx,edi
0040657D   |.  6A 01             push 1
0040657F   |.  6A 09             push 9
00406581   |.  6A 30             push 30
00406583   |.  50                push eax
00406584   |.  E8 73000000       call AXMAN.004065FC
00406589   |.  8B75 10           mov esi,dword ptr ss:[ebp+10]        ; 以下是將156936773每三個數字間加“-”
0040658C   |.  8D45 D0           lea eax,dword ptr ss:[ebp-30]        ; ASII "156936773"
0040658F   |.  6A 03             push 3                               ; /maxlen = 3 複製前3個字元
00406591   |.  50                push eax                             ; |src = "156936773"
00406592   |.  56                push esi                             ; |dest
00406593   |.  FF15 D4454100     call dword ptr ds:[<&MSVCRT.strncpy>>; \strncpy
00406599   |.  8066 03 00        and byte ptr ds:[esi+3],0
0040659D   |.  BB 5CAB4100       mov ebx,AXMAN.0041AB5C
004065A2   |.  53                push ebx                             ; /src => "-"
004065A3   |.  56                push esi                             ; |dest = "156"
004065A4   |.  E8 7DB90000       call <jmp.&MSVCRT.strcat>            ; \strcat
004065A9   |.  8B3D D8454100     mov edi,dword ptr ds:[<&MSVCRT.strnc>;  MSVCRT.strncat
004065AF   |.  8D45 D3           lea eax,dword ptr ss:[ebp-2D]
004065B2   |.  6A 03             push 3                               ; /maxlen = 3
004065B4   |.  50                push eax                             ; |src = "936773"
004065B5   |.  56                push esi                             ; |dest = "156-"
004065B6   |.  FFD7              call edi                             ; \strncat
004065B8   |.  8066 07 00        and byte ptr ds:[esi+7],0
004065BD   |.  56                push esi                             ; |dest = "156-936"
004065BD   |.  56                push esi                             ; |dest
004065BE   |.  E8 63B90000       call <jmp.&MSVCRT.strcat>            ; \strcat
004065C3   |.  8D45 D6           lea eax,dword ptr ss:[ebp-2A]
            .
            .                                                         ;004065C6至004065EB非關鍵部分省略
            .
            .
004065EE   |.  5F                pop edi
004065EF   |.  5E                pop esi
004065F0   |.  5B                pop ebx
004065F1   |.  64:890D 00000000  mov dword ptr fs:[0],ecx
004065F8   |.  C9                leave
004065F9   \.  C2 0C00           retn 0C

-------------------------------------------------------------------
由 0040655E跟進,以下為此次重點,關鍵演算法,到這裡了,有一種自豪感吧。
004066F4   |.  33D2              xor edx,edx                  ; edx清0 
004066F6   |.  8A01              mov al,byte ptr ds:[ecx]     ;第一個字元“j”,HEX值為61,放入al
004066F8   |.  84C0              test al,al               
004066FA   |.  74 25             je short AXMAN.00406721      ;是0的話跳走
004066FC   |.  56                push esi                     ;開始計算
004066FD   |>  0FBEC0            /movsx eax,al                ;eax=al
00406700   |.  C1E2 04           |shl edx,4                   ; edx 左移0x4
00406703   |.  03D0              |add edx,eax                 ;edx=edx+eax 
00406705   |.  41                |inc ecx                     ; ecx加1,也就是上面指向字串地址向後移一位,取下一個字元
00406706   |.  8BC2              |mov eax,edx                 ;把edx值給eax 
00406708   |.  25 000000F0       |and eax,F0000000            ;與0xF0000000
0040670D   |.  74 07             |je short AXMAN.00406716     ;為0的話,至00406716
0040670F   |.  8BF0              |mov esi,eax
00406711   |.  C1EE 18           |shr esi,18
00406714   |.  33D6              |xor edx,esi                  ;異或
00406716   |>  F7D0              |not eax                     ;取反
00406718   |.  23D0              |and edx,eax                 ;
0040671A   |.  8A01              |mov al,byte ptr ds:[ecx]    ; 取下一個字元放入al裡
0040671C   |.  84C0              |test al,al                  ;檢查是否為0,也就是是否取完字串中的字元
0040671E   |.^ 75 DD             \jnz short AXMAN.004066FD    ;滿足條件的話,繼續計算
00406720   |.  5E                pop esi
00406721   |>  8B4424 08         mov eax,dword ptr ss:[esp+8]
00406725   |.  8910              mov dword ptr ds:[eax],edx   ;最終結果放EAX指向的地址裡
00406727   \.  C2 0800           retn 8
--------------------------------------------------------------------------------
【破解總結】
由此向上追溯到00406480處,為比較真假註冊碼。此註冊程式碼部分有三個關鍵call,分別是00406464、00406491和004066F0。個人認為關鍵演算法倒不是很難,難點在於要理解“資料處理”,也就是把name和company字串和"My Love"strcat在一起的部分,和將註冊碼每三個數字間加“-”這兩個部分運算。好在ollydbg除錯結構原理讓我們能清晰、直觀地分析這些呼叫。該序號產生器在本人檔案空間 http://estudy.ys168.com 可以下載。

【使用者名稱、密碼】
提供一組註冊碼:
name:jackily
company:http://estudy.ys168.com
code:156-936-773
--------------------------------------------------------------------------------
【演算法序號產生器】
【演算法序號產生器】
/* axman 3.12rGB c語言序號產生器 */
/* 在Turboc 2.0 下除錯透過  */
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
main()
{ char name[100]={0},company[50]={0},code[50]={0};
  int i;
  unsigned long l=0,k,m;
  printf("Axman 3.12rGB KeyGen by jackily 2004-12-15\n");
  printf("Email:jackily_zhang@msn.com or jackily_zhang@yahoo.com.cn\n");
  printf("please input name:");
  scanf("%s",name);
  printf("\nplease input company:");
  scanf("%s",company);
  strcat(name,company);
  strlwr(name);
  strcat(name,"My Love");
  for (i=0;i<strlen(name);i++)
     { k=name[i];l<<=0x4;l+=name[i];k=l;
     if ((k&=0xf0000000)!=0) { m=k; m>>=0x18; l^=m;}
     k=~k; /*0xffffffff-k;*/  /*not eax*/
     l&=k;
     }
  ltoa(l,code,10);  /* change "l" into string */
  printf("\nserial number is:");
  for (i=0;i<3;i++) printf("%c",code[i]);
  printf("-");
  for (i=3;i<6;i++) printf("%c",code[i]);
  printf("-");
  for (i=6;i<strlen(code);i++)
  printf("%c",code[i]);
  if (9-strlen(code)==1) printf("0");  /* 註冊碼長度小於9時,補0 */
  if (9-strlen(code)==2) printf("00");
  }
--------------------------------------------------------------------------------

【版權宣告】 本文純屬技術交流, 轉載請註明作者並保持文章的完整, 謝謝!
2004-11-15

相關文章