5.1 序列化保護方式

gclome發表於2020-12-05

最近在看《加密與解密》第五章,會將自己的學習經歷記錄下來,

5.1 序列化保護方式

5.1.1 序列號保護機制

軟體驗證序列號,其實就是驗證使用者名稱和序列號之間的數學對映關係

(1)將使用者名稱等資訊作為自資訊,通過函式F變換之後得到註冊碼

公式為:序列號=F(使用者名稱)

由於這種方式的保護機制在使用者機器上再現了生成註冊碼的過程(即在使用者機器上執行了函式F),所以是以明文出現在記憶體中的。這是非常不安全的,因為無論F函式多麼複雜,解密者只需要把函式F的實現程式碼從軟體提取出來,就可編制一個通用的計算註冊碼程式了

(2)通過註冊碼驗證使用者名稱的正確性
軟體作者在給註冊使用者生成註冊碼的時候,使用的依然是下面這種變換
序列號=F(使用者名稱)

注:這裡的F是一個可逆變換
軟體在檢查註冊碼的時候,是利用F的逆變換對使用者輸入的註冊碼進行變換的。若變換的結果和使用者名稱相同,這說明是正確的註冊碼,

在這裡插入圖片描述(5-2)
用來生成註冊碼的函式F未直接出現在軟體程式碼中,而且正確註冊碼的明文也未出現在記憶體中

破解此類註冊碼檢查方式的途徑:
1、修改比較指令
2、通過找出其逆變換,即函式F,從而得到一個正確的註冊碼或者寫出序號產生器
3、給定一個使用者名稱,利用窮舉法找到一個滿足式(5-2)的序列號。只適合窮舉難度不大的函式
4、給定一個序列號,利用式(5-2)變換出一個使用者名稱,從而得到一個正確的使用者名稱/序列號對。

(3)通過對等函式來檢查註冊碼
在這裡插入圖片描述
此方法同樣不會再記憶體中出現明文,F1、F2是兩種完全不同的的演算法,但使用者名稱通過F1演算法的計算出的特徵字等於序列號通過F2演算法計算出的特徵字,這種演算法在設計上比較簡單,保密性相對以上兩種演算法也要好的多。如果能夠把F1、F2演算法設計成不可逆演算法的話,保密性相當的好;可一旦解密者找到其中之一的反演算法的話,這種演算法就不安全了。一元演算法的設計看來再如何努力也很難有太大的突破,那麼二元呢?

(4)同時將使用者名稱和註冊碼採用的自變數(即採用二元函式)

特定值 = F(使用者名稱,序列號)

這個演算法看上去相當不錯,使用者名稱稱與序列號之間的關係不再那麼清晰了,但同時也失去了使用者名稱於序列號的一一對應關係,軟體開發者必須自己維護使用者名稱稱與序列號之間的唯一性,但這似乎不是難以辦到的事,建個資料庫就好了。當然你也可以根據這一思路把使用者名稱稱和序列號分為幾個部分來構造多元的演算法。
  
特定值 = F(使用者名稱1,使用者名稱2,…序列號1,序列號2…)

在這裡插入圖片描述

5.1.2 如何攻擊序列號保護機制

1、資料約束性的祕訣

這個概念是+ORC提出的,只限於用明文比較註冊碼的那種保護方式。在大多數序列號保護的程式中,那個真正的、正確的註冊碼或密碼(Password)會於某個時刻出現在記憶體中,當然它出現的位置是不定的,但多數情況下它會在一個範圍之內,即存放使用者輸入序列號的記憶體地址±0X90位元組的地方。這是由於加密者所用工具內部的一個Windows資料傳輸的約束條件決定的。

2、hmemcpy函式

函式Hmemcpy是Windows9x系統的內部函式,位於KERNEL32.DLL中,它的作用是將記憶體中的一塊資料拷貝到另一個地方。由於Windows9x系統頻繁使用該函式處理各種字串,因此用它作為斷點很實用,它是Windows9x平臺最常用的斷點。在Windows NT/2K中沒有這個斷點,因為其核心和Windows9x完全不同。
 
3、利用訊息斷點
許多序列號保護軟體都有一個按鈕,當按下和釋放滑鼠時,將傳送WM_LBUTTONDOWN(0201h)和VM_LBUTTONUP(0202h)訊息,因此,用這個訊息下斷點很容易就能得到按鈕的事件程式碼。

4、利用提示資訊
目前大多數軟體在設計時採用了人機對話的方式。即軟體在執行一段程式之後會顯示一串提示資訊,以反映該程式執行後的狀態。
例如:在traceme例項中輸入假序列號,會顯示“序列號錯誤,再來一次”。可以用ollydbg、ida、X64dbg等反彙編工具查詢相應的字串,定位到相關程式碼處

5.1.3 字串比較形式

在這裡插入圖片描述
在這裡插入圖片描述

相關文章