翻譯|使用教程|編輯:黃竹雯|2019-04-19 11:38:46.000|閱讀 512 次
概述:VMProtect 是一種很可靠的工具,可以保護應用程序代碼免受分析和破解,但只有在應用程序內保護機制正確構建且沒有可能破壞整個保護的嚴重錯誤的情況下,才能實現最好的效果。 讓我們一起來看看為應用程序提供良好保護的關鍵要素。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
VMProtect 是一種很可靠的工具,可以保護應用程序代碼免受分析和破解,但只有在應用程序內保護機制正確構建且沒有可能破壞整個保護的嚴重錯誤的情況下,才能實現最好的效果。 讓我們一起來看看為應用程序提供良好保護的關鍵要素。
許多開發人員在設計自己的應用程序注冊過程時常常犯的一個錯誤是將整個注冊密鑰檢查包含在一個單獨的函數中,該函數還返回一個易于理解的值:
function CheckRegistration(const RegNumber: String): Boolean; begin if RegNumber='123' then Result:=True else Result:=False; end; procedure TForm1.Button1Click(Sender: TObject); begin ... if not CheckRegistration(RegNumber) then exit; Application.CreateForm(TForm2, Form2); Form2.ShowModal; ... end;
使用這種方法,入侵者甚至不需要理解密鑰檢查算法。他可能只是在檢查過程的開頭修改代碼,就可使其始終返回正確的注冊密鑰值:
function CheckRegistration(const RegNumber: String): Boolean; begin Result:=True; exit; ... end;
檢查密鑰的一種更有效的方法是將檢查的正確性嵌入到程序的主要操作邏輯中,使得注冊密鑰檢查的算法不能與調用過程的算法分離。我們還建議將操作邏輯與注冊密鑰檢查過程“混合”,以便在繞過檢查時使程序失敗。 對于上面的示例,可以按如下方式完成:
function CheckRegistration(const RegNumber: String): Boolean; begin if RegNumber='123' then begin Application.CreateForm(TForm2, Form2); Result:=True end else Result:=False; end; procedure TForm1.Button1Click(Sender: TObject); begin ... Form2:=nil; if not CheckRegistration(RegNumber) then exit; Form2.ShowModal; ... end;
如果這樣來實現CheckRegistration的功能,入侵者想要繞過它的話,就必須分析所有細節中的注冊密鑰檢查代碼。如果此應用程序受VMProtect保護,則建議同時虛擬化CheckRegistration函數和TForm1.Button1Click過程。 為了使黑客更難破解程序,你可以打開“Ultra”保護模式,將代碼突變和虛??擬化結合起來。
開發人員常犯的另一個錯誤是注冊密鑰檢查的錯誤實現。輸入的密鑰通常只是與正確的值進行比較。通過跟蹤字符串比較函數的參數,cracker可以輕松匹配密鑰的正確值:
var ValidRegNumber: String; ... function CheckRegistration(const RegNumber: String): Boolean; begin if RegNumber=ValidRegNumber then Result:=True else Result:=False; end;
為避免這種情況,我們建議比較密鑰的哈希值,而不是實際值。哈希函數是不可逆的,因此破解者無法從哈希中檢索真正的密鑰值,并且必須花費更多的時間來研究程序,因為現在需要分析更多的代碼片段,而不僅僅是注冊密鑰檢查過程:
var HashOfValidRegNumber: Longint; ... // Peter Weinberger's PJW hashing algorithm example of use function HashPJW(const Value: String): Longint; var I:Integer; G:Longint; begin Result:=0; for I:=1 to Length(Value) do begin Result:=(Result shl 4)+Ord(Value[I]); G:=Result and $F0000000; if G<>0 then Result:=(Result xor (G shr 24)) xor G; end; end; function CheckRegistration(const RegNumber: String): Boolean; begin if HashPJW(RegNumber)=HashOfValidRegNumber then Result:=True else Result:=False; end; ... initialization HashOfValidRegNumber:=HashPJW(ValidRegNumber); end.
使用VMProtect保護應用程序時,應使用 HashPJW 和 CheckRegistration 功能,讓黑客更難入侵。
通常,即使在注冊程序上花費大量時間的開發人員也很少注意保護注冊程序的結果。下面的示例在調用序列號檢查過程之前使用全局變量來存儲和控制應用程序的注冊狀態。 對于入侵者來說,找到一個全局變量是件小事 - 他只需要在注冊之前和之后比較數據段。順便說一下,流行的ArtMoney程序使用相同的原理。
var IsRegistered: Boolean; ... procedure TForm1.Button1Click(Sender: TObject); begin ... if not IsRegistered then IsRegistered:=CheckRegistration(RegNumber); if not IsRegistered then exit; ... end;
為避免這種情況,我們建議將與程序注冊相關的所有檢查結果存儲在動態內存中。在這種情況下,在注冊之前和之后掃描修改的存儲塊的數據段是無用的。這是一個非常簡單的示例,演示如何將結果存儲在動態分配的內存中:
type PBoolean = ^Boolean; var IsRegistered: PBoolean; ... procedure TForm1.Button1Click(Sender: TObject); begin ... if not IsRegistered^ then IsRegistered^:=CheckRegistration(RegNumber); if not IsRegistered^ then exit; ... end; ... initialization New(IsRegistered);
這些是利用內置保護機制的最簡單方法。注冊程序,注冊密鑰檢查和存儲結果的實際實現僅限于開發人員的創造性。無論如何,你應該知道這些常見錯誤,避免在開發自己的保護機制時出現這種錯誤。
VMProtect 在線訂購有優惠噢~ 立即購買正版VMProtect>>>
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn