【原創】控制元件註冊 3dlink 1.6 sp2 的演算法詳解及序號產生器(手把手系列)

看雪資料發表於2015-11-15

控制元件註冊 3dlink 1.6 sp2 的演算法詳解及序號產生器 (手把手教你學註冊)

【破解作者】 jackily
【作者郵箱】 jackily_zhang@msn.com;jackily_zhang@yahoo.com.cn
【作者主頁】 http://estudy.ys168.com
【使用工具】 ollydbg 1.10 
【破解平臺】 Win9x/NT/2000/XP
【軟體名稱】 3dlink 1.6 sp2 控制元件
【下載地址】 http://www.3dlinx.com/downloads/3dlinx/3dlinx16sp2/3dlinx1_6sp2.zip
             http://estudy.ys168.com  其它目錄中的3dlintrail1.5.exe
【軟體簡介】 這個軟體是個控制元件,被VC,C++,DELPHI來呼叫,可以非常簡單地開發三維程式,這個是3dlinx最新版,安裝完畢後全部是DLL檔案。未註冊時,載入控制元件時會有一個nag視窗,並有30天使用限制和10個設計視窗限制。3dlintrail1.5.exe是前一版本的測試版,帶註冊程式,名字是LinXRegister.exe。先安裝1.6再安裝1.5版本,不要安裝在一起,就可以有一個獨立的程式來註冊了。
【破解宣告】 本破解純屬以學習為目的,偶得一點心得,願與大家分享!感謝Shooo提供了序號產生器的演算法思路,本人進行了修改(在總結中有說明)。
--------------------------------------------------------------------------------
【破解內容】
經分析,其實真正的註冊程式碼在1.6 sp2中的poppages.dll中。執行ollydbg,載入LinxRegister.exe。點右鍵―“搜尋”―“字元參考”,找
到ASCII "Registration succeeded!"。地址是00401719,在00401717跳轉處下斷,而這段程式碼源於00401650。按F9除錯,出現註冊畫面,分四
個輸入欄,第一個是3dlink產品名稱(可選);第二個是computer code entry(已自動生成,但可以修動);第三個是ID號(根據電腦配置和
作業系統自動生成,灰色不可修);第四個是註冊碼(要求使用者輸入)。第一欄是3DLINK,第二欄是“274925803”,第三欄是“481920”,在
第四欄中,我們輸入“1234567”。點註冊,在剛才下斷的地方停下來。程式碼分析如下:

