1. 程式人生 > >160個crackme(6)

160個crackme(6)

這是160個crackme的第六道,比較簡單;

一·逆向的軟體及目的:

   

當我們點選About-Help的時候,就知道了這道crackme是讓我們輸入正確的Nome(我覺得作者是將name打錯了…)和Codice,然後OK鍵和Cancella鍵會消失,顯示出後面的圖示:

二·開始工作:

分析:首先我們發現這個歐卡鍵是被灰度的,不可用,所以猜測應該是先輸入正確的註冊碼後,Cancella鍵消失,然後ok鍵可以用,然後再輸入正確的註冊碼後Ok鍵消失,圖示顯示出來。

正式開始逆向:

  1. PEID查殼:

沒有殼,是Delphi寫的。

  1. 因為IDE對Delphi編寫的軟體我覺得沒有DeDe分析的好,所以我喜歡用DeDe檢視一下事件:

一共有10個事件,根據名字我們發現前四個事件應該是關鍵的,我們在OD中將這幾個事件的開始地址00442C78,00442D64,00442E04,00442EA8下斷點並寫上註釋。

NomeChange事件:當我還在輸入的時候就斷在了00442E04的位置,然而我們並沒有點選任何按鈕,說明軟體在輸入的時候就開始判斷對不對了。然後我們F8單步繼續走(注意觀察堆疊和暫存器的變化),當我們走到00442E57的時候,我們發現將我們輸入的name放到暫存器EAX裡了,而下面剛好有一個call,這個call很有可能是驗證name的函式,所以F7單步進入,然後看到這裡:

說明輸入的name必須大於5個字元,然後下面就是關鍵演算法:

00442A93到00442AAC就是判斷name的演算法,翻譯成python就是:

eax=1
name=input(“name”)
a=name
b=len(a)
ebx=b
for i in range(0,b-1):
     ecx=ord(a[i])
     esi=ord(a[i+1])
     ecx=ecx*esi
     ecx=ecx*eax
     ebx=ebx+ecx
     eax=eax+1
print(hex(ebx))

 

然後通過name用上面演算法算出來的一個值減去通過codice用另一個演算法算出來的值,如果等於0x29A,那麼cancella鍵就會消失

CodeChange事件:當我們輸入codie時,程式斷下來了,然後F8繼續執行,同樣觀察堆疊和暫存器,在00442EE3的地址處,codice放入EAX中,所以進入下面的call,剛好是codice的演算法。

判斷codice的演算法:

可以看出輸入的codice必須是數字,然轉換為python程式碼就是:

for i in codie:
     ecx=10*eax+int(i)
     eax=ecx
print(hex(eax))

其實就是將codie字串轉換為unicode編碼

codeclik事件:點選cancella鍵時,在00442EA8斷了下來,然後00442EE7位置的call進入,這裡就是讓cancella鍵消失的關鍵函數了:

取name的第五位a[4],然後除以0x7取餘數後加0x2的值的階乘儲存下來,然後減去name計算出來的值如果等於0x7A69,就消去cancella鍵。

所以消去cancella鍵的註冊機可以這樣寫:

name=input("輸入name:")
eax=ord(name[4])%0x7+0x2    #對應0x0442B35
ebx=1
for i in range(1,eax+1):          #call 0x042A20
     ebx=ebx*i
eax=0
for i in name:
     eax=eax+ord(i)*ebx         #對應0x0442B54
ebx=eax-0x7a69                  #反推密碼 對應0x0442B65
key=ebx
print(u"cancella鍵消失的密碼:%d"%key)

 

okclik事件:用上面同樣的方法,找到時ok鍵消失的演算法的位置00442BF9:

 

密碼從後往前獲取密碼一位的平方乘以(下標+1),除以0x19,餘數加0x41,替換掉原來的密碼位置,然後和name比較一不一樣,如果一樣就將ok鍵消失掉。

所以用python寫註冊機可以這樣寫:

先輸入codice然後再根據codice反算出name:

codice=input("輸入codice:")
a=codice
ecx=len(a)
eax=0
x=0
key=" "
for i in range(0,ecx):
     x=ord(a[i])*ord(a[i])         #對應0x0442C0E
     if(x>0xffff):                    #對應0x0442C10
          x=0xffff
     eax=x*(i+1)%0x19+0x41   #對應0x0442C1B和0x0442C1D
     if(eax>0xff):
          eax=0xff
     key=key+chr(eax)                  #對應0x0442C21
print("OK鍵消失的name:%s"%key)

 

總結:將使ok鍵消失的程式碼和cancella消失的程式碼分開寫,也就是讓cancella的程式碼是通過name算出codice,讓ok鍵消失的程式碼是通過codice去算name,這樣要簡單一點!