【原創】FileRecoveryAngel 演算法分析+序號產生器

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

破文作者: ZabShow
破解平臺: WinXP
軟體名稱: FileRecoveryAngel
軟體大小:  777 KB
軟體語言:  英文
軟體類別:  國外軟體 / 共享版 / 資料備份
應用平臺:  Win9x/NT/2000/XP
介面預覽:  無
加入時間:  2005-01-22 16:47:00
下載次數:  715
推薦等級:  
開 發 商: http://www.filerecoveryangel.com/
軟體介紹:   
    Filerecoveryangle是一款檔案恢復工具,它能夠幫助你從格式化成FAT12、FAT16、FAT32、NTFS檔案系統的磁碟中恢復被刪除的檔案。它不僅僅可以針對硬碟進行檔案恢復,它還很好地適用於軟盤、數位相機、USB驅動器、ZIP盤、CompactFlash卡、SmartMedia,以及索尼記憶棒。

保護方式:使用者名稱+ 序列號
破解目的:學習中。。。
破解工具:Peid,OD
破解宣告:我乃小菜鳥一隻,偶得一點心得,願與大家分享:)

破解過程: 


用peid檢視為:Borland Delphi 4.0 - 5.0 沒殼。呵呵~~~
註冊失敗後會顯示“Register False!”,用od載入後用字串外掛找到“Register False!”雙擊後來到004808EC:

004808E0   |.  BA B8094800       mov edx,FileReco.004809B8             ;  ASCII "IsRegister"
004808E5   |.  8BC7              mov eax,edi
004808E7   |.  E8 549AFEFF       call FileReco.0046A340
004808EC   |.  B8 700A4800       mov eax,FileReco.00480A70             ;  ASCII "Register`False!" <--------------來到這裡

004808F1   |.  E8 A6FAFCFF       call FileReco.0045039C
004808F6   |.  8BC7              mov eax,edi
004808F8   |.  E8 9325F8FF       call FileReco.00402E90

往上找到:
004807B6   |. /75 0F             jnz short FileReco.004807C7      ;比較使用者名稱是否為空

004807B8   |. |B8 4C094800       mov eax,FileReco.0048094C             ;  ASCII "Name can not been empty!"

004807BD   |. |E8 DAFBFCFF       call FileReco.0045039C
004807C2   |. |E9 36010000       jmp FileReco.004808FD
004807C7   |> \8B45 FC           mov eax,dword ptr ss:[ebp-4]     <----------- 在這裡下斷

我們在004807C7 處下斷執行程式,在註冊欄輸入:

Name: ZabShow
Key: 123456

點選Register後被od斷下,一路往下分析:

004807C7   |> \8B45 FC           mov eax,dword ptr ss:[ebp-4]          ;  使用者名稱:ZabShow        
004807CA   |.  E8 0936F8FF       call FileReco.00403DD8                ;  取長度:6位
004807CF   |.  8BF8              mov edi,eax
004807D1   |.  03FF              add edi,edi
004807D3   |.  8D55 EC           lea edx,dword ptr ss:[ebp-14]
004807D6   |.  8B86 E4020000     mov eax,dword ptr ds:[esi+2E4]
004807DC   |.  E8 639AFAFF       call FileReco.0042A244                ;  註冊碼:123456
004807E1   |.  8B45 EC           mov eax,dword ptr ss:[ebp-14]
004807E4   |.  8D55 F8           lea edx,dword ptr ss:[ebp-8]
004807E7   |.  E8 407DF8FF       call FileReco.0040852C
004807EC   |.  8D45 F8           lea eax,dword ptr ss:[ebp-8]
004807EF   |.  50                push eax
004807F0   |.  8BCF              mov ecx,edi
004807F2   |.  BA 02000000       mov edx,2
004807F7   |.  8B45 F8           mov eax,dword ptr ss:[ebp-8]          ;  註冊碼:123456
004807FA   |.  E8 E137F8FF       call FileReco.00403FE0
004807FF   |.  8D55 F4           lea edx,dword ptr ss:[ebp-C]
00480802   |.  8B45 FC           mov eax,dword ptr ss:[ebp-4]          ;  使用者名稱:ZabShow
00480805   |.  E8 7EA0FEFF       call FileReco.0046A888                ; 關鍵!!!我們等會進去

