專業名片、卡片、胸牌製作系統CardMaker 3.3

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

標 題:專業名片、卡片、胸牌製作系統CardMaker 3.3

發信人:yesky1

時 間:2003年10月01日 07:47 

詳細資訊:


軟體名稱:   專業名片、卡片、胸牌製作系統CardMaker 
最新版本:   3.3 
適用平臺:   Win9x, WinME, WinNT, Win2000, WinXP 
軟體作者:   方麗  
作者主頁:    http://www.flisoft.net 

主要功能: 
    專業名片、卡片、胸牌製作系統CardMaker,內建超大圖形庫(近百種,包括基本線條、基本形狀、箭頭總彙、流程圖、星與旗幟、標註等

)、超大影像庫(近百種,包括各類背景、各類線條等,並還在不斷擴充),具有強大的圖形處理能力、強大的影像處理能力、強大的文字處

理能力,對各類要素都提供了豐富的要素渲染方案,系統提供了完善的資料庫功能,完全解決了編輯一張卡片列印不同姓名、不同職位、不

同...的任意多張卡片這一卡片系統業的長期困擾。使用本系統你可以列印名片、各類卡片、各類胸牌、餐票,可以一次性列印出你單位所有人

的出入證、胸牌而不需你再手工添上他們的姓名、職位,可以一次性列印出給你所有朋友或客戶的信封標貼,可以列印出超級專業、優美無比

的各類名片。

【軟體限制】:10天后功能限制
 

【難    度】: 爆破簡單,演算法稍繁

【作者宣告】:初學Crack,只是感興趣,沒有其它目的。失誤之處敬請諸位大俠賜教!  

【破解工具】:olldydbg、IDA Pro

―――――――――――――――――――――――――――――――――   
【過    程】:  

首先 Peid測無殼,VC程式,就是個頭有些大,2兆多,IDA跑了好一會,才反彙編完。

首先注意到未註冊標題欄有'[Not register 0/10]'字樣,於是
IDA中查詢,找到Not register的其引用之處:

SoftwareMicrosoftWindowsCurrentVersion下RdPrintCurrentVersion301項明碼,使用了幾天就是幾,:)

在讀寫了System32jgldog301.dll此檔案,不是dll檔案,只是個資料檔案。估計也是儲存使用資訊的,沒深究。

....
前面省去讀取登錄檔和jgldog301.dll校驗使用時間的程式碼。
....
.text:0042888B                 lea     edx, [esp+1BCh+FileSystemFlags]
.text:0042888F                 lea     ecx, [esp+1BCh+VolumeSerialNumber]
.text:00428896                 push    0Ah             ; nFileSystemNameSize
.text:00428898                 push    eax             ; lpFileSystemNameBuffer
.text:00428899                 lea     eax, [esp+1C4h+MaximumComponentLength]
.text:0042889D                 push    edx             ; lpFileSystemFlags
.text:0042889E                 push    eax             ; lpMaximumComponentLength
.text:0042889F                 push    ecx             ; lpVolumeSerialNumber
.text:004288A0                 push    0Ch             ; nVolumeNameSize
.text:004288A2                 push    esi             ; lpVolumeNameBuffer
.text:004288A3                 push    offset aC       ; lpRootPathName
.text:004288A8                 call    ds:GetVolumeInformationA  ; 讀取C盤的序列號
.text:004288AE                 mov     edx, [esp+1BCh+VolumeSerialNumber]
.text:004288B5                 lea     eax, [esp+1BCh+var_190]
.text:004288B9                 push    offset unk_56AD0C         ; 記憶體中一張表,變換C盤序列號時使用
.text:004288BE                 lea     ecx, [esp+1C0h+var_194]
.text:004288C2                 push    eax
.text:004288C3                 push    ecx
.text:004288C4                 mov     [esp+1C8h+var_194], edx ; C盤序列號
.text:004288C8                 mov     [esp+1C8h+var_190], 19320h ; 種子數
.text:004288D0                 call    sub_425480  ; <========== *********追演算法關鍵,
.text:004288D5                 fild    [esp+1C8h+var_194] ; 將變換後結果作為整數壓入浮點棧
.text:004288D9                 add     esp, 0Ch
.text:004288DC                 fstp    qword ptr [esp+1BCh+var_188] ; 變換後結果作為浮點數,彈出浮點棧,留待待會比較
.text:004288E0                 call    ?AfxGetModuleState@@YGPAVAFX_MODULE_STATE@@XZ ; AfxGetModuleState(void)
.text:004288E5                 mov     eax, [eax+4]
.text:004288E8                 push    edi
.text:004288E9                 push    offset aSerilno ; "SerilNo"
.text:004288EE                 lea     edx, [esp+1C4h+Type]
.text:004288F2                 push    offset aVSV     ; "註冊資訊"
.text:004288F7                 push    edx
.text:004288F8                 mov     ecxeax
.text:004288FA                 call    sub_508B2B      ; 讀取儲存在登錄檔中的待驗證註冊碼 

HKEY_CURRENT_USERSoftwareFLi'SoftCardMaker註冊資訊 下 Serial項
.text:004288FF                 push    offset asc_56939C ; "-"
.text:00428904                 lea     ecx, [esp+1C0h+Type]
.text:00428908                 mov     [esp+1C0h+var_4], 4
.text:00428913                 call    sub_4E60A8      ; 註冊碼中"-"位置
.text:00428918                 mov     ebpeax
.text:0042891A                 test    ebpebp
.text:0042891C                 jle     loc_428A0D      ; 若沒有"-",則出錯
.text:00428922                 lea     eax, [esp+1BCh+MaximumComponentLength]
.text:00428926                 push    ebp
.text:00428927                 push    eax
.text:00428928                 lea     ecx, [esp+1C4h+Type]
.text:0042892C                 mov     [esp+1C4h+var_1A8], edi
.text:00428930                 call    sub_4E5FE3      ; 取註冊碼中"-"前部分
.text:00428935                 mov     ecx, [esp+1BCh+MaximumComponentLength]
.text:00428939                 mov     eax, [ecx-8]
.text:0042893C                 test    eaxeax
.text:0042893E                 jle     short loc_42897D
.text:00428940                 lea     ecx, [eax+ecx-1]
.text:00428944                 mov     edxeax
.text:00428946 
.text:00428946 loc_428946:                             ; CODE XREF: sub_428440+537j
.text:00428946                 lea     eaxds:0[edi*8]  ; //開始對註冊碼進行變換,從右至左
.text:0042894D                 sub     eaxedi
.text:0042894F                 lea     edi, [eax+eax*4]  ; 以上三句實現功能類似edi = 35d * edi
.text:00428952                 mov     al, [ecx]
.text:00428954                 cmp     al, 61h           ; 如果ASCII碼值大於'a'
.text:00428956                 jb      short loc_42895C
.text:00428958                 sub     al, 3Dh           
.text:0042895A                 jmp     short loc_428966
.text:0042895C ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0042895C 
.text:0042895C loc_42895C:                             ; CODE XREF: sub_428440+516j
.text:0042895C                 cmp     al, 41h           ;  如果ASCII碼值大於'A'
.text:0042895E                 jb      short loc_428964
.text:00428960                 sub     al, 37h
.text:00428962                 jmp     short loc_428966
.text:00428964 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00428964 
.text:00428964 loc_428964:                             ; CODE XREF: sub_428440+51Ej
.text:00428964                 sub     al, 30h
.text:00428966 
.text:00428966 loc_428966:                             ; CODE XREF: sub_428440+51Aj
.text:00428966                                         ; sub_428440+522j
.text:00428966                 mov     byte ptr [esp+1BCh+FileSystemFlags], al
.text:0042896A                 mov     eax, [esp+1BCh+FileSystemFlags]
.text:0042896E                 and     eax, 0FFh
.text:00428973                 add     edieax        ; edi = edi + eax
.text:00428975                 dec     ecx
.text:00428976                 dec     edx
.text:00428977                 jnz     short loc_428946 ; //迴圈前一位元組對註冊碼進行變換
.text:00428979                 mov     [esp+1BCh+var_1A8], edi
.text:0042897D 
.text:0042897D loc_42897D:                             ; CODE XREF: sub_428440+4FEj
.text:0042897D                 lea     ecx, [esp+1BCh+MaximumComponentLength]
.text:00428981                 call    sub_4EE588
.text:00428986                 mov     ecx, [esp+1BCh+Type]
.text:0042898A                 xor     esiesi
.text:0042898C                 lea     edx, [esp+1BCh+cbData]
.text:00428990                 mov     eax, [ecx-8]
.text:00428993                 lea     ecx, [esp+1BCh+Type]
.text:00428997                 sub     eaxebp
.text:00428999                 dec     eax
.text:0042899A                 push    eax
.text:0042899B                 push    edx
.text:0042899C                 call    sub_4E5F67  ; 取註冊碼中"-"後部分,不過好像驗證註冊碼沒有用到這裡的結果?? 演算法於前一部