00401650    > 51                push ecx
00401651    .  56                push esi
00401652    .  57                push edi
00401653    .  8BF1              mov esi,ecx
00401655    .  6A 01             push 1
00401657    .  BF 05400080       mov edi,80004005
0040165C    .  E8 7DC60000       call LinXRegi.0040DCDE
00401661    .  8B8E B0000000     mov ecx,dword ptr ds:[esi+B0]
00401667    .  85C9              test ecx,ecx
00401669    .  0F84 F9000000     je LinXRegi.00401768
0040166F    .  8B86 B4000000     mov eax,dword ptr ds:[esi+B4]
00401675    .  8B11              mov edx,dword ptr ds:[ecx]
00401677    .  8D0440            lea eax,dword ptr ds:[eax+eax*2]
0040167A    .  C1E0 02           shl eax,2
0040167D    .  8BB8 C0814100     mov edi,dword ptr ds:[eax+4181C0]
00401683    .  8B80 BC814100     mov eax,dword ptr ds:[eax+4181BC]
00401689    .  57                push edi
0040168A    .  50                push eax
0040168B    .  51                push ecx
0040168C    .  FF52 24           call dword ptr ds:[edx+24]            ;  poppages.01EBA5A5
0040168F    .  8BF8              mov edi,eax
00401691    .  85FF              test edi,edi
00401693    . /0F8C CF000000     jl LinXRegi.00401768
00401699    . |8B86 B0000000     mov eax,dword ptr ds:[esi+B0]
0040169F    . |50                push eax
004016A0    . |8B08              mov ecx,dword ptr ds:[eax]
004016A2    . |FF51 0C           call dword ptr ds:[ecx+C]                  ;分析是否已註冊,是則到004016A9,退出。
004016A5    . |85C0              test eax,eax                               
004016A7    . |75 18             jnz short LinXRegi.004016C1                ;否則跳至004016c1繼續註冊程式
004016A9    . |50                push eax
004016AA    . |68 90814100       push LinXRegi.00418190                       ;  ASCII "3DLinX Registration"
004016AF    . |68 60854100       push LinXRegi.00418560                       ;  ASCII "This product is already registered."
004016B4    . |8BCE              mov ecx,esi
004016B6    . |E8 C7BE0000       call LinXRegi.0040D582
004016BB    . |5F                pop edi
004016BC    . |33C0              xor eax,eax
004016BE    . |5E                pop esi
004016BF    . |59                pop ecx
004016C0    . |C3                retn
004016C1    > |8B86 A8000000     mov eax,dword ptr ds:[esi+A8]      ;ASII "1234567"      
004016C7    . |8B96 B0000000     mov edx,dword ptr ds:[esi+B0]      ;ASII "274925803"
004016CD    . |8BBE A0000000     mov edi,dword ptr ds:[esi+A0]      ; ASII "481920"   ,這三個數我們很熟悉吧。
004016D3    . |53                push ebx
004016D4    . |8B9E 98000000     mov ebx,dword ptr ds:[esi+98]
004016DA    . |8D4C24 0C         lea ecx,dword ptr ss:[esp+C]
004016DE    . |55                push ebp
004016DF    . |8B2A              mov ebp,dword ptr ds:[edx]
004016E1    . |51                push ecx
004016E2    . |50                push eax
004016E3    . |E8 160E0000       call LinXRegi.004024FE             ;將ASII碼變成HEX十六進位制數
004016E8    . |83C4 04           add esp,4
004016EB    . |50                push eax
004016EC    . |57                push edi
004016ED    . |E8 0C0E0000       call LinXRegi.004024FE                ;將ASII碼變成HEX十六進位制數
004016F2    . |83C4 04           add esp,4
004016F5    . |50                push eax
004016F6    . |53                push ebx
004016F7    . |E8 020E0000       call LinXRegi.004024FE               ;將ASII碼變成HEX十六進位制數
004016FC    . |8B96 B0000000     mov edx,dword ptr ds:[esi+B0]
00401702    . |83C4 04           add esp,4
00401705    . |50                push eax
00401706    . |52                push edx
00401707    . |FF55 20           call dword ptr ss:[ebp+20]    ;關鍵呼叫,動態載入poppages.dll 地址:01EBA253,跟進。
                                                               ;在實際除錯時,儘管在同一機器上,該呼叫地址會隨記憶體中程式而經
                                                                常變動。
0040170A    . |5D                pop ebp
0040170B    . |8BF8              mov edi,eax
0040170D    . |5B                pop ebx
0040170E    . |85FF              test edi,edi                    ;比較標誌,註冊失敗跳至00401750。成功則出現成功畫面。這裡不
                                                                 ;能完全爆破,因為在poppages.dll中的01EBA293 處有對控制元件檔案
                                                                ;的處理,否則只會出現成功畫面,但下次還提示註冊。
00401710    . |6A 00             push 0
00401712    . |68 90814100       push LinXRegi.00418190             ;  ASCII "3DLinX Registration"
00401717    . |7C 37             jl short LinXRegi.00401750            ;剛才下斷的地方
00401719    . |68 48854100       push LinXRegi.00418548                   ;  ASCII "Registration succeeded!"
0040171E    . |8BCE              mov ecx,esi
00401720    . |E8 5DBE0000       call LinXRegi.0040D582
00401725    . |68 34854100       push LinXRegi.00418534                       ;  ASCII "Product Registered"
0040172A    . |8D8E A4000000     lea ecx,dword ptr ds:[esi+A4]
00401730    . |E8 72D30000       call LinXRegi.0040EAA7
00401735    . |6A 00             push 0
00401737    . |8BCE              mov ecx,esi
00401739    . |E8 A0C50000       call LinXRegi.0040DCDE
0040173E    . |8BB6 B0000000     mov esi,dword ptr ds:[esi+B0]
00401744    . |56                push esi
00401745    . |8B06              mov eax,dword ptr ds:[esi]
00401747    . |FF50 28           call dword ptr ds:[eax+28]
0040174A    . |8BC7              mov eax,edi
0040174C    . |5F                pop edi
0040174D    . |5E                pop esi
0040174E    . |59                pop ecx
0040174F    . |C3                retn
00401750    > |68 04854100       push LinXRegi.00418504           ;  ASCII "Registration failure. Check input for validity."
00401755    . |8BCE              mov ecx,esi
00401757    . |E8 26BE0000       call LinXRegi.0040D582
0040175C    . |8BB6 B0000000     mov esi,dword ptr ds:[esi+B0]
00401762    . |56                push esi
00401763    . |8B06              mov eax,dword ptr ds:[esi]
00401765    . |FF50 28           call dword ptr ds:[eax+28]
00401768    > \8BC7              mov eax,edi
0040176A    .  5F                pop edi
0040176B    .  5E                pop esi
0040176C    .  59                pop ecx
0040176D    .  C3                retn

--------------------------------------------------------------------------------
由00401707跟進。
01EBA253     55                  push ebp                                     
01EBA254     8BEC                mov ebp,esp
01EBA256     83EC 30             sub esp,30
01EBA259     56                  push esi
01EBA25A     8B75 08             mov esi,dword ptr ss:[ebp+8]
01EBA25D     57                  push edi
01EBA25E     807E 1C 00          cmp byte ptr ds:[esi+1C],0
01EBA262     0F84 B0000000       je poppages.01EBA318
01EBA268     8B7D 10             mov edi,dword ptr ss:[ebp+10]
01EBA26B     393D B02FEF01       cmp dword ptr ds:[1EF2FB0],edi
01EBA271     0F85 A1000000       jnz poppages.01EBA318             ;以下三行是剛才轉換的三個HEX值
01EBA277     FFB6 68020000       push dword ptr ds:[esi+268]       ;ESI+268是"123456"的HEX值“1E240”
01EBA27D     57                  push edi                          ;EDI為ID的HEX值“75A80”。
01EBA27E     FF75 0C             push dword ptr ss:[ebp+C]         ;這裡是CODE ENTRY的HEX值“106308EB”
01EBA281     FF75 14             push dword ptr ss:[ebp+14]           ;這裡是0x69930,程式約定。
01EBA284     E8 B6680100         call poppages.01ED0B3F                ;關鍵,呼叫演算法程式,跟進。          
01EBA289     8B4D 18             mov ecx,dword ptr ss:[ebp+18]        
01EBA28C     83F8 01             cmp eax,1                             ;EAX是否為1,註冊碼比較標誌。
01EBA28F     8901                mov dword ptr ds:[ecx],eax
01EBA291     75 14               jnz short poppages.01EBA2A7           ;EAX不為1,註冊碼不正確。跳至poppages.01EBA2A7
01EBA293     6A 04               push 4                                ;正確的話,程式對控制元件進處理,解除註冊限制。
01EBA295     58                  pop eax
01EBA296     3946 14             cmp dword ptr ds:[esi+14],eax
01EBA299     74 79               je short poppages.01EBA314
01EBA29B     68 90C6EE01         push poppages.01EEC690
01EBA2A0     8946 14             mov dword ptr ds:[esi+14],eax
01EBA2A3     6A 09               push 9
01EBA2A5     EB 59               jmp short poppages.01EBA300
01EBA2A7     83F8 31             cmp eax,31
01EBA2AA     75 28               jnz short poppages.01EBA2D4
01EBA2AC     8D45 08             lea eax,dword ptr ss:[ebp+8]
01EBA2AF     6A 00               push 0
01EBA2B1     50                  push eax
01EBA2B2     8D45 10             lea eax,dword ptr ss:[ebp+10]
01EBA2B5     50                  push eax
01EBA2B6     8D45 0C             lea eax,dword ptr ss:[ebp+C]
01EBA2B9     50                  push eax
01EBA2BA     E8 42680100         call poppages.01ED0B01
01EBA2BF     FF75 08             push dword ptr ss:[ebp+8]
01EBA2C2     FF75 10             push dword ptr ss:[ebp+10]
01EBA2C5     FF75 0C             push dword ptr ss:[ebp+C]
01EBA2C8     6A 05               push 5
01EBA2CA     FF76 18             push dword ptr ds:[esi+18]
01EBA2CD     E8 48660100         call poppages.01ED091A
01EBA2D2     EB 40               jmp short poppages.01EBA314
01EBA2D4     83F8 32             cmp eax,32
01EBA2D7     75 31               jnz short poppages.01EBA30A
01EBA2D9     8B86 68020000       mov eax,dword ptr ds:[esi+268]
01EBA2DF     8B8E 6C020000       mov ecx,dword ptr ds:[esi+26C]
01EBA2E5     50                  push eax
01EBA2E6     8D9401 40E20100     lea edx,dword ptr ds:[ecx+eax+1E240]
01EBA2ED     52                  push edx
01EBA2EE     51                  push ecx
01EBA2EF     50                  push eax
01EBA2F0     8D45 D0             lea eax,dword ptr ss:[ebp-30]
01EBA2F3     57                  push edi
01EBA2F4     50                  push eax
01EBA2F5     E8 2E650100         call poppages.01ED0828
01EBA2FA     8D45 D0             lea eax,dword ptr ss:[ebp-30]
01EBA2FD     50                  push eax
01EBA2FE     6A 0A               push 0A
01EBA300     FF76 18             push dword ptr ds:[esi+18]
01EBA303     E8 255E0100         call poppages.01ED012D
01EBA308     EB 0A               jmp short poppages.01EBA314
01EBA30A     83F8 01             cmp eax,1
01EBA30D     7E 09               jle short poppages.01EBA318
01EBA30F     83F8 31             cmp eax,31
01EBA312     7D 04               jge short poppages.01EBA318
01EBA314     33C0                xor eax,eax
01EBA316     EB 05               jmp short poppages.01EBA31D
01EBA318     B8 05400080         mov eax,80004005
01EBA31D     5F                  pop edi
01EBA31E     5E                  pop esi
01EBA31F     C9                  leave
01EBA320     C2 1400             retn 14

--------------------------------------------------------------------------------
由01EBA284 跟進,關鍵演算法。
01ED0B3F     55                  push ebp
01ED0B40     8B5424 10           mov edx,dword ptr ss:[esp+10]  ;把ID的HEX值“75A80”給EDX
01ED0B44     8BEC                mov ebp,esp
01ED0B46     56                  push esi
01ED0B47     57                  push edi
01ED0B48     8345 14 34          add dword ptr ss:[ebp+14],34  ;把0x69930加0x34
01ED0B4C     83FA 01             cmp edx,1
01ED0B4F     7D 05               jge short poppages.01ED0B56
01ED0B51     BA 01000000         mov edx,1
01ED0B56     8B7D 0C             mov edi,dword ptr ss:[ebp+C]  ;把CODE ENTRY的HEX值“106308EB”給EDI
01ED0B59     8BCF                mov ecx,edi                   ;再分別賦於ECX和EAX
01ED0B5B     8BC7                mov eax,edi
01ED0B5D     81E1 00E00700       and ecx,7E000                ;ECX與0x7E000
01ED0B63     25 001F0000         and eax,1F00                  ;EAX與0x1F00
01ED0B68     C1E9 0D             shr ecx,0D                    ;ECX右移0x0D
01ED0B6B     C1E8 08             shr eax,8                    ;ECX右移0x8
01ED0B6E     81C1 BC070000       add ecx,7BC                 ;ECX加0x7BC
01ED0B74     6BC9 44             imul ecx,ecx,44             ;ECX乘0x44
01ED0B77     69C0 F3000000       imul eax,eax,0F3            ; EAX乘0x0F3
01ED0B7D     03C8                add ecx,eax                 ;ECX加EAX的值放入ECX中
01ED0B7F     8BC7                mov eax,edi                 ;再次把CODE ENTRY的HEX值“106308EB”給EAX
01ED0B81     25 00007800         and eax,780000              ;與0X780000
01ED0B86     C1E8 13             shr eax,13                  ;右移0X13
01ED0B89     69C0 08010000       imul eax,eax,108            ;乘0X108
01ED0B8F     8D3401              lea esi,dword ptr ds:[ecx+eax] ;把ECX和EAX的值相加放入ESI中
01ED0B92     8BCF                mov ecx,edi                      ; 再次把CODE ENTRY的HEX值“106308EB”給ECX
01ED0B94     81E1 0000807F       and ecx,7F800000           ;與0X7F800000
01ED0B9A     81E7 FF000000       and edi,0FF                ;EDI與0X0FF
01ED0BA0     C1E9 0F             shr ecx,0F                  ;ECX右移0X0F
01ED0BA3     8B45 14             mov eax,dword ptr ss:[ebp+14] ;把01ED0B48語句中的0X69964賦予EAX
01ED0BA6     6BC0 07             imul eax,eax,7                ;乘0X7
01ED0BA9     03CF                add ecx,edi                   ;ECX加EDI的值給ECX
01ED0BAB     6BC9 03             imul ecx,ecx,3                ;ECX乘0X3
01ED0BAE     03C8                add ecx,eax                     ;ECX加EAX的值給ECX
01ED0BB0     B8 01000000         mov eax,1                        ;賦予EAX1,目的是給註冊標誌。表示成功
01ED0BB5     8D0C51              lea ecx,dword ptr ds:[ecx+edx*2] ;把ECX加上EDX乘2的值給ECX
01ED0BB8     8BD6                mov edx,esi                      
01ED0BBA     6BD2 1F             imul edx,edx,1F                  ;EDX乘0X1F
01ED0BBD     03D1                add edx,ecx                      ;EDX加ECX
01ED0BBF     8D0C75 00000000     lea ecx,dword ptr ds:[esi*2]
01ED0BC6     8BF2                mov esi,edx                      ;EDX 給ESI
01ED0BC8     81E6 FFFFFF7F       and esi,7FFFFFFF                 ;ESI與0X7FFFFFFF,換算完畢。
01ED0BCE     3B75 08             cmp esi,dword ptr ss:[ebp+8]     ;關鍵比較,還記得EBP+8的內容嗎?這裡是“1E240”,也就是把 
                                                                   ; 換算的值和我們輸入的“123456”的HEX值比較。ESI內的值為“ 
                                                                    ; 802A35” ,換算為十進位制為“8399413”。      