0048080A   |.  8B45 F4           mov eax,dword ptr ss:[ebp-C]          ;  真註冊碼
0048080D   |.  8B55 F8           mov edx,dword ptr ss:[ebp-8]          ;  假註冊碼
00480810   |.  E8 D336F8FF       call FileReco.00403EE8
00480815   |.  75 02             jnz short FileReco.00480819

到我們到達0048080A處,便可以看到真的註冊碼: DFF9D6A9898IDC,好!我們重新來過。

Name:ZabShow
Key: DFF9D6A9898IDC

點選Register後,傳說中的對話方塊又出來了,竟然提示錯誤!怎麼回事呢?我們們稍後分解!

現在進入按F7跟進 00480805 call FileReco.0046A888,也就是算註冊碼的地方:

0046A888   /$  55                push ebp
0046A889   |.  8BEC              mov ebp,esp
0046A88B   |.  33C9              xor ecx,ecx
0046A88D   |.  51                push ecx
0046A88E   |.  51                push ecx
0046A88F   |.  51                push ecx
0046A890   |.  51                push ecx
0046A891   |.  51                push ecx
0046A892   |.  51                push ecx
0046A893   |.  51                push ecx
0046A894   |.  51                push ecx
0046A895   |.  53                push ebx
0046A896   |.  56                push esi
0046A897   |.  57                push edi
0046A898   |.  8955 F8           mov dword ptr ss:[ebp-8],edx
0046A89B   |.  8945 FC           mov dword ptr ss:[ebp-4],eax          ;  使用者名稱
0046A89E   |.  8B45 FC           mov eax,dword ptr ss:[ebp-4]
0046A8A1   |.  E8 E696F9FF       call FileReco.00403F8C
0046A8A6   |.  33C0              xor eax,eax
0046A8A8   |.  55                push ebp
0046A8A9   |.  68 D2A94600       push FileReco.0046A9D2
0046A8AE   |.  64:FF30           push dword ptr fs:[eax]
0046A8B1   |.  64:8920           mov dword ptr fs:[eax],esp
0046A8B4   |.  8D45 F4           lea eax,dword ptr ss:[ebp-C]
0046A8B7   |.  E8 9C92F9FF       call FileReco.00403B58
0046A8BC   |.  8B45 FC           mov eax,dword ptr ss:[ebp-4]          ;  使用者名稱
0046A8BF   |.  E8 1495F9FF       call FileReco.00403DD8                ;  取使用者名稱長度
0046A8C4   |.  8BF0              mov esi,eax                           ;  EAX內為使用者名稱長度
0046A8C6   |.  85F6              test esi,esi
0046A8C8   |.  7E 29             jle short FileReco.0046A8F3           ;  若長度為0則跳
0046A8CA   |.  BB 01000000       mov ebx,1                             ;  設定讀取字元標記位
0046A8CF   |>  8D4D EC           /lea ecx,dword ptr ss:[ebp-14]
0046A8D2   |.  8B45 FC           |mov eax,dword ptr ss:[ebp-4]         ;  使用者名稱
0046A8D5   |.  0FB64418 FF       |movzx eax,byte ptr ds:[eax+ebw-1]    ;  逐位取使用者名稱字元,把ASCII碼存入EAX

0046A8DA   |.  BA 02000000       |mov edx,2
0046A8DF   |.  E8 2CDDF9FF       |call FileReco.00408610               ;  把ASCII碼由數值型變為字元型

0046A8E4   |.  8B55 EC           |mov edx,dword ptr ss:[ebp-14]        ;  字元型的ASCII
0046A8E7   |.  8D45 F4           |lea eax,dword ptr ss:[ebp-C]
0046A8EA   |.  E8 F194F9FF       |call FileReco.00403DE0               ;  存入字串
0046A8EF   |.  43                |inc ebx
0046A8F0   |.  4E                |dec esi                              ;  計數器減1
0046A8F1   |.^ 75 DC             \jnz short FileReco.0046A8CF          ;  沒取完則跳
0046A8F3   |>  8B45 F4           mov eax,dword ptr ss:[ebp-C]          ;  由ASCII碼變換後的字串