分類似
.text:004289A1                 mov     ecx, [esp+1BCh+cbData]
.text:004289A5                 mov     eax, [ecx-8]
.text:004289A8                 test    eaxeax
.text:004289AA                 jle     short loc_4289E4
.text:004289AC                 lea     ecx, [eax+ecx-1]
.text:004289B0                 mov     edxeax
.text:004289B2 
.text:004289B2 loc_4289B2:                             ; CODE XREF: sub_428440+5A2j
.text:004289B2                 mov     eaxesi
.text:004289B4                 shl     eax, 4
.text:004289B7                 add     eaxesi
.text:004289B9                 shl     eax, 1
.text:004289BB                 mov     esieax
.text:004289BD                 mov     al, [ecx]
.text:004289BF                 cmp     al, 61h
.text:004289C1                 jb      short loc_4289C7
.text:004289C3                 sub     al, 3Dh
.text:004289C5                 jmp     short loc_4289D1
.text:004289C7 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:004289C7 
.text:004289C7 loc_4289C7:                             ; CODE XREF: sub_428440+581j
.text:004289C7                 cmp     al, 41h
.text:004289C9                 jb      short loc_4289CF
.text:004289CB                 sub     al, 37h
.text:004289CD                 jmp     short loc_4289D1
.text:004289CF ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:004289CF 
.text:004289CF loc_4289CF:                             ; CODE XREF: sub_428440+589j
.text:004289CF                 sub     al, 30h
.text:004289D1 
.text:004289D1 loc_4289D1:                             ; CODE XREF: sub_428440+585j
.text:004289D1                                         ; sub_428440+58Dj
.text:004289D1                 mov     byte ptr [esp+1BCh+FileSystemFlags], al
.text:004289D5                 mov     eax, [esp+1BCh+FileSystemFlags]
.text:004289D9                 and     eax, 0FFh
.text:004289DE                 add     esieax
.text:004289E0                 dec     ecx
.text:004289E1                 dec     edx
.text:004289E2                 jnz     short loc_4289B2
.text:004289E4 
.text:004289E4 loc_4289E4:                             ; CODE XREF: sub_428440+56Aj
.text:004289E4                 lea     ecx, [esp+1BCh+cbData]
.text:004289E8                 call    sub_4EE588
.text:004289ED                 fild    [esp+1BCh+var_1A8] ; 將註冊碼中"-"前部分變換結果壓入浮點棧
.text:004289F1                 mov     [esp+1BCh+var_194], edi
.text:004289F5                 mov     [esp+1BCh+var_190], esi
.text:004289F9                 fcomp   qword ptr [esp+1BCh+var_188]  <======== ******* 關鍵比較, 註冊碼中"-"前部分變換結果 與 

使用者c盤序列號變換結果進行比較。
.text:004289FD                 fnstsw  ax
.text:004289FF                 test    ah, 40h
.text:00428A02                 jz      short loc_428A0B  ; 註冊碼錯誤則跳,爆破可以修改這裡
.text:00428A04                 mov     edi, 1
.text:00428A09                 jmp     short loc_428A0D
.text:00428A0B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00428A0B 
.text:00428A0B loc_428A0B:                             ; CODE XREF: sub_428440+5C2j
.text:00428A0B                 xor     ediedi
.text:00428A0D 
.text:00428A0D loc_428A0D:                             ; CODE XREF: sub_428440+4DCj
.text:00428A0D                                         ; sub_428440+5C9j
.text:00428A0D                 lea     ecx, [esp+1BCh+Type]
.text:00428A11                 mov     [esp+1BCh+var_4], ebx
.text:00428A18                 call    sub_4EE588
.text:00428A1D                 test    ediedi
.text:00428A1F                 pop     edi
.text:00428A20                 pop     esi
.text:00428A21                 pop     ebp
.text:00428A22                 pop     ebx
.text:00428A23                 jz      short loc_428A3B
.text:00428A25                 mov     ecx, [esp+1ACh+var_18C]
.text:00428A29                 push    offset aPowerfulCardMa ; lpString "Powerful Card Maker 3.3"
.text:00428A2E                 add     ecx, 0ACh
.text:00428A34                 call    ??4CString@@QAEABV0@PBD@Z ; CString::operator=(char const *)
.text:00428A39                 jmp     short loc_428A59
.text:00428A3B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00428A3B 
.text:00428A3B loc_428A3B:                             ; CODE XREF: sub_428440+5E3j
.text:00428A3B                 mov     edx, [esp+1ACh+var_1A4]
.text:00428A3F                 mov     eax, [esp+1ACh+var_18C]
.text:00428A43                 push    0Ah
.text:00428A45                 push    edx
.text:00428A46                 add     eax, 0ACh
.text:00428A4B                 push    offset aPowerfulCard_0 ; "Powerful Card Maker 3.3[Not register%d/"...
.text:00428A50                 push    eax
.text:00428A51                 call    sub_4E642E
.text:00428A56                 add     esp, 10h
.text:00428A59 
.text:00428A59 loc_428A59:                             ; CODE XREF: sub_428440+5F9j
.text:00428A59                 mov     ecx, [esp+1ACh+arg_0]
.text:00428A60                 mov     eax, 1
.text:00428A65                 mov     dword ptr [ecx+20h], 1CF8000h
.text:00428A6C                 mov     ecx, [esp+1ACh+var_C]
.text:00428A73                 mov     large fs:0, ecx
.text:00428A7A                 add     esp, 1ACh
.text:00428A80 
.text:00428A80 unknown_libname_45:
.text:00428A80                 retn    4
.text:00428A80 sub_428440      endp





下面看一下對硬碟序列號的變換:
sub_425480 
.text:00425480                 push    ebx
.text:00425481                 mov     ebx, [esp+arg_0]   ;  ebx 高32位 種子數19320h 
.text:00425485                 push    ebp
.text:00425486                 mov     ebp, [esp+4+arg_8] ;  ebp -->56AD0C 記憶體中表查表
.text:0042548A                 push    esi
.text:0042548B                 mov     esi, [esp+8+arg_4] ;  esi 低32位 硬碟序列號
.text:0042548F                 push    edi
.text:00425490                 mov     edi, offset unk_56ADAC ; 還是記憶體中的表
.text:00425495 
.text:00425495 loc_425495:                             ; CODE XREF: sub_425480+3Ej
.text:00425495                 mov     eax, [edi]
.text:00425497                 mov     ecx, [ebp+eax*4+0]
.text:0042549B                 mov     eax, [ebx]
.text:0042549D                 add     ecxeax
.text:0042549F                 push    ecx
.text:004254A0                 call    sub_4253B0   ; 查表做變換,演算法見下
.text:004254A5                 mov     edx, [esi]
.text:004254A7                 push    esi
.text:004254A8                 xor     edxeax
.text:004254AA                 push    ebx
.text:004254AB                 mov     [esi], edx
.text:004254AD                 call    sub_425460      ; 高32位和低32位值調換位置
.text:004254B2                 add     edi, 4
.text:004254B5                 add     esp, 0Ch
.text:004254B8                 cmp     edi, offset aClinecapmenuit ; "CLineCapMenuItem"
.text:004254BE                 jb      short loc_425495 ; 終了位置
.text:004254C0                 push    esi
.text:004254C1                 push    ebx
.text:004254C2                 call    sub_425460
.text:004254C7                 add     esp, 8
.text:004254CA                 xor     eaxeax
.text:004254CC                 pop     edi
.text:004254CD                 pop     esi
.text:004254CE                 pop     ebp
.text:004254CF                 pop     ebx
.text:004254D0 
.text:004254D0 unknown_libname_44:
.text:004254D0                 retn
.text:004254D0 sub_425480      endp
.text:004254D0 


變換:
函式DWORD sub_4253B0(DWORD)
輸入一個DWORD值,進行查表變換,表值如下,因為是單輸入單輸出函式還算簡單

0056ACEC  04 02 00 03 00 02 01 09 07 04 00 01 00 06 01 02  .....
0056ACFC  07 07 5F 5F 01 03 05 09 07 03 00 01 08 09 08 5F  __..._
0056AD0C  04 02 00 03 02 04 01 09 07 08 00 05 00 03 03 08  ....
0056AD1C  08 07 5F 5F 01 03 05 09 07 03 00 01 08 09 08 5F  __..._
0056AD2C  04 0A 09 02 0D 08 00 0E 06 0B 01 0C 07 0F 05 03  .... .
0056AD3C  0E 0B 04 0C 06 0D 0F 0A 02 03 08 01 00 07 05 09   .....
0056AD4C  05 08 01 0D 0A 03 04 02 0E 0F 0C 07 06 00 09 0B  .....
0056AD5C  07 0D 0A 01 00 08 09 0F 0E 04 06 0C 0B 02 05 03  .....
0056AD6C  06 0C 07 01 05 0F 0D 08 04 0A 09 0E 00 03 0B 02  .....
0056AD7C  04 0B 0A 00 07 02 01 0D 03 06 08 05 09 0C 0F 0E   .....
0056AD8C  0D 0B 04 01 03 0F 05 09 00 0A 0E 07 06 08 02 0C  . ....
0056AD9C  01 0F 0D 00 05 07 0A 04 09 02 03 0E 06 0B 08 0C  .... .
0056ADAC  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
0056ADBC  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
0056ADCC  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
0056ADDC  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
0056ADEC  00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00  .............
0056ADFC  04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00  ............
0056AE0C  07 00 00 00 06 00 00 00 05 00 00 00 04 00 00 00  ............
0056AE1C  03 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00  .............
0056AE2C  43 4C 69 6E 65 43 61 70 4D 65 6E 75 49 74 65 6D  CLineCapMenuItem


