1. 程式人生 > >160個CrackMe(4)

160個CrackMe(4)

這次寫的是160個CrackMe系列裡的Andrénalin系列的第四個,前面三個還是比較容易的,總的說來這個系列的演算法都是將使用者輸入的字串經過一系列的運算後與一個註冊碼比較,如果一樣則註冊成功,所以這個系列直接爆破的話就很容易,直接找到關鍵字串—註冊成功的語句,然後再合適的位置將判斷跳轉的語句(je,jne等)nop掉就可以了。

一·目標軟體:Andrénalin.4.exe

執行介面:(未註冊)

註冊後:

二·分析:

首先,我們發現這個軟體沒有確定鍵,只有0123456789*#和一個刪除鍵,那麼這個軟體很有可能輸入之後靠Timer控制元件來自動進行判斷的(不排除隱藏按鍵的可能)。

查殼:

VB編寫的,沒有加殼。。。

檢視事件:

果然有Timer,還不止一個,看來判斷的地方不止一個。

OD中跟蹤分析:

  1. 先檢視字串,看有沒有什麼可以利用的:

居然有這麼多的已註冊(REGISTRIERT)和一堆看似一樣卻有微小差別的字串,我們隨便進入到一個字串所在的位置研究一下:

有一個VB裡面的標準比較函式:vbVarTstEq ,那麼這個字串很有可能就是最終用來比較的字串了(當然不一定是這個字串,因為還有很多個與這個字串相像的字串)

  1. 跟蹤演算法:

先不要下斷點,隨便輸入一個數據(我輸的147258)後再在Timer1_404650的位置下斷點,因為這是第一個Timer的位置,也剛好在那個字串的上方,這裡開始跟蹤演算法比較容易跟蹤

我們發現,在00404982的位置的call函式取了字串裡的第一位字元,然後再00404994的位置上通過rtcAnsiValueBstr函式將字元轉化為Unicode,相當與python裡ord(a[i]);

然後通過0040499A到004049C8地址的指令將16進位制的Unicode轉換為10進位制的,然後加上一個常數(暫時不知道這個數怎麼來的)得到的值再轉換為16進位制,比如字元‘8’:

‘8’à 0x38 à 56 à 56+常數=Yà Y轉換為16進製得到一個數

所以總的演算法就是這樣把每一個字元轉換為一個16進位制的字串,而且在字串前面還加了一個‘0’;

我們分析了那些相似的字串,只有這一組全部是16進位制數:

0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C 

所以這組應該才是對的比較碼

尋找常數產生的演算法:

我們分析發現,這個常數是在取字串裡每一位的上面產生的,就是這個call esi裡,經過多次輸入和單步跟蹤發現,這個常數取的是字串的前兩位,比如輸入的是‘12345’,那麼常數就是12,如果輸入的是‘*#1234’,那麼常數就是0;

三·寫註冊機:

知道了驗證碼後,就可以倒推出key了;

先通過驗證碼的開頭兩個字元(除去‘0’)0x81,算出常數是74,那麼key的開頭兩個數字就是74,算出常數後就可以倒退出key了;

算常數的程式碼:

for i in range(0,10):
     a=ord(str(i))
     for j in range(0,10):
          if(a+i*10+j==0x81):
               num=i*10+j
               print(num)
               break

算key的程式碼:

key="817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C"
Key=""
id="0123456789*#"
keylen=len(key)
for ecx in range(0,keylen-1):
     eax=key[ecx]+key[ecx+1]
     ebx=int(eax,16)
     for i in id:
          a=ord(i)
          if(a+num==ebx):
               Key=Key+i
               eax=""
               break
print("Key: %s"%Key)