0046A8F6   |.  E8 DD94F9FF       call FileReco.00403DD8                ;  取長度
0046A8FB   |.  8BD8              mov ebx,eax
0046A8FD   |.  E8 4680F9FF       call FileReco.00402948
0046A902   |.  83FB 14           cmp ebx,14                            ;  長度與14h比較
0046A905   |.  7E 1B             jle short FileReco.0046A922           ;  小於則跳
0046A907   |.  8D45 F4           lea eax,dword ptr ss:[ebp-C]
0046A90A   |.  50                push eax
0046A90B   |.  B9 14000000       mov ecx,14
0046A910   |.  BA 01000000       mov edx,1
0046A915   |.  8B45 F4           mov eax,dword ptr ss:[ebp-C]
0046A918   |.  E8 C396F9FF       call FileReco.00403FE0                ;  把20位後的字元全部去掉

0046A91D   |.  BB 14000000       mov ebx,14
0046A922   |>  8BF3              mov esi,ebx                           ;  把長度給ESI
0046A924   |.  85F6              test esi,esi                          ;  測試長度是否為0
0046A926   |.  7E 7F             jle short FileReco.0046A9A7           ;  為0則跳
0046A928   |.  BB 01000000       mov ebx,1                             ;  設定讀取字元標記位
0046A92D   |>  8D45 E8           /lea eax,dword ptr ss:[ebp-18]
0046A930   |.  8B55 F4           |mov edx,dword ptr ss:[ebp-C]         ;  由ASCII碼變換後的字串

0046A933   |.  8A541A FF         |mov dl,byte ptr ds:[edx+ebw-1]       ;  逐位取字元。把ASCII碼存入dl

0046A937   |.  E8 C493F9FF       |call FileReco.00403D00
0046A93C   |.  8B45 E8           |mov eax,dword ptr ss:[ebp-18]
0046A93F   |.  BA E8A94600       |mov edx,FileReco.0046A9E8            ; 表1:abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

0046A944   |.  E8 7B97F9FF       |call FileReco.004040C4               ;  將字元與表1比對找到其所在位置,記下位置數,存在EAX內

0046A949   |.  8BF8              |mov edi,eax                          ;  把EAX送給edi,設為數1

0046A94B   |.  85FF              |test edi,edi
0046A94D   |.  7F 0C             |jg short FileReco.0046A95B
0046A94F   |.  8B45 F4           |mov eax,dword ptr ss:[ebp-C]
0046A952   |.  8A4418 FF         |mov al,byte ptr ds:[eax+ebw-1]
0046A956   |.  8845 F3           |mov byte ptr ss:[ebp-D],al
0046A959   |.  EB 2F             |jmp short FileReco.0046A98A
0046A95B   |>  8D45 E4           |lea eax,dword ptr ss:[ebp-1C]
0046A95E   |.  BA 30AA4600       |mov edx,FileReco.0046AA30            ;  表2:85987456212365897456

0046A963   |.  8A541A FF         |mov dl,byte ptr ds:[edx+ebw-1]       ;  取上面的表2的各位的ASCII碼

0046A967   |.  E8 9493F9FF       |call FileReco.00403D00
0046A96C   |.  8B45 E4           |mov eax,dword ptr ss:[ebp-1C]
0046A96F   |.  E8 D8DCF9FF       |call FileReco.0040864C               ;  把從表2取的字元轉化為數字,設為數2

0046A974   |.  03F8              |add edi,eax                          ;  數1與數2相加
0046A976   |.  83FF 3E           |cmp edi,3E                           ;  比較是否小於62
0046A979   |.  7E 03             |jle short FileReco.0046A97E          ;  小於則跳
0046A97B   |.  83EF 3E           |sub edi,3E                           ;  如果大於62則減62
0046A97E   |>  B8 E8A94600       |mov eax,FileReco.0046A9E8            ;  表1:abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

0046A983   |.  8A4438 FF         |mov al,byte ptr ds:[eax+edg-1]       ;  從表中依據edi找到找到相應的字元