.text:004253B0 sub_4253B0      proc near               ; CODE XREF: sub_425480+20p
.text:004253B0 
.text:004253B0 arg_0           = dword ptr  4
.text:004253B0 
.text:004253B0                 mov     eax, [esp+arg_0]
.text:004253B4                 xor     edxedx
.text:004253B6                 mov     ecxeax
.text:004253B8                 push    ebx
.text:004253B9                 shr     ecx, 18h        ; 高8位
.text:004253BC                 and     ecx, 0Fh        ; 24 --- 28位
.text:004253BF                 xor     ebxebx
.text:004253C1                 mov     dl, byte_56AD8C[ecx] ;  查表
.text:004253C7                 mov     ecxedx
.text:004253C9                 mov     edxeax
.text:004253CB                 shr     edx, 1Ch        ; 29 --- 32位
.text:004253CE                 mov     bl, byte_56AD9C[edx]
.text:004253D4                 mov     edxeax
.text:004253D6                 shl     ebx, 4
.text:004253D9                 shr     edx, 14h
.text:004253DC                 or      ecxebx
.text:004253DE                 and     edx, 0Fh
.text:004253E1                 xor     ebxebx
.text:004253E3                 mov     bl, byte_56AD7C[edx]
.text:004253E9                 mov     edxeax
.text:004253EB                 shl     ecx, 4
.text:004253EE                 shr     edx, 10h
.text:004253F1                 or      ecxebx
.text:004253F3                 and     edx, 0Fh
.text:004253F6                 xor     ebxebx
.text:004253F8                 mov     bl, byte_56AD6C[edx]
.text:004253FE                 mov     edxeax
.text:00425400                 shl     ecx, 4
.text:00425403                 shr     edx, 0Ch
.text:00425406                 or      ecxebx
.text:00425408                 and     edx, 0Fh
.text:0042540B                 xor     ebxebx
.text:0042540D                 mov     bl, byte_56AD5C[edx]
.text:00425413                 mov     edxeax
.text:00425415                 shl     ecx, 4
.text:00425418                 shr     edx, 8
.text:0042541B                 or      ecxebx
.text:0042541D                 and     edx, 0Fh
.text:00425420                 xor     ebxebx
.text:00425422                 mov     bl, byte_56AD4C[edx]
.text:00425428                 mov     edxeax
.text:0042542A                 shl     ecx, 4
.text:0042542D                 shr     edx, 4
.text:00425430                 or      ecxebx
.text:00425432                 and     edx, 0Fh
.text:00425435                 xor     ebxebx
.text:00425437                 and     eax, 0Fh
.text:0042543A                 mov     bl, byte_56AD3C[edx]
.text:00425440                 xor     edxedx
.text:00425442                 mov     dl, byte_56AD2C[eax]
.text:00425448                 shl     ecx, 4
.text:0042544B                 or      ecxebx
.text:0042544D                 pop     ebx
.text:0042544E                 shl     ecx, 4
.text:00425451                 or      ecxedx
.text:00425453                 mov     eaxecx
.text:00425455                 shr     eax, 15h
.text:00425458                 shl     ecx, 0Bh
.text:0042545B                 or      eaxecx
.text:0042545D                 retn
.text:0042545D sub_4253B0      endp


發現這裡缺乏將硬碟序列號轉換為顯示在註冊對話方塊中的軟體號software Serial中的函式,在PE Explore中檢視找註冊對話方塊視窗ID號為1024 

即 418h,於是在IDA中查詢立即數0x418h即可找到這裡:0041AA18 

透過查詢註冊視窗ID 1024 即 418h,即可找到這裡:0041AA18 

.text:0041AA0F                 push    418h
.text:0041AA14                 mov     [esp+20h+var_10], esi
.text:0041AA18                 call    ??0CDialog@@QAE@IPAVCWnd@@@Z ; CDialog::CDialog(uint,CWnd *)
檢視其Cross Reference找到這裡

...
.text:00428D9D                 call    ds:GetVolumeInformationA
.text:00428DA3                 mov     ecx, [esp+1Ch]
.text:00428DA7                 lea     edx, [esp+14h]
.text:00428DAB                 push    offset unk_56ACEC
.text:00428DB0                 lea     eax, [esp+14h]
.text:00428DB4                 push    edx
.text:00428DB5                 push    eax
.text:00428DB6                 mov     [esp+1Ch], ecx
.text:00428DBA                 mov     dword ptr [esp+20h], 19320h
.text:00428DC2                 call    sub_425480
.text:00428DC7                 mov     eax, [esp+1Ch]
.text:00428DCB                 add     esp, 0Ch
.text:00428DCE                 test    eaxeax
.text:00428DD0                 pop     esi
.text:00428DD1                 jbe     short loc_428E20
.text:00428DD3 
.text:00428DD3 loc_428DD3:                             ; CODE XREF: .text:00428E1Ej
.text:00428DD3                 xor     edxedx
.text:00428DD5                 mov     ecx, 23h
.text:00428DDA                 div     ecx
.text:00428DDC                 cmp     edx, 0Ah
.text:00428DDF                 jl      short loc_428DEF
.text:00428DE1                 add     dl, 37h
.text:00428DE4                 mov     [esp+14h], dl
.text:00428DE8                 mov     edx, [esp+14h]
.text:00428DEC                 push    edx
.text:00428DED                 jmp     short loc_428DFB
.text:00428DEF ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00428DEF 
.text:00428DEF loc_428DEF:                             ; CODE XREF: .text:00428DDFj
.text:00428DEF                 add     dl, 30h
.text:00428DF2                 mov     [esp+4], dl
.text:00428DF6                 mov     eax, [esp+4]
.text:00428DFA                 push    eax
.text:00428DFB 
.text:00428DFB loc_428DFB:                             ; CODE XREF: .text:00428DEDj
.text:00428DFB                 lea     ecx, [esp+4]
.text:00428DFF                 call    sub_4EE98B
.text:00428E04                 mov     ecx, [esp+0Ch]
.text:00428E08                 mov     eax, 0D41D41D5h
.text:00428E0D                 mul     ecx
.text:00428E0F                 sub     ecxedx
.text:00428E11                 shr     ecx, 1
.text:00428E13                 add     ecxedx
.text:00428E15                 shr     ecx, 5
.text:00428E18                 mov     eaxecx
.text:00428E1A                 mov     [esp+0Ch], eax
.text:00428E1E                 jnz     short loc_428DD3 ; 前半截機器碼
.text:00428E20 
.text:00428E20 loc_428E20:                             ; CODE XREF: .text:00428DD1j
.text:00428E20                 push    offset asc_56939C ; "-"
.text:00428E25                 lea     ecx, [esp+4]
.text:00428E29                 call    sub_4EE964      ; 前半截機器碼 + "-"
.text:00428E2E                 mov     ecx, off_56B748
.text:00428E34                 mov     [esp+8], ecx
.text:00428E38                 mov     eax, [esp+10h]
.text:00428E3C                 mov     byte ptr [esp+2ECh], 1
.text:00428E44                 test    eaxeax
.text:00428E46                 jbe     short loc_428E8D
.text:00428E48 
.text:00428E48 loc_428E48:                             ; CODE XREF: .text:00428E8Bj
.text:00428E48                 xor     edxedx
.text:00428E4A                 mov     ecx, 22h
.text:00428E4F                 div     ecx
.text:00428E51                 cmp     edx, 0Ah
.text:00428E54                 jl      short loc_428E64
.text:00428E56                 add     dl, 37h
.text:00428E59                 mov     [esp+4], dl
.text:00428E5D                 mov     edx, [esp+4]
.text:00428E61                 push    edx
.text:00428E62                 jmp     short loc_428E70
.text:00428E64 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00428E64 
.text:00428E64 loc_428E64:                             ; CODE XREF: .text:00428E54j
.text:00428E64                 add     dl, 30h
.text:00428E67                 mov     [esp+14h], dl
.text:00428E6B                 mov     eax, [esp+14h]
.text:00428E6F                 push    eax
.text:00428E70 
.text:00428E70 loc_428E70:                             ; CODE XREF: .text:00428E62j
.text:00428E70                 lea     ecx, [esp+0Ch]
.text:00428E74                 call    sub_4EE98B
.text:00428E79                 mov     eax, 0F0F0F0F1h
.text:00428E7E                 mul     dword ptr [esp+10h]
.text:00428E82                 mov     eaxedx
.text:00428E84                 shr     eax, 5
.text:00428E87                 mov     [esp+10h], eax
.text:00428E8B                 jnz     short loc_428E48 ; 後半截機器碼
.text:00428E8D 
.text:00428E8D loc_428E8D:                             ; CODE XREF: .text:00428E46j
.text:00428E8D                 lea     ecx, [esp+8]
.text:00428E91                 push    ecx
.text:00428E92                 lea     ecx, [esp+4]    ; 合成最終機器碼
.text:00428E96                 call    ??YCString@@QAEABV0@ABV0@@Z ; CString::operator+=(CString const &)
.text:00428E9B                 push    0
.text:00428E9D                 lea     ecx, [esp+28h]
.text:00428EA1                 call    sub_41A9F0      ; 顯示註冊視窗


這裡的變換和前面的變換類似,只是記憶體表不同,逆向起來有些繁,於是直接根據前面比較註冊碼過程,序號產生器直接呼叫

GetVolumeInformationA 來取硬碟序列號。

這個軟體好像沒有用註冊標誌位,每一次都調是用GetVolumeInformationA 獲取硬碟序列號來驗證,所以可以在IDA中檢視

