DataFit 8.0

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

破解DataFit 8.0

    這是個科學與工程工具(science and engineering,不知道該
怎麼譯:-)。用於對資料進行統計分析,曲線擬合,繪圖等。在RCE
Message Board上見到有人提起,以為是個VB PCode程式,雖然很
討厭PCode,可是不學不行呀,於是下載回來練手,結果是Native
Code。既來之,則破之,這個倒比較簡單。

1.大致看了看,好象沒什麼別的東西,只要研究主程式就行。在
  SmartCheck下載入,執行起來後,有個"New Project"對話方塊,這
  個地方最好選Cancel,否則SmartCheck好象動不了了,可以看到
  一大堆對Rnd的呼叫。我以為是掉到陷阱裡了,不過從後面看未必,
  只是太慢而已。

  從SmartCheck中可以看見,實際上是keyfile保護,會訪問
  DataFit.lic和Eval.lic。

  另外,我習慣性地把text section改為E0000020,結果不能執行。
  在SoftIce下沒反應,直接執行報找不到Q.dll,看來還有自校驗。
  先不管它。


2.在SmartCheck下執行,開啟Help|License,可以輸一個license
  number,與使用者名稱無關?輸入12345678。

  輸完後沒有反應,也許是重啟校驗,於是退出程式。在主視窗的
  Unload事件處理中,找到對license number的處理(SmartCheck
  不能把程式碼拷出來,這點不如W32Dasm:-),從9C2148開始:

  1)license number按奇、偶數位重新組合:
    "12345678" -> "24681357"

  2)將最後1位放到最前面,迴圈13次。我的number給得太小,有的數
    字用了兩次。
  
    這中間呼叫了LCase,說明number實際上是字母或包含字母。
 
  3)從9C239B起,對license number進行換碼(一個大的select case),
    26個小寫字母亂序後重新得到一個字串。可見license number
    全為字母。

  4)從9C2876起,對number再次換碼,把26個小寫字母看作一個閉合
    的環,每個字母左移12位,如'l'->'a','m'->'b'。

  以下好象就沒什麼明顯的程式碼了,無數的Rnd,Double,Chr呼叫。我
  以為這些程式碼是"逗你玩",於是掉頭去看前面,也有很多類似的代
  碼,而且沒有看到上面變換的結果被使用。


3.也許應該試試湊個keyfile。不過在IDA Pro中看看再說。在上面的
  程式碼之後,卻可以看到呼叫__vbaStrCmp進行明碼比較。不知為什麼
  SmartCheck沒有報出對__vbaStrCmp的呼叫。用於與明碼比較的字元
  串是上面處理過的字串再次按奇偶數位組合的結果。

  比較指令很多,實際上是個迴圈,在5CD150開始的函式內。比較迴圈
  執行300次,難怪在SmartCheck中那麼多重複的程式碼。問題是用於比
  較的明碼是用Rnd生成的?

  先不管它,用斷到的第1個明碼"stcrdvgiexsgxqyh"寫一個逆反過程
  試試:

  CString strInput="stcrdvgiexsgxqyh";
      
  //將奇,偶數位重新放置

  CString strKey;
  
  for(int i=0;i<strInput.GetLength()/2;i++)
  {
     strKey += strInput[i + strInput.GetLength()/2];
     strKey += strInput[i];
  }

  //逐字元移位(把26個字母看做封閉的環:-)

  int nLen=strKey.GetLength();

  for(i=0;i<nLen;i++)
  {
     strKey.SetAt(i,(strKey[i] + 0xC >'z')?
  strKey[i] + 0xC - 0x1A : strKey[i] + 0xC);
  }

  //換碼

  char szPlain[]="abcdefghijklmnopqrstuvwxyz";
  char szCipher[]="lesiaxkcpgnmvrzfbhjuqdoywt";

  for(i=0;i<nLen;i++)
  {
     for(int j=0;j<26;j++)
     {
  if(strKey[i]==szCipher[j])
  {
           strKey.SetAt(i,szPlain[j]);
     break;
  }
     }
  }

  //把第1位放到最後面,迴圈13次

  for(i=0;i<13;i++)
  {
     strKey=strKey.Right(nLen - 1) + strKey.Left(1);
  }

  //再次將奇,偶數位重新放置

  CString strOutput;

  for(i=0;i<strKey.GetLength()/2;i++)
  {
     strOutput += strKey[i + strKey.GetLength()/2];
     strOutput += strKey[i];
  }
  
  TRACE("%s
",strOutput);

  把結果"wcczvtsuibhsrpgb"輸入,OK:-)。再看看目錄下面,並沒有
  DataFit.lic檔案。上述license number被寫入了登錄檔。看來沒有
  keyfile也行:-)。


4.下面再來看看license number怎麼會由隨機數生成?以下為相關的彙編
  程式碼。

.text:005CD1F2                 mov     ebx, 61h        ; 'a'
.text:005CD1F7                 mov     [ebp+var_50], 0FFFFFFFFh
.text:005CD1FE                 mov     edi, 2
.text:005CD203                 mov     [ebp+var_number], edi
.text:005CD206                 lea     eax, [ebp+var_number]
.text:005CD209                 push    eax
.text:005CD20A                 call    ds:rtcRandomNext ; 這裡把var_50置為-1,push的
.text:005CD20A                                         ; 卻是另一個指標(->2)?
.text:005CD20A                                         ; 
.text:005CD20A                                         ; 在SmartCheck中為Rnd(-1),
.text:005CD20A                                         ; 這個是對的
.text:005CD20A                                         ; 
.text:005CD210                 fstp    st
.text:005CD212                 lea     ecx, [ebp+var_number]
.text:005CD215                 mov     esi, ds:__vbaFreeVar
.text:005CD21B                 call    esi ; __vbaFreeVar
.text:005CD21D                 mov     word ptr [ebp+var_50], 19h
.text:005CD223                 mov     [ebp+var_number], edi
.text:005CD226                 lea     ecx, [ebp+var_number]
.text:005CD229                 push    ecx
.text:005CD22A                 call    ds:rtcRandomize ; Rnd(25)
.text:005CD230                 lea     ecx, [ebp+var_number]
.text:005CD233                 call    esi ; __vbaFreeVar
.text:005CD235                 mov     [ebp+var_38], 0
.text:005CD23C                 mov     [ebp+var_nCount], 1
.text:005CD243 
.text:005CD243 loc_5CD243:                             ; CODE XREF: sub_5CD150+21D
.text:005CD243                 mov     eax, 12Ch       ; 300次
.text:005CD248                 cmp     word ptr [ebp+var_nCount], ax
.text:005CD24C                 jg      loc_5CD379
.text:005CD252                 mov     edx, offset unk_45F354
.text:005CD257                 lea     ecx, [ebp+var_pCurrLicNum]
.text:005CD25A                 call    ds:__vbaStrCopy
.text:005CD260                 mov     esi, 1
.text:005CD265 
.text:005CD265 loc_5CD265:                             ; CODE XREF: sub_5CD150+1F2
.text:005CD265                 mov     eax, 10h        ; 1個license number為16位
.text:005CD26A                 cmp     si, ax
.text:005CD26D                 jg      l_cmp
.text:005CD273                 mov     [ebp+var_50], 80020004h
.text:005CD27A                 mov     [ebp+var_number], 0Ah
.text:005CD281                 lea     edx, [ebp+var_number]
.text:005CD284                 push    edx
.text:005CD285                 call    ds:rtcRandomNext
.text:005CD28B                 fstp    [ebp+var_rnd]
.text:005CD291                 mov     eax, 7Ah        ; 'z'
.text:005CD296                 sub     ax, bx          ; bx=0x61 ->'a'
.text:005CD299                 jo      l_exception
.text:005CD29F                 add     ax, 1
.text:005CD2A3                 jo      l_exception
.text:005CD2A9                 movsx   eax, ax
.text:005CD2AC                 mov     [ebp+var_int], eax
.text:005CD2B2                 fild    [ebp+var_int]   ; 裝入整數到st(0)
.text:005CD2B8                 fstp    [ebp+var_194]   ; var_194 <-st(0)
.text:005CD2BE                 fld     [ebp+var_194]   ; 裝入實數到st(0)
.text:005CD2BE                                         ; 這幾句把0x7A轉化為實數
.text:005CD2BE                                         ; 0x7A->字元'z'
.text:005CD2C4                 fmul    [ebp+var_rnd]
.text:005CD2CA                 movsx   ecx, bx
.text:005CD2CD                 mov     [ebp+var_198], ecx
.text:005CD2D3                 fild    [ebp+var_198]
.text:005CD2D9                 fstp    [ebp+var_19C]
.text:005CD2DF                 fadd    [ebp+var_19C]   ; 加,不用再看下去了:-)
.text:005CD2E5                 fnstsw  ax
.text:005CD2E7                 test    al, 0Dh
.text:005CD2E9                 jnz     loc_5CD74E
.text:005CD2EF                 call    ds:__vbaR8IntI2
.text:005CD2F5                 mov     edi, eax
.text:005CD2F7                 lea     ecx, [ebp+var_number]
.text:005CD2FA                 call    ds:__vbaFreeVar
.text:005CD300                 mov     edx, [ebp+var_pCurrLicNum]
.text:005CD303                 push    edx
.text:005CD304                 movsx   eax, di
.text:005CD307                 push    eax
.text:005CD308                 call    ds:rtcBstrFromAnsi
.text:005CD30E                 mov     edx, eax
.text:005CD310                 lea     ecx, [ebp+var_48]
.text:005CD313                 mov     edi, ds:__vbaStrMove
.text:005CD319                 call    edi ; __vbaStrMove
.text:005CD31B                 push    eax
.text:005CD31C                 call    ds:__vbaStrCat
.text:005CD322                 mov     edx, eax
.text:005CD324                 lea     ecx, [ebp+var_pCurrLicNum]
.text:005CD327                 call    edi ; __vbaStrMove
.text:005CD329                 lea     ecx, [ebp+var_48]
.text:005CD32C                 call    ds:__vbaFreeStr
.text:005CD332                 mov     eax, 1
.text:005CD337                 add     ax, si
.text:005CD33A                 jo      l_exception
.text:005CD340                 mov     esi, eax
.text:005CD342                 jmp     loc_5CD265
.text:005CD347 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
.text:005CD347 
.text:005CD347 l_cmp:                                  ; CODE XREF: sub_5CD150+11D
.text:005CD347                 mov     ecx, [ebp+arg_pPtInputedLicNum]
.text:005CD34A                 mov     edx, [ecx]
.text:005CD34C                 push    edx
.text:005CD34D                 mov     eax, [ebp+var_pCurrLicNum]
.text:005CD350                 push    eax
.text:005CD351                 call    ds:__vbaStrCmp
.text:005CD357                 test    eax, eax
.text:005CD359                 jz      short loc_5CD372
.text:005CD35B                 mov     eax, 1
.text:005CD360                 add     ax, word ptr [ebp+var_nCount]
.text:005CD364                 jo      l_exception
.text:005CD36A                 mov     [ebp+var_nCount], eax
.text:005CD36D                 jmp     loc_5CD243

 沒有太大的意思。見MSDN對Randomize的解釋:若想得到重複的隨機數序列,
 在使用具有數值引數的 Randomize 之前直接呼叫具有負引數值的Rnd。這裡
 先用-1去調Rnd,得到固定的"隨機數"序列,用來在'a'-'z'間取值。可以
 照葫蘆畫瓢,做出300個license number,一網打盡:-)。

 Rnd (-1)
 Randomize (25)

 For i = 1 To 300   '300個license number
 
     CurrLicNum = ""
     
     For j = 1 To 16    '每個16字元
          
         CurrLicNum = CurrLicNum + Chr(&H61 + Int(26 * Rnd))
     
     Next j
 Next i

 這裡只是明文,還要逆回去。難道廠商只打算賣300份?或許這300個license
 number用完了,就要用keyfile了:-)

相關文章