0046A987   |.  8845 F3           |mov byte ptr ss:[ebp-D],al           ;  存入記憶體
0046A98A   |>  8D45 E0           |lea eax,dword ptr ss:[ebp-20]
0046A98D   |.  8A55 F3           |mov dl,byte ptr ss:[ebp-D]
0046A990   |.  E8 6B93F9FF       |call FileReco.00403D00               ;  連線成字串
0046A995   |.  8B55 E0           |mov edx,dword ptr ss:[ebp-20]
0046A998   |.  8B45 F8           |mov eax,dword ptr ss:[ebp-8]
0046A99B   |.  E8 4094F9FF       |call FileReco.00403DE0
0046A9A0   |.  8B45 F8           |mov eax,dword ptr ss:[ebp-8]
0046A9A3   |.  43                |inc ebx
0046A9A4   |.  4E                |dec esi                              ;  計數器減1
0046A9A5   |.^ 75 86             \jnz short FileReco.0046A92D
0046A9A7   |>  33C0              xor eax,eax
0046A9A9   |.  5A                pop edx
0046A9AA   |.  59                pop ecx
0046A9AB   |.  59                pop ecx
0046A9AC   |.  64:8910           mov dword ptr fs:[eax],edx
0046A9AF   |.  68 D9A94600       push FileReco.0046A9D9
0046A9B4   |>  8D45 E0           lea eax,dword ptr ss:[ebp-20]
0046A9B7   |.  BA 04000000       mov edx,4
0046A9BC   |.  E8 BB91F9FF       call FileReco.00403B7C
0046A9C1   |.  8D45 F4           lea eax,dword ptr ss:[ebp-C]
0046A9C4   |.  E8 8F91F9FF       call FileReco.00403B58
0046A9C9   |.  8D45 FC           lea eax,dword ptr ss:[ebp-4]
0046A9CC   |.  E8 8791F9FF       call FileReco.00403B58
0046A9D1   \.  C3                retn
0046A9D2    .^ E9 198CF9FF       jmp FileReco.004035F0
0046A9D7    .^ EB DB             jmp short FileReco.0046A9B4
0046A9D9    .  5F                pop edi
0046A9DA    .  5E                pop esi
0046A9DB    .  5B                pop ebx
0046A9DC    .  8BE5              mov esp,ebp
0046A9DE    .  5D                pop ebp
0046A9DF    .  C3                retn                            ;返回

綜上:
本軟體為典型的使用者名稱+註冊碼式的註冊方式
其中要用到兩個表
T1=abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
T2=85987456212365897456
1.對使用者名稱的每一位字元取ASCII碼儲存為16進位制,在把 ASCII碼由數值型轉為字串型並依次存入字串STR1中,如果STR1的長度大於14H(20)則把20位後的截掉.
2.對STR1中的每一個字元,依次從T1表中找到與其相同字元,並記下位置號記為pos,再對T2表中依次取字元,並變為數值型與pos相加得到tmp1.
3.將tmp1與3EH(62)相比較,如果大於則將tmp1減去62.
4.再從T1表中由tmp1的值確定相應位置的一個字元設為tmpKey
5.最後將所有的tmpKey相連則就是所要的註冊碼了.

好!
下面來解答我們前面留下的問題,為什麼輸入正確的註冊碼後仍然不能註冊呢?
原因在這裡:
0048080A   |.  8B45 F4           mov eax,dword ptr ss:[ebp-C]          ;  真註冊碼
0048080D   |.  8B55 F8           mov edx,dword ptr ss:[ebp-8]          ;  假註冊碼
當在0048080A 時我們能看到程式算出的真註冊碼,下d eax可以看到註冊碼為DFF9D6A9898IDC
而0048080D 是我們自己輸入的註冊碼,下d edx可以看到註冊碼為FF9D6A9898IDC。呵呵
看出來了吧,原來程式把我們輸入的註冊碼的第一位給去掉了,也就是說第一位註冊碼不參與比較,只是用來湊數的,或是讓人家做的記憶體序號產生器沒用(因為別人不知道註冊碼的第一位被省去啦),所以我們只要在真註冊碼前面隨便添一位就可以了( 我加的是D ).

Name: ZabShow
Key: DDFF9D6A9898IDC

另附序號產生器程式碼(Delphi):

for i:=1 to length(name) do
    tmp1:=tmp1+inttohex(ord(name[i]),2);
if length(tmp1)>20 then
  tmp1:=copy(tmp1,1,20);
for i:=1 to length(tmp1) do
begin
  tmpPos:=pos(tmp1[i],t1);
  tmp3:=copy(t2,i,1);
  tmpCode:=tmpPos+strtoint(tmp3);
  if tmpCode>62 then
    tmpCode:=tmpCode-62;
  key:=key+copy(t1,tmpCode,1);
end;
key:='D'+key;

相關文章