01ED0BD1     74 0A               je short poppages.01ED0BDD       ;成功跳至01ED0BDD(這裡是真正的爆破點)
01ED0BD3     03D1                add edx,ecx
01ED0BD5     40                  inc eax
01ED0BD6     83F8 32             cmp eax,32
01ED0BD9   ^ 7E EB               jle short poppages.01ED0BC6
01ED0BDB     33C0                xor eax,eax                      ;給EAX賦予0,表示註冊不成功
01ED0BDD     5F                  pop edi
01ED0BDE     5E                  pop esi
01ED0BDF     5D                  pop ebp
01ED0BE0     C2 1000             retn 10

--------------------------------------------------------------------------------
【破解總結】
該控制元件的難點在於動態載入poppages.dll,有三個關鍵呼叫。不能用keymaker來作記憶體序號產生器,因為在程式碼分析中指出,poppages.dll的載入
是動態的,地址是隨時可變的,也就是說做出的記憶體序號產生器不能通用,只能用一次。因此爆破點應選在poppages.dll檔案中(w32dasm和hiew中的實際地址是10050BD1)。還需要指出的是在寫序號產生器的時候,以上01ED0B5D 、01ED0B81、01ED0B94中0X7E000、0X780000和0X7F800000中的0必須寫完整,還有必須用unsigned long(無符號,長整數)定義變數,否則不能得出正確結果。另外在01ED0BD3至01ED0BD9處的迴圈可以不用考慮。這就是在【宣告】中我提到的修改了的序號產生器演算法。

提供一組註冊碼
注 冊 項 目:3DLINK
CODE  ENTRY:274925803
COMPUTER ID:481920
SN         :8399413

--------------------------------------------------------------------------------
【演算法序號產生器】

/* 3Dlink 1.6 sp2演算法序號產生器 */
/* 在Turboc 2.0 下除錯透過  */
/* 感謝Shooo提供演算法思路       */
#include "stdio.h"
main()
{ unsigned long code,id;
  unsigned long i,j,k,l,m;
  printf("3DLINK 1.6 SP2 Register by jackily 2004-12-11\n");
  printf("Email:jackily_zhang@msn.com or jackily_zhang@yahoo.com.cn\n");
  printf("please input code entry:");
  scanf("%lu",&code);
  printf("\nplease input computer id:");
  scanf("%lu",&id);
   m=id;
  i=j=k=code;
  i&=0x7e000;i>>=0x0d;i+=0x7bc;i*=0x44;
  j&=0x1f00;j>>=0x08;j*=0xf3;
  i+=j;
  j=code;
  j&=0x780000;j>>=0x13;j*=0x108;
  l=i+j;
  i=code;
  i&=0x7f800000;i>>=0xf;
  k&=0xff;
  i+=k;
  i*=0x3;
  j=0x69964*0x7;
  i+=j;
  m*=2;
  i+=m;
  m=l;m*=0x1f;
  m+=i;
  l=m;
  l&=0x7fffffff;
  printf("\nserial number is %lu",l);
  }
--------------------------------------------------------------------------------
【版權宣告】 本文純屬技術交流, 轉載請註明作者並保持文章的完整, 謝謝!2004-12-11

相關文章