GetVolumeInformationA 的Cross Reference來找到比較之處
.text:004289F9                 fcomp   qword ptr [esp+1BCh+var_188]  <======== ******* 關鍵比較, 註冊碼中"-"前部分變換結果 與 

使用者c盤序列號變換結果進行比較。
.text:004289FD                 fnstsw  ax
.text:004289FF                 test    ah, 40h
.text:00428A02                 jz      short loc_428A0B  ; 註冊碼錯誤則跳,爆破可以類似修改這裡


軟體演算法:
註冊碼形如xxxxxx-xxxxx, 註冊碼比較計算只用了"-"前部分,所以"-"後隨便輸
硬碟序列號的變換及基本上是查表

使用者註冊碼的變換是演算法類似從右至左
X(n) = 35*X(n-1) + Y
Y為此次值


附序號產生器:(寫序號產生器.花了我半天時間,看來還是爆破容易阿,:))
vc6.0下編譯透過,使用時呼叫GetRegisterCode()即可,


// 從0056AD0C開始的記憶體表,由HEX WorkShop生成
unsigned char rawData[308] =
{
    0x04, 0x02, 0x00, 0x03, 0x02, 0x04, 0x01, 0x09, 0x07, 0x08, 0x00, 0x05, 0x00, 0x03, 0x03, 0x08, 
    0x08, 0x07, 0x5F, 0x5F, 0x01, 0x03, 0x05, 0x09, 0x07, 0x03, 0x00, 0x01, 0x08, 0x09, 0x08, 0x5F, 
    0x04, 0x0A, 0x09, 0x02, 0x0D, 0x08, 0x00, 0x0E, 0x06, 0x0B, 0x01, 0x0C, 0x07, 0x0F, 0x05, 0x03, 
    0x0E, 0x0B, 0x04, 0x0C, 0x06, 0x0D, 0x0F, 0x0A, 0x02, 0x03, 0x08, 0x01, 0x00, 0x07, 0x05, 0x09, 
    0x05, 0x08, 0x01, 0x0D, 0x0A, 0x03, 0x04, 0x02, 0x0E, 0x0F, 0x0C, 0x07, 0x06, 0x00, 0x09, 0x0B, 
    0x07, 0x0D, 0x0A, 0x01, 0x00, 0x08, 0x09, 0x0F, 0x0E, 0x04, 0x06, 0x0C, 0x0B, 0x02, 0x05, 0x03, 
    0x06, 0x0C, 0x07, 0x01, 0x05, 0x0F, 0x0D, 0x08, 0x04, 0x0A, 0x09, 0x0E, 0x00, 0x03, 0x0B, 0x02, 
    0x04, 0x0B, 0x0A, 0x00, 0x07, 0x02, 0x01, 0x0D, 0x03, 0x06, 0x08, 0x05, 0x09, 0x0C, 0x0F, 0x0E, 
    0x0D, 0x0B, 0x04, 0x01, 0x03, 0x0F, 0x05, 0x09, 0x00, 0x0A, 0x0E, 0x07, 0x06, 0x08, 0x02, 0x0C, 
    0x01, 0x0F, 0x0D, 0x00, 0x05, 0x07, 0x0A, 0x04, 0x09, 0x02, 0x03, 0x0E, 0x06, 0x0B, 0x08, 0x0C, 
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
    0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
    0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
    0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
    0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 
    0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x43, 0x4C, 0x69, 0x6E, 0x65, 0x43, 0x61, 0x70, 0x4D, 0x65, 0x6E, 0x75, 0x49, 0x74, 0x65, 0x6D, 
    0x00, 0x00, 0x00, 0x00, 
} ;

char bb[50];  //全域性變數,儲存軟體找到的註冊碼

// 因為軟體碼(software serial)變換, 只是記憶體表不太一樣同,逆向起來有些繁,
// 於是直接根據前面比較註冊碼過程,序號產生器直接呼叫,不過必須在本機上執行 :)
DWORD APIENTRY GetDiskSerialNo(void)
{
    LPCTSTR lpRootPathName="c:\"; //取C盤的序列號
    LPTSTR lpVolumeNameBuffer=new char[12];//磁碟卷標
    DWORD nVolumeNameSize=12;

    DWORD VolumeSerialNumber;//磁碟序列號
    DWORD MaximumComponentLength;
    LPTSTR lpFileSystemNameBuffer=new char[10];
    DWORD nFileSystemNameSize=10;
    DWORD FileSystemFlags;
      GetVolumeInformation(lpRootPathName,
    lpVolumeNameBuffer, nVolumeNameSize,
    &VolumeSerialNumber, &MaximumComponentLength,
    &FileSystemFlags,
    lpFileSystemNameBuffer, nFileSystemNameSize);
    return  VolumeSerialNumber;
}


DWORD Encrypt1(DWORD dwSource)
{
    DWORD dwResult=0;
    DWORD dwTemp = 0;
    // 查表變換,直接從IDA中複製出來,稍微修改一下就可以了,偷點懶
  _asm
  {
    MOV     EAX, dwSource
    XOR     EDXEDX
    MOV     ECXEAX
    PUSH    EBX
    SHR     ECX, 18h
    AND     ECX, 0Fh
    XOR     EBXEBX
    MOV     DLBYTE PTR rawData[ECX+80h] ; DS:[ECX+56AD8C]
    MOV     ECXEDX
    MOV     EDXEAX
    SHR     EDX, 1Ch
    MOV     BLBYTE PTR rawData[EDX+90h]
    MOV     EDXEAX
    SHL     EBX, 4
    SHR     EDX, 14h
    OR      ECXEBX
    AND     EDX, 0Fh
    XOR     EBXEBX
    MOV     BLBYTE PTR rawData[EDX+70h]
    MOV     EDXEAX
    SHL     ECX, 4
    SHR     EDX, 10h
    OR      ECXEBX
    AND     EDX, 0Fh
    XOR     EBXEBX
    MOV     BLBYTE PTR rawData[EDX+60h]
    MOV     EDXEAX
    SHL     ECX, 4
    SHR     EDX, 0Ch
    OR      ECXEBX
    AND     EDX, 0Fh
    XOR     EBXEBX
    MOV     BLBYTE PTR rawData[EDX+50h]
    MOV     EDXEAX
    SHL     ECX, 4
    SHR     EDX, 8
    OR      ECXEBX
    AND     EDX, 0Fh
    XOR     EBXEBX
    MOV     BLBYTE PTR rawData[EDX+40h]
    MOV     EDXEAX
    SHL     ECX, 4
    SHR     EDX, 4
    OR      ECXEBX
    AND     EDX, 0Fh
    XOR     EBXEBX
    AND     EAX, 0Fh
    MOV     BLBYTE PTR rawData[EDX+30h]
    XOR     EDXEDX
    MOV     DLBYTE PTR rawData[EAX+20h]
    SHL     ECX, 4
    OR      ECXEBX
    POP     EBX
    SHL     ECX, 4
    OR      ECXEDX
    MOV     EAXECX
    SHR     EAX, 15h
    SHL     ECX, 0Bh
    OR      EAXECX
    MOV dwResult, EAX
  }

    return dwResult;

}




//使用迭代取註冊碼
//
DWORD Encrypt2(DWORD Xn)
{
    DWORD dwYushu = 0;
    DWORD Xn1 = 0;
    int yushu = 0; // 餘數
    char c1[2];
    Xn1 = Xn/35;   
    yushu = Xn - Xn1*35;

    c1[0]=0; 
    c1[1]=0;
        
    if(Xn >0) 
    {
        if (yushu==0)   
            c1[0]='0';  
        else if(yushu<=9)
            c1[0]=yushu+48;
        else
            c1[0]=yushu+55;
        
        lstrcat(bb,c1);
        
        return Encrypt3(Xn1);
    }
    else
    {
        return 0;   
    }   

}


//主函式
void GetRegisterCode()
{
    DWORD dwEn1 = GetDiskSerialNo(); //獲取硬碟序列號
    DWORD dwEn2 = 0x19320;   // 種子數
    DWORD dwTemp = 0;
    DWORD dwTemp2 = 0;
    int j = 0;
    for(int i = 0;i<0x20;i++)
    {
        j =rawData[4*i+0x0A0];
        int k =4*j;

        // 好久沒寫過程式了,不知道怎麼從unsigned char陣列中取出DWORD值,只好藉助彙編了,呵呵
        __asm mov EDX, k
        __asm mov EAXDWORD PTR rawData[EDX]
        __asm mov dwTemp, EAX

        dwTemp = dwEn1 + dwTemp;
        dwTemp2 = dwEn1;
        dwTemp = Encrypt1(dwTemp);
        dwEn1 = dwEn2^dwTemp;
        dwEn2 = dwTemp2;
    }

    dwTemp = dwEn2;
    dwEn2 = dwEn1;
    dwEn1 = dwTemp;

    // dwEn1儲存是硬碟序列號變換後的結果
    // 註冊碼透過往這裡湊
    ::ZeroMemory(bb,sizeof(bb));  
    Encrypt2(dwEn1);  // 獲取註冊碼
    char aa[100];
    ::ZeroMemory(aa,sizeof(aa));    
    wsprintf(aa,"註冊碼為:%s - 任意字串",bb);
    MessageBox(0,aa,"Powerful Card Maker 3.2序號產生器",0);

}

夠碌模恢浪登宄嗣揮小
最後祝看雪的兄弟們國慶快樂,:)

相關文章