VB 共享軟件防破解設計技術初探(一)
標 題: 【原創】VB 共享軟件防破解設計技術初探(一)
作 者: 愛琴海
時 間: 2008-09-04,20:32:29
鏈 接: http://bbs.pediy.com/showthread.php?t=72050
VB 共享軟件防破解設計技術初探(一)
××××××××××××××××××××××××××××××××××××××××××××××
其他文章快速鏈接:
VB 共享軟件防破解設計技術初探(二)
http://bbs.pediy.com/showthread.php?t=72204
VB 共享軟件防破解設計技術初探(三)
http://bbs.pediy.com/showthread.php?t=72489
××××××××××××××××××××××××××××××××××××××××××××××
作者:愛琴海[SCG] 2008/09/04 (轉載請保留該信息)
一轉眼又過去了一年,回頭一看,今年我沒發表過任何破解類文章,沒有任何有價值的文章,名下的精華只是徒有其表的7個,也許太忙,也許讀大學讀得後悔,也許墮落了。
在看雪註冊的帳號一晃就是兩個春夏秋冬了,大三要忙自己的學業了,估計以後也不會再有時間和精力破解軟件,學習加密思想了。兩年的時間發生了太多的事情,來不及回憶,來不及思考,我們班班長不久前溺水去逝了,估摸著也到頭七了……
這世事總無償,讓人來不及追憶,來不及哀悼。今天實習的時候,好好的,竟然被車床飛出來的鐵屑燙傷……
趁現在還在罈子裡活動,趁現在腦子還沒生鏽,我琢磨著把自己兩年來積累的部分經驗和思想寫下來,留下點什麼有用的東西。
學習VB編程也就一年,只是入門而已,談不上什麼高手。本系列是作者本人嘗試過和破解過的一些技術經驗之談,如果有問題或者有紕漏和錯誤,敬請高位高手點明和說明;也不知道該系列能寫多少,能寫多久;若是有時間,有精力,有能力,我會繼續寫下去,謝謝大家的觀看。
加密解密一直是相輔相成的技術,沒有矛何必有盾?有盾怎能沒矛?
在不斷的嘗試和實踐中,才能積累起豐富的加密解密經驗,為自己寫的共享軟件設計出一套完善的加密系統,或者攻克一個高度加密的共享軟件,兩者都是件令人歡心令人耗盡精力。終記起這樣的一段詩句:「衣帶漸寬終不悔,為伊消得人憔悴」。
本系列第一篇,粗略的講解我認識到的VB防破解技術,後續篇將實戰演練教學
我個人認識的VB防破解包括如下幾下方面:
1、 文件完整性,防止被非法修改
2、 運行時的校驗,防止被LOADER
3、 反調試,防止動態跟蹤和掛接
4、 防靜態反彙編分析
5、 註冊碼系統(算法部分,核心內容)
6、 加殼防脫殼
7、 隱蔽性設計
8、 另闢蹊徑
由於VB天生的原因,有些功能實現起來非常麻煩,比方說算法部分,如果採用大數運算的話,缺少大數運行庫。所以,有時也可以採用第三方DLL來補充大數的不足。
我先粗略的講下以上8大點的大概分類:
1、 文件完整性,可採用CRC32或者MD5或者哈希算法等,計算出文件的加密值,在適當的時候進行對比,判斷文件被修改與否。當然那也可以加猛殼來 防止文件非法修改。還有簡單點的檢查文件最後修改時間,看看是否是你自己設置好的時間,如果不是,則很有可能被修改過;也可以檢測文件大小,往往壓縮殼被 脫掉後,文件的大小會增加;保護殼被脫掉後,文件大小會變小,我們可以根據這個設置好臨界值來檢測有沒有被脫殼。常用的還有故意設計好關於算法方面的陷 阱,如果是破解者會主動掉進你的陷阱,而事實上,這個跳轉除非爆破,不然在算法上是永遠也無法到達的,這樣就檢出破解者在修改程序流程。你可以無聲無息的 程序死掉,不要直接退出,不然會被追蹤到退出函數。
2、 防止LOADER,這個實現起來不容易,但是可以巧妙的應用VB裡的SHELL函數,進行「金蟬脫殼」。常用的保護殼裡有些也能防止LOADER。
在下次系列裡將講解「金蟬脫殼」技術
3、 反調試,如同《使用VB進行反跟蹤的技術點滴》一文講解,基本差不多了。常見的有:檢測父進程;遍歷所有進程檢查程序標題欄,看看是否有敏感字符;反SMARTCHECK加載;經典時值步長比較;異常處理技術(這個要當作重點)一些猛殼本身也有反調試功能。
4、
還可以檢測程序啟動時間,一般調試器加載都是比正常啟動程序要慢10倍左右
還可以檢測內存分配,如果OD調試器啟用了HIDEOD插件的話,那麼程序獲得的
內存分配上限和下限都是不一樣的
還可以檢測所有標題,枚舉進程等
一般要加幾個TIMER控件來時時反調試,這樣可以在OD掛接到程序的時候檢測出來
可參考實例:
http://bbs.pediy.com/showthread.php?t=67232
http://bbs.pediy.com/showthread.php?t=57181
以前看雪論壇裡有篇文章,laomms大俠寫的《使用VB進行反跟蹤的技術點滴》一文,對我們學習VB的防破解設計是很有幫助的,為了大家觀看方便,我將它引錄到下文中:
原文地址:http://bbs.pediy.com/showthread.php?t=26213
———————————————————————————————————————
跟其它語言相比,VB總是被人「鄙視」,其實沒有好與不好的語言,正如某程序員說的:沒有最好的語言,只有最好的程 序員。VB也有它自己的特點,簡單、方便、可視化強、利於快速開發,6M的迷你版更是讓人在不釋手。而且容易入門,也是通往其它語言最好的一個奠基。可惜 關於VB方面的保護技術的文章很少,軟件加密技術裡面有涉及VB的保護內容,但是源碼太少了,大部分是C和MASM源碼,這裡我們也粗略的講講VB的一些 保護技術,如果你還有更好的方法希望在下面補充。
一、檢測父進程反RING3調試器,我們知道WIN32系統一般軟件的父進程都是EXPLORE,而OD等RING3調試器對軟件進行調試時都是 將它們的線程設為它的子線程,我們只要讓程序檢查父進程是否為EXPLORE就行,看附件裡的Anti-Debug,如果發現父進程不是 EXPLORE.EXE就自動退出,源碼如下:
'相關的API自己查查
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&) '建立進程快照
If hSnapShot Then
Process.dwSize = 1060
If (Process32First(hSnapShot, Process)) Then '遍歷第一個進程,獲得PROCESSENTRY32結構
Do
i = InStr(1, Process.szExeFile, Chr(0)) '獲得映像名稱
mName = LCase(Left(Process.szExeFile, i - 1)) '並轉換成小寫
If mName = "explorer.exe" Then '是不是explorer.exe
explorer = Process.th32ProcessID '獲得進程ID
ElseIf Process.th32ProcessID = GetCurrentProcessId() Then '是不是自己
pid = Process.th32ParentProcessID '獲得自己父進程ID
Else
flag = False
End If
Loop Until (Process32Next(hSnapShot, Process) < 1) '遍歷所有進程直到返回值為False
End If
l1 = CloseHandle(hSnapShot)
End If
If pid <> explorer Then
TerminateProcess hprocess, 0
Else
MsgBox "ok"
On Error Resume Next
End If
End Sub
當然這個方法也不是萬能的,在Process32First下斷,更改跳轉輕易躲過。
二、反SMARTCHECK加載,SMARTCHECK是調試VB的利器,有必要對其進行防範。小樓前輩在軟件加密技術內幕中提到兩種檢測方法:
利用VB的AppActivate函數激活SMARTCHECK窗口,然後發送ALT+F4進行關閉該窗口和利用FindWindow發現SMARTCHECK窗口直接將其關閉,其代碼基本上是這樣:
winHwnd = FindWindow(vbNullString, "Numega SmartCheck")
If winHwnd <> 0 Then
AppActivate "Numega SmartCheck"
sendkey "%{f4}", True
sendkey "%y", True
其實,我覺得直接檢測進程SMARTCHK.EXE是否存在也可以,方法跟上面類似,你還可以檢測其它比如W32DASM等進程,附件中的Anti-Load就是實例,發現SMARTCHK調用,自動退出:
…..
If InStr(LCase(Process.szExeFile), "smartchk.exe") > 0 Then
smart = Process.th32ProcessID
TerminateProcess hprocess, 0
Unload Me
Exit Do
End If
…….
三、檢測SOFTICE,附件裡的Anti-ice就是Aming前輩的代碼,在內存中直接檢測SOFTICE。
四、利用IsDebuggerPresent檢測調試器,這個對於OD來說已經一點用都沒有了。具體看附件中的IsDebuggerPresent。
Private Declare Function IsDebuggerPresent Lib "kernel32" () As Long
Private Sub Command1_Click()
If IsDebuggerPresent Then
End
Else
MsgBox "沒有被調試"
End If
End Sub
五、加密字符串。
比如Text1.text=」恭喜」,我們可以這樣寫:Text1.text=Chr(-18009) & Chr(-12366) & amp; Chr(33),另外一種就是寫算法將字符串進行加密,實例Encodestring裡你將找不到字符串信息,找到的是亂碼。
六、實現軟件代碼校檢防止被修改,比如用CRC或者MD5進行自身代碼完整性檢測,實現方法:
先寫一個用於增加CRC特徵碼的軟件,假設定義為結尾部分:
Const CRC_HEAD = &H761226 '用於判斷是否添加了CRC校驗
Private Type stCRC
lHead As Long '驗證是否進行CRC校驗的標識
lCRC As Long 'CRC校驗值
End Type
Private Sub Command1_Click()
CRC_Exe App.Path & "\工程1.Exe"
End Sub
Private Function CRC_Exe(ByVal strExe As String) As Boolean
Dim hFile As Long
Dim lFileLen As Long
Dim sCRC As stCRC
Dim btExe() As Byte
On Error GoTo Err_CRC_Exe
lFileLen = FileLen(strExe)
hFile = FreeFile
Open strExe For Binary As #hFile '打開加密文件
Seek hFile, lFileLen - LenB(sCRC) + 1 '定位CRC標識域,位於Exe文件尾部文件
Get hFile, , sCRC
If sCRC.lHead = CRC_HEAD Then '如果已經添加了CRC校驗則退出,反之添加CRC校驗
MsgBox "已CRC驗證!"
Close #hFile
Exit Function
Else
Seek hFile, 1 '定位到文件首部
ReDim btExe(lFileLen - 1)
Get hFile, , btExe '按字節方式將Exe數據讀入數組
sCRC.lHead = CRC_HEAD '添加CRC驗證標識
sCRC.lCRC = Get_CRC(VarPtr(btExe(0)), lFileLen) '獲取Exe內容CRC值
Put hFile, , sCRC '將CRC校驗寫入Exe文件尾部
End If
Close #hFile
MsgBox "CRC校驗完成!"
CRC_Exe = True
Exit Function
Err_CRC_Exe:
If hFile <> 0 Then Close #hFile
CRC_Exe = False
MsgBox Err.Description
End Function
為程序本身增加CRC校檢代碼:
Const CRC_HEAD = &H761226 '用於判斷是否添加了CRC校驗
Private Type stCRC
lHead As Long '驗證是否進行CRC校驗的標識
lCRC As Long 'CRC校驗值
End Type
Private Sub Form_Load()
Dim hFile As Long
Dim sCRC As stCRC
Dim strExe As String
Dim lFileLen As Long
Dim btExe() As Byte
strExe = App.Path & "\" & App.EXEName & ".exe"
lFileLen = FileLen(strExe)
ReDim btExe(lFileLen - LenB(sCRC) - 1) As Byte '定義Exe字節緩存數組
hFile = FreeFile
Open strExe For Binary As #hFile '讀取Exe數據到數組
Get #hFile, , btExe
Get #hFile, , sCRC
Close #hFile
If sCRC.lHead = CRC_HEAD Then '如果程序添加了CRC驗證則驗證CRC值
If Get_CRC(VarPtr(btExe(0)), UBound(btExe) + 1) = lCRC Then '驗證Exe數據CRC和保存的CRC值是否相同
MsgBox "文件未修改!".
Else
MsgBox "文件被非法修改!"
End If
Else
MsgBox "文件尚未進行CRC驗證!" '檢查尾部是否已已經增加CRC校檢
End If
End Sub
其中的CRC模塊網上很多。附件中的CRC32就是實例,修改任何一處軟件都提示被修改。增加自校檢後建議再隨便加個殼,否則用UltraEdit直接就可以對比原文件查出CRC校驗值位置。
七、利用SEH進行反跟蹤,附件裡的SHE如果用SMARTCHECK調試的話就合自動退出,附上小樓的源碼:
Option Explicit
Private Declare Sub DebugBreak Lib "kernel32" ()
Private Sub Command1_Click()
On Error GoTo ERR_RaiseException
DebugBreak
DebugBreak
Exit Sub
ERR_RaiseException:
MsgBox "沒有發現調試器!"
End Sub
Sub SetHandler()
SetUnhandledExceptionFilter AddressOf NewExceptionHandler
End Sub
Sub RestoreHandler()
SetUnhandledExceptionFilter 0
End Sub
Private Sub Form_Load()
SetHandler
End Sub
Private Sub Form_Unload(Cancel As Integer)
RestoreHandler
End Sub
'SHE模塊略過。
除了上面的一些方法外,你還可以用一些密碼學知識增加難度,如果技術夠強,還可以借用內嵌彙編弄一些花指令和反調試SEH機制
______________________________________________________________
感謝laomms大俠給我們上了關於VB反調試的生動一課
5、 代碼混淆?加花,VM,選擇P-CODE方式等,都可以起到不錯的作用。
有些干脆搬出假目標(什麼「註冊正確」之類的提示,其實這個地方根本沒有正確的算法)甚至,你可以直接修改VB的開始語句:(主要是防VBExplorer靜態分析)
正常其實語句:
004018CC >/$ 68 7C1D4000 PUSH 1112.00401D7C
004018D1 |. E8 F0FFFFFF CALL <JMP.&MSVBVM60.#100>
這個明顯透露了VB程序,我們要做的是搬走這個位置
換句話說是把這個CALL移走,移到天南海角去……
004018D6 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018D8 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018DA |. 0000 ADD BYTE PTR DS:[EAX],AL
004018DC |. 3000 XOR BYTE PTR DS:[EAX],AL
004018DE |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E0 |. 3800 CMP BYTE PTR DS:[EAX],AL
004018E2 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E4 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E6 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E8 |. 3A28 CMP CH,BYTE PTR DS:[EAX]
004018EA |. 8A00 MOV AL,BYTE PTR DS:[EAX]
004018EC \. CF IRETD
修改後:───────────────────────》》》
004018CC > $ /E9 7FA50100 JMP 了凡第一.0041BE50
004018D1 |90 NOP
004018D2 |90 NOP
004018D3 |90 NOP
004018D4 |90 NOP
004018D5 |90 NOP
0041BE50 60 PUSHAD
0041BE51 0F31 RDTSC
經典時值,單步跟,不小心的話就會進入到錯誤地址
0041BE53 8BC8 MOV ECX,EAX
0041BE55 0F31 RDTSC
0041BE57 2BC1 SUB EAX,ECX
0041BE59 3D 00050000 CMP EAX,500
0041BE5E ^ 0F8F BAF9FFFF JG 了凡第一.0041B81E
0041BE64 83F8 00 CMP EAX,0
0041BE67 ^ 0F8C C7F9FFFF JL 了凡第一.0041B834
0041BE6D 61 POPAD
0041BE6E 68 68504000 PUSH 了凡第一.00405068
0041BE73 60 PUSHAD
0041BE74 0F31 RDTSC
0041BE76 8BC8 MOV ECX,EAX
0041BE78 0F31 RDTSC
0041BE7A 2BC1 SUB EAX,ECX
0041BE7C 3D 00050000 CMP EAX,500
0041BE81 ^ 0F8F ADF9FFFF JG 了凡第一.0041B834
0041BE87 83F8 00 CMP EAX,0
0041BE8A ^ 0F8C 8EF9FFFF JL 了凡第一.0041B81E
0041BE90 61 POPAD
0041BE91 E8 305AFEFF CALL <JMP.&MSVBVM60.#100>
搬到這裡來了
0041BE96 ^ 0F85 3A5AFEFF JNZ 了凡第一.004018D6
0041BE9C ^ 0F84 345AFEFF JE 了凡第一.004018D6
效果:
如果有時間,你可以自己設計得更恐怖點,東一句西一句,讓別人無法還原
5、 註冊算法系統
這個是軟件防破解的核心內容,推薦採用 陷阱+隱藏關鍵算法到異常裡面執行+不可逆算法+公開密碼體制+算法跟核心功能模塊代碼綁定,只有正確解密後的功能代碼才能發揮因該有的功能。
經常碰到VB的註冊算法,一般共享軟件不夠重視這塊內容,只是進行簡單的加加減減,或者XOR,或者凱撒+矩陣,結果好像跟輸入的用戶名完全不一樣,似乎 很安全,其實只要破解者跟蹤到了算法,按照那樣的計算的話,基本都是明碼比較,非常容易破解,甚至根本不用瞭解你的算法是什麼。
曾經看到過有共享軟件作者在網上說:「我用的機器碼是隨機生成,保存在註冊表裡的,但是就算這樣,別人用了什麼內存註冊機就把我的註冊碼算出來了,這到底怎麼回事?太受打擊了…」
市面上出現明碼比較的多是些新手寫的軟件,而且大部分是VB程序,為什麼?因為VB本身的算法支持不是很好,大都是跟用戶名的ASCII碼綁定。這些都是 弱點,容易被發現和跟蹤,別人只要用函數斷點斷MID,LEFT,RIGHT字符函數,那麼關於ASCII取用的基本都會被發現。
在這裡,我推薦採用浮點計算,除了算法本身不可逆,強度夠大,經得起窮舉外,還要小心謹慎的隱藏掉比較代碼,因為大都初學破解VB程序的菜鳥都喜歡斷 StrComp函數,大都可以直接斷到關鍵比較位置,如果你的良好的密碼系統即將為你帶來第一桶金,但是不幸你發現菜鳥斷個比較函數,然後爆破了,呵呵, 你的心情怎樣?更不要說是明碼比較的了。
浮點計算,你要把字符串轉為DOUBLE類型,指數運算和求余運算是比較好的算法,但是VB本身又不支持大數運算,單純的指數運算和求余很可能會發生溢出錯誤。
高次指數運算和求余可採用中國剩餘定理來計算,也可以看看我寫的代碼,也許你會有啟發:
首先是MOD函數必須自己寫一個,VB自帶的MOD範圍太小
Private Function Modx(x As Double, y As Double) As Double
Dim w As Double
w = Fix(x / y) * y
Modx = x - w
End Function
這樣就實現了稍大數在Vb裡的求余動作
Private Function Rsa(p As Double) As Double
Dim b As Double
Dim rsan As Double
rsan = 99221
Rsa = 1
For b = 1 To 15935
Rsa = Rsa * p
Rsa = Modx(Rsa, rsan)
Next b
End Function
通過每次都求余,剩下的繼續執行指數運算,下次再求余,就避免的誤差和溢出
我們看下:
3^6 mod 25 = 729 mod 25 =4
等同於:
3^6 mod 25 =(((((((((3 mod 25) * 3) mod 25) * 3) mod 25) * 3) mod 25)* 3) mod 25)* 3 mod 25 = 4
可發現計算結果一致,當然這個規律是可以證明的,通過這樣的計算法則,我們可以大量減少運算強度。你不想實驗下嗎?
上面給的程序其實就是RSA算法的應用,但是只能當作理論來用,實際上N太小了,非常容易被分解,呵呵,我們以此來學習RSA算法倒是沒問題,以後用RSA的時候,只要用第三方DLL即可,比方說《共享軟件加密算法庫》即有相關應用。
這裡的E為 15935
這裡的N為 99221
這裡的加密法則為 C = P^E mod N
如果N足夠大,一般要求512位以上(二進制)才能有些安全度,要破解RSA算法,只要分解N為兩個大質數的乘積即可……
可以用RSAtool來分解,速度很快……
分解後計算出D (解密密鑰)
則解密算法為 P = C^D mod N
這裡計算出D為48767
也就是說逆運算為:
'解密過程
Private Function Jiemi(c As Double) As Double
Dim b As Double
Dim rsan As Double
rsan = 99221
Jiemi = 1
For b = 1 To 48767
Jiemi = Jiemi * c
Jiemi = Modx(Jiemi, rsan)
Next b
End Function
當然,還有其他算法也很不錯,到時有空再後續系列裡詳細演示……
關於如何隱藏關鍵算法到異常處理中去?
這個一直是Vb裡很酷的技術,今天我把自己琢磨出的東西簡單說一下,到下期系列的時候再具體演示
VB裡的異常處理機制是 通過 On error goto 這個語句進行的,這個功能可大了,配合Resume Next、Resume 等語句,基本可以實現VB裡的高級隱藏技術
大致是先在算法裡嵌入迷惑性質的算法,通過一個可行的數值來產生一個指定的,不常見的錯誤,比方說可以除零,通過 On error goto 進行 異常捕獲,判斷Err.Number 是否等於某個數值(不同數值對應不同錯誤類型)或者故意製造出一個溢出來捕獲,捕獲後可以解密一兩句算法,然後通過 Resume Next回到原程序,繼續解密,又產生其他的錯誤,然後繼續解密真正的算法……
大家可以看看具體應用的例子
http://bbs.pediy.com/showthread.php?t=71741
http://bbs.pediy.com/showthread.php?t=72017
這些技術在VB共享軟件裡出現過,但是不常見,甚至可以說是稀少了;其作用真的很不錯,因為破解者在不知道你具體用意的前提下,一步步分析下來,分析的是 正常路徑,絕對不會產生我們指定的錯誤,到最後發現總是無法解密算法,他才意識到似乎掉到一個非同尋常的陷阱裡了,然後他回回頭往上看,不停的分析,哪裡 才是正確的JNZ或者JE等跳轉指令,殊不知若這樣分析,他永遠也分析不到我們指定的正確算法
說得形象點吧,就像打RPG類單機遊戲一樣,破解者一步步玩下來,沒出現任何差池,最後通關到了打BOSS的時候,發現不管怎麼打就是要死,打得都沒信心 了,為什麼如此?因為我們這個遊戲要求在玩第一關或者前面幾關的時候要觸發某些隱藏劇情,或者隱藏劇情的任務獎勵,獎勵的東西是什麼絕世神兵,可以秒殺 BOSS,或者要觸發多個不同的隱藏劇情,獲得一組或者好幾組密鑰等,參與最後的BOSS大決戰,少了這些參數,就算遊戲順利玩下來了,最後也是徒勞的
而這個隱藏的劇情不是發現了就可以進入隱藏劇情的,我們要求多少經驗值,或者多少攻擊力,或者以前做過些什麼,比方說是幫老奶奶過馬路,撿到一分錢交給警察叔叔等,而這些事情是普通玩家和破解者所不會做,或者做不到的
比方說我要實現一個異常除零錯誤,來捕獲流程進行注射關鍵代碼(正常情況下是不會發生錯誤,也就得不到注射了,所以總是要感冒,總是要生病,總是要死的,最後他甚至認為你的程序寫的有問題,算法無解等,其實是沒有做隱藏任務)
如:
On Error GoTo chuling
Dim a As Double
Dim b As Double
a = 110
b = "&H" & Left(MD5(Right(Text2.Text, 16)), 5
a = 110 / b Xor 123456789
If a = 123 Then
MsgBox "註冊碼錯誤", , "提示"
Else
If a = 0 Then MsgBox "註冊碼正確", , "提示"
提示 :想想,正常過來的畫,a怎麼可能等於0
End If
Exit Sub
chuling:
'關鍵核心算法
噢,原來是發生了一次異常,在流程裡注射了 「a = 0」這條指令
a = 0
Resume Next
這只是個簡單的實例,MD5是MD5算法,因其逆算要窮舉所以作為隱藏劇情的加密是可以的,你事先先計算好某個數字串的MD5,轉十進制後,算出其有效片段,將該有效片段作為XOR常量,即可。
不知道要發生異常的人,只會直接看下來,到時總也無法註冊成功,就算他知道要做隱藏任務,要使得XOR後為零,使得除數為零出錯,他也無法根據已知XOR常數去反推原始數字串,除非爆破,否則難以為繼。
算法還有很多,比方說離散數學原理等都可以用上去
如果算法還可以跟具體程序功能代碼解密掛鉤,那麼效果不是一般的好
現在是總的概要來說的,總結下:
VB 加密算法要求
1、不可逆及在不知道密鑰的情況下,只能加密,不能解密
2、算法隱藏很隱蔽的陷阱和隱藏劇情,及各類觸發條件,最好是一般人都接觸不到的觸發條件
3、儘量用公開算法
4、關鍵比較必須隱蔽
5、算法採用注射式,不同的註冊碼輸入驗證會激活不同的注射代碼
6、最重要的一點是:算法跟程序很緊密,甚至是程序的大段功能代碼都必須用註冊碼來解密後才能執行正確的功能,否則解密出來的代碼執行會出錯,這樣是為了防止爆破
7、最後是非明碼,用浮點計算
6、 加殼防脫殼
單單靠自己一個人的力量很多時候完成一套完整的安全的VB防破解體系是很困難的,我們要學會「站在巨人的肩膀上」,利用已有工具和加密思想,結合自己的創 新,使得程序更加堅固。大部分保護殼都有反調試,防修改,時間限制等功能,好好利用可以增加你的軟件的強度。VB程序一般加殼有三類:
第一, 壓縮殼,然後在程序代碼裡加入檢測文件大小等校驗手法,主要目的是方修改和方便網絡傳輸,減少體積
第二, 保護殼,常見的有ASProctect、Armadillo、EXECryptor、Themida等,有些兼容性不好,有些已經別解密者摸透,不推薦用 ASProctect ,研究的人太多了。
第三, 虛擬機保護,常見的有VMProtect,將關鍵代碼和算法過程及隱藏任務代碼虛擬執行,代碼急劇擴張,讓人跟得頭痛。VB本身的P-CODE方式也是類似於虛擬機了,但是被人研究的多了,破解只是時間和精力上的問題。
7、隱蔽性設計
結合異常機制和,反調試機制,界面上進行迷惑等手段,假算法,假註冊成功提示,通過給類手段,將真正的算法和功能模塊隱藏,執行的時候是正確的流程,但是一旦有調試器存在就會朝著令一個方向,甚至是很多方向發展,無窮無盡的輪迴……
比方說我畫出兩個一模一樣的註冊按鈕,當發現調試和異常問題後,就啟動令一個模樣一樣的按鈕,原先的按鈕就此屏蔽,那麼不管破解者如何努力,他們跟蹤的算法和事件永遠是替換後的按鈕對應的算法和事件,而其是根本無法註冊成功的
參考實例:
http://bbs.pediy.com/showthread.php?t=52623
http://bbs.pediy.com/showthread.php?t=52189
8、另闢蹊徑
常規的註冊方式是用戶名對應註冊碼,或者機器碼對應註冊碼,或者機器碼+用戶名+註冊碼,或者是單獨的註冊碼;有的是KEYFILE方式,有的是網路驗證(目前網絡驗證結合本地驗證已經越來越流行,越來越難搞了)
他們有一個共同點,那都是要輸入字符,或者是處理字符串,這樣一來,都有可能被快速找到斷點字符串處理的函數進行破解
我想能不能用新的註冊方式呢?還真的有,但是是概念性的,實用價值還不夠大
我想到的另闢蹊徑是利用語音麥克風,讓用戶讀出一段語音,由電腦自動判斷是否是對應的「咒語」,這樣就避免了字符處理,而且大家對聲音的處理都不清楚,也 就不好跟蹤了,軟件作者發售軟件到時候,可以根據對方的機器碼來計算出相應的讀音,進行錄音,然後傳給消費者,或者刻錄到光盤裡郵寄給消費者,消費者在每 次使用軟件的時候,都要跟著錄音念一遍咒語,即可被自動識別。
根據這個原理,我曾經完成了一個CM,下載地址如下:
http://bbs.pediy.com/showthread.php?t=61417
朗讀咒語的時候,請按住鍵盤的「Scroll Lock」鍵,朗讀完咒語後鬆開此鍵。系統助手(一個老頭)會自動通過語音告訴你結果如何。
現在公佈相關代碼:(其實核心就是微軟的語音識別技術)
MyAgent.Characters.Load "Merlin", DATAPATH & "Merlin.acs"
'獲取與CharacterID相對應的IAgentCtlCharacter變量
Set Merlin = MyAgent.Characters("Merlin")
'顯示/隱藏動畫人物
Merlin.LanguageID = &H409
Merlin.Show
Set GenieRequest1 = Merlin.MoveTo(880, 580) '450,300
Merlin.Speak Chr(87) & Chr(101) & Chr(108) & Chr(99) & Chr(111) & Chr(109) & Chr(101) & Chr(46)
Merlin.Speak Chr(80) & Chr(108) & Chr(101) & Chr(97) & Chr(115) & Chr(101) & Chr(32) & Chr(114) & Chr(101) & Chr(97) & Chr(100) & Chr(32) & Chr(121) & Chr(111) & Chr(117) & Chr(114) & Chr(32) & Chr(112) & Chr(97) & Chr(115) & Chr(115) & Chr(119) & Chr(111) & Chr(114) & Chr(100)
Static initialized As Boolean
'添加自定義命令
If Not initialized Then
Merlin.Commands.Add " ", " ", Chr(104) & Chr(101) & Chr(108) & Chr(108) & Chr(111), True, False
Merlin.Commands.Add " ", " ", Chr(99) & Chr(108) & Chr(111) & Chr(115) & Chr(101), True, False
Merlin.Commands.Add " ", "", Chr(83) & Chr(67) & Chr(71) & Right(zhucema, 6), True, False
initialized = True
End If
Merlin.Show
以上是加載語音空間,和電腦動畫助手的代碼
Private Sub MyAgent_Command(ByVal UserInput As Object)
Dim apack As Byte
Merlin.Play "read"
Select Case UserInput.Voice
這句是捕獲麥克風語音的代碼
Case Chr(104) & Chr(101) & Chr(108) & Chr(108) & Chr(111)
Merlin.Speak Chr(104) & Chr(101) & Chr(108) & Chr(108) & Chr(111) & Chr(44) & Chr(115) & Chr(105) & Chr(114) & Chr(46)
Merlin.Speak Chr(80) & Chr(108) & Chr(101) & Chr(97) & Chr(115) & Chr(101) & Chr(32) & Chr(114) & Chr(101) & Chr(97) & Chr(100) & Chr(32) & Chr(121) & Chr(111) & Chr(117) & Chr(114) & Chr(32) & Chr(112) & Chr(97) & Chr(115) & Chr(115) & Chr(119) & Chr(111) & Chr(114) & Chr(100)
Case Chr(99) & Chr(108) & Chr(111) & Chr(115) & Chr(101)
Merlin.Speak Chr(65) & Chr(114) & Chr(101) & Chr(32) & Chr(121) & Chr(111) & Chr(117) & Chr(32) & Chr(115) & Chr(117) & Chr(114) & Chr(101) & Chr(32) & Chr(116) & Chr(111) & Chr(32) & Chr(99) & Chr(108) & Chr(111) & Chr(115) & Chr(101) & Chr(63)
apack = MsgBox("你確定要退出本程序?", 4 + 32 + 0, "退出請示...")
If apack = 6 Then End
以上是相關處理了,具體代碼不便公開了
侷限:沒有麥克風和聲卡的電腦就不要完成註冊了
所謂另闢蹊徑指的就是使用別人都沒有用過的技術,我記得以前有個軟件作者(同時也是加密解密高手)將註冊信息隱藏到了JPG或者BMP圖片裡,註冊的時候 只要把相應的圖片選中即可(當然,其本質可能是得到裡面的數據,進行處理後還原附加在裡面的信息來完成註冊,一般人就算能逆出算法,那要怎樣修改圖片才能 使之即可以打開,又可以附帶信息呢?)
這個就是一個另闢蹊徑,想他人沒有想到的,做他人沒有思路做的東西
其本質還是要使用強壯的算法了,要不然也容易被逆
好了,第一講就到這裡吧,第一講是系統的粗略的講解下VB防破解設計的思路和相關技術信息。
如果有空,有時間,有精力,有能力,我將發佈第二篇,也就是《共享軟件防破解設計技術初探(二)》 所涉及的應該都是以上講的,我會的一些具體程序設計過程和完整的代碼和成品,手把手教你寫出自己滿意的,連自己在不源代碼的情況下也不能破解的軟件。
作 者: 愛琴海
時 間: 2008-09-04,20:32:29
鏈 接: http://bbs.pediy.com/showthread.php?t=72050
VB 共享軟件防破解設計技術初探(一)
××××××××××××××××××××××××××××××××××××××××××××××
其他文章快速鏈接:
VB 共享軟件防破解設計技術初探(二)
http://bbs.pediy.com/showthread.php?t=72204
VB 共享軟件防破解設計技術初探(三)
http://bbs.pediy.com/showthread.php?t=72489
××××××××××××××××××××××××××××××××××××××××××××××
作者:愛琴海[SCG] 2008/09/04 (轉載請保留該信息)
一轉眼又過去了一年,回頭一看,今年我沒發表過任何破解類文章,沒有任何有價值的文章,名下的精華只是徒有其表的7個,也許太忙,也許讀大學讀得後悔,也許墮落了。
在看雪註冊的帳號一晃就是兩個春夏秋冬了,大三要忙自己的學業了,估計以後也不會再有時間和精力破解軟件,學習加密思想了。兩年的時間發生了太多的事情,來不及回憶,來不及思考,我們班班長不久前溺水去逝了,估摸著也到頭七了……
這世事總無償,讓人來不及追憶,來不及哀悼。今天實習的時候,好好的,竟然被車床飛出來的鐵屑燙傷……
趁現在還在罈子裡活動,趁現在腦子還沒生鏽,我琢磨著把自己兩年來積累的部分經驗和思想寫下來,留下點什麼有用的東西。
學習VB編程也就一年,只是入門而已,談不上什麼高手。本系列是作者本人嘗試過和破解過的一些技術經驗之談,如果有問題或者有紕漏和錯誤,敬請高位高手點明和說明;也不知道該系列能寫多少,能寫多久;若是有時間,有精力,有能力,我會繼續寫下去,謝謝大家的觀看。
加密解密一直是相輔相成的技術,沒有矛何必有盾?有盾怎能沒矛?
在不斷的嘗試和實踐中,才能積累起豐富的加密解密經驗,為自己寫的共享軟件設計出一套完善的加密系統,或者攻克一個高度加密的共享軟件,兩者都是件令人歡心令人耗盡精力。終記起這樣的一段詩句:「衣帶漸寬終不悔,為伊消得人憔悴」。
本系列第一篇,粗略的講解我認識到的VB防破解技術,後續篇將實戰演練教學
我個人認識的VB防破解包括如下幾下方面:
1、 文件完整性,防止被非法修改
2、 運行時的校驗,防止被LOADER
3、 反調試,防止動態跟蹤和掛接
4、 防靜態反彙編分析
5、 註冊碼系統(算法部分,核心內容)
6、 加殼防脫殼
7、 隱蔽性設計
8、 另闢蹊徑
由於VB天生的原因,有些功能實現起來非常麻煩,比方說算法部分,如果採用大數運算的話,缺少大數運行庫。所以,有時也可以採用第三方DLL來補充大數的不足。
我先粗略的講下以上8大點的大概分類:
1、 文件完整性,可採用CRC32或者MD5或者哈希算法等,計算出文件的加密值,在適當的時候進行對比,判斷文件被修改與否。當然那也可以加猛殼來 防止文件非法修改。還有簡單點的檢查文件最後修改時間,看看是否是你自己設置好的時間,如果不是,則很有可能被修改過;也可以檢測文件大小,往往壓縮殼被 脫掉後,文件的大小會增加;保護殼被脫掉後,文件大小會變小,我們可以根據這個設置好臨界值來檢測有沒有被脫殼。常用的還有故意設計好關於算法方面的陷 阱,如果是破解者會主動掉進你的陷阱,而事實上,這個跳轉除非爆破,不然在算法上是永遠也無法到達的,這樣就檢出破解者在修改程序流程。你可以無聲無息的 程序死掉,不要直接退出,不然會被追蹤到退出函數。
2、 防止LOADER,這個實現起來不容易,但是可以巧妙的應用VB裡的SHELL函數,進行「金蟬脫殼」。常用的保護殼裡有些也能防止LOADER。
在下次系列裡將講解「金蟬脫殼」技術
3、 反調試,如同《使用VB進行反跟蹤的技術點滴》一文講解,基本差不多了。常見的有:檢測父進程;遍歷所有進程檢查程序標題欄,看看是否有敏感字符;反SMARTCHECK加載;經典時值步長比較;異常處理技術(這個要當作重點)一些猛殼本身也有反調試功能。
4、
還可以檢測程序啟動時間,一般調試器加載都是比正常啟動程序要慢10倍左右
還可以檢測內存分配,如果OD調試器啟用了HIDEOD插件的話,那麼程序獲得的
內存分配上限和下限都是不一樣的
還可以檢測所有標題,枚舉進程等
一般要加幾個TIMER控件來時時反調試,這樣可以在OD掛接到程序的時候檢測出來
可參考實例:
http://bbs.pediy.com/showthread.php?t=67232
http://bbs.pediy.com/showthread.php?t=57181
以前看雪論壇裡有篇文章,laomms大俠寫的《使用VB進行反跟蹤的技術點滴》一文,對我們學習VB的防破解設計是很有幫助的,為了大家觀看方便,我將它引錄到下文中:
原文地址:http://bbs.pediy.com/showthread.php?t=26213
———————————————————————————————————————
跟其它語言相比,VB總是被人「鄙視」,其實沒有好與不好的語言,正如某程序員說的:沒有最好的語言,只有最好的程 序員。VB也有它自己的特點,簡單、方便、可視化強、利於快速開發,6M的迷你版更是讓人在不釋手。而且容易入門,也是通往其它語言最好的一個奠基。可惜 關於VB方面的保護技術的文章很少,軟件加密技術裡面有涉及VB的保護內容,但是源碼太少了,大部分是C和MASM源碼,這裡我們也粗略的講講VB的一些 保護技術,如果你還有更好的方法希望在下面補充。
一、檢測父進程反RING3調試器,我們知道WIN32系統一般軟件的父進程都是EXPLORE,而OD等RING3調試器對軟件進行調試時都是 將它們的線程設為它的子線程,我們只要讓程序檢查父進程是否為EXPLORE就行,看附件裡的Anti-Debug,如果發現父進程不是 EXPLORE.EXE就自動退出,源碼如下:
'相關的API自己查查
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&) '建立進程快照
If hSnapShot Then
Process.dwSize = 1060
If (Process32First(hSnapShot, Process)) Then '遍歷第一個進程,獲得PROCESSENTRY32結構
Do
i = InStr(1, Process.szExeFile, Chr(0)) '獲得映像名稱
mName = LCase(Left(Process.szExeFile, i - 1)) '並轉換成小寫
If mName = "explorer.exe" Then '是不是explorer.exe
explorer = Process.th32ProcessID '獲得進程ID
ElseIf Process.th32ProcessID = GetCurrentProcessId() Then '是不是自己
pid = Process.th32ParentProcessID '獲得自己父進程ID
Else
flag = False
End If
Loop Until (Process32Next(hSnapShot, Process) < 1) '遍歷所有進程直到返回值為False
End If
l1 = CloseHandle(hSnapShot)
End If
If pid <> explorer Then
TerminateProcess hprocess, 0
Else
MsgBox "ok"
On Error Resume Next
End If
End Sub
當然這個方法也不是萬能的,在Process32First下斷,更改跳轉輕易躲過。
二、反SMARTCHECK加載,SMARTCHECK是調試VB的利器,有必要對其進行防範。小樓前輩在軟件加密技術內幕中提到兩種檢測方法:
利用VB的AppActivate函數激活SMARTCHECK窗口,然後發送ALT+F4進行關閉該窗口和利用FindWindow發現SMARTCHECK窗口直接將其關閉,其代碼基本上是這樣:
winHwnd = FindWindow(vbNullString, "Numega SmartCheck")
If winHwnd <> 0 Then
AppActivate "Numega SmartCheck"
sendkey "%{f4}", True
sendkey "%y", True
其實,我覺得直接檢測進程SMARTCHK.EXE是否存在也可以,方法跟上面類似,你還可以檢測其它比如W32DASM等進程,附件中的Anti-Load就是實例,發現SMARTCHK調用,自動退出:
…..
If InStr(LCase(Process.szExeFile), "smartchk.exe") > 0 Then
smart = Process.th32ProcessID
TerminateProcess hprocess, 0
Unload Me
Exit Do
End If
…….
三、檢測SOFTICE,附件裡的Anti-ice就是Aming前輩的代碼,在內存中直接檢測SOFTICE。
四、利用IsDebuggerPresent檢測調試器,這個對於OD來說已經一點用都沒有了。具體看附件中的IsDebuggerPresent。
Private Declare Function IsDebuggerPresent Lib "kernel32" () As Long
Private Sub Command1_Click()
If IsDebuggerPresent Then
End
Else
MsgBox "沒有被調試"
End If
End Sub
五、加密字符串。
比如Text1.text=」恭喜」,我們可以這樣寫:Text1.text=Chr(-18009) & Chr(-12366) & amp; Chr(33),另外一種就是寫算法將字符串進行加密,實例Encodestring裡你將找不到字符串信息,找到的是亂碼。
六、實現軟件代碼校檢防止被修改,比如用CRC或者MD5進行自身代碼完整性檢測,實現方法:
先寫一個用於增加CRC特徵碼的軟件,假設定義為結尾部分:
Const CRC_HEAD = &H761226 '用於判斷是否添加了CRC校驗
Private Type stCRC
lHead As Long '驗證是否進行CRC校驗的標識
lCRC As Long 'CRC校驗值
End Type
Private Sub Command1_Click()
CRC_Exe App.Path & "\工程1.Exe"
End Sub
Private Function CRC_Exe(ByVal strExe As String) As Boolean
Dim hFile As Long
Dim lFileLen As Long
Dim sCRC As stCRC
Dim btExe() As Byte
On Error GoTo Err_CRC_Exe
lFileLen = FileLen(strExe)
hFile = FreeFile
Open strExe For Binary As #hFile '打開加密文件
Seek hFile, lFileLen - LenB(sCRC) + 1 '定位CRC標識域,位於Exe文件尾部文件
Get hFile, , sCRC
If sCRC.lHead = CRC_HEAD Then '如果已經添加了CRC校驗則退出,反之添加CRC校驗
MsgBox "已CRC驗證!"
Close #hFile
Exit Function
Else
Seek hFile, 1 '定位到文件首部
ReDim btExe(lFileLen - 1)
Get hFile, , btExe '按字節方式將Exe數據讀入數組
sCRC.lHead = CRC_HEAD '添加CRC驗證標識
sCRC.lCRC = Get_CRC(VarPtr(btExe(0)), lFileLen) '獲取Exe內容CRC值
Put hFile, , sCRC '將CRC校驗寫入Exe文件尾部
End If
Close #hFile
MsgBox "CRC校驗完成!"
CRC_Exe = True
Exit Function
Err_CRC_Exe:
If hFile <> 0 Then Close #hFile
CRC_Exe = False
MsgBox Err.Description
End Function
為程序本身增加CRC校檢代碼:
Const CRC_HEAD = &H761226 '用於判斷是否添加了CRC校驗
Private Type stCRC
lHead As Long '驗證是否進行CRC校驗的標識
lCRC As Long 'CRC校驗值
End Type
Private Sub Form_Load()
Dim hFile As Long
Dim sCRC As stCRC
Dim strExe As String
Dim lFileLen As Long
Dim btExe() As Byte
strExe = App.Path & "\" & App.EXEName & ".exe"
lFileLen = FileLen(strExe)
ReDim btExe(lFileLen - LenB(sCRC) - 1) As Byte '定義Exe字節緩存數組
hFile = FreeFile
Open strExe For Binary As #hFile '讀取Exe數據到數組
Get #hFile, , btExe
Get #hFile, , sCRC
Close #hFile
If sCRC.lHead = CRC_HEAD Then '如果程序添加了CRC驗證則驗證CRC值
If Get_CRC(VarPtr(btExe(0)), UBound(btExe) + 1) = lCRC Then '驗證Exe數據CRC和保存的CRC值是否相同
MsgBox "文件未修改!".
Else
MsgBox "文件被非法修改!"
End If
Else
MsgBox "文件尚未進行CRC驗證!" '檢查尾部是否已已經增加CRC校檢
End If
End Sub
其中的CRC模塊網上很多。附件中的CRC32就是實例,修改任何一處軟件都提示被修改。增加自校檢後建議再隨便加個殼,否則用UltraEdit直接就可以對比原文件查出CRC校驗值位置。
七、利用SEH進行反跟蹤,附件裡的SHE如果用SMARTCHECK調試的話就合自動退出,附上小樓的源碼:
Option Explicit
Private Declare Sub DebugBreak Lib "kernel32" ()
Private Sub Command1_Click()
On Error GoTo ERR_RaiseException
DebugBreak
DebugBreak
Exit Sub
ERR_RaiseException:
MsgBox "沒有發現調試器!"
End Sub
Sub SetHandler()
SetUnhandledExceptionFilter AddressOf NewExceptionHandler
End Sub
Sub RestoreHandler()
SetUnhandledExceptionFilter 0
End Sub
Private Sub Form_Load()
SetHandler
End Sub
Private Sub Form_Unload(Cancel As Integer)
RestoreHandler
End Sub
'SHE模塊略過。
除了上面的一些方法外,你還可以用一些密碼學知識增加難度,如果技術夠強,還可以借用內嵌彙編弄一些花指令和反調試SEH機制
______________________________________________________________
感謝laomms大俠給我們上了關於VB反調試的生動一課
5、 代碼混淆?加花,VM,選擇P-CODE方式等,都可以起到不錯的作用。
有些干脆搬出假目標(什麼「註冊正確」之類的提示,其實這個地方根本沒有正確的算法)甚至,你可以直接修改VB的開始語句:(主要是防VBExplorer靜態分析)
正常其實語句:
004018CC >/$ 68 7C1D4000 PUSH 1112.00401D7C
004018D1 |. E8 F0FFFFFF CALL <JMP.&MSVBVM60.#100>
這個明顯透露了VB程序,我們要做的是搬走這個位置
換句話說是把這個CALL移走,移到天南海角去……
004018D6 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018D8 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018DA |. 0000 ADD BYTE PTR DS:[EAX],AL
004018DC |. 3000 XOR BYTE PTR DS:[EAX],AL
004018DE |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E0 |. 3800 CMP BYTE PTR DS:[EAX],AL
004018E2 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E4 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E6 |. 0000 ADD BYTE PTR DS:[EAX],AL
004018E8 |. 3A28 CMP CH,BYTE PTR DS:[EAX]
004018EA |. 8A00 MOV AL,BYTE PTR DS:[EAX]
004018EC \. CF IRETD
修改後:───────────────────────》》》
004018CC > $ /E9 7FA50100 JMP 了凡第一.0041BE50
004018D1 |90 NOP
004018D2 |90 NOP
004018D3 |90 NOP
004018D4 |90 NOP
004018D5 |90 NOP
0041BE50 60 PUSHAD
0041BE51 0F31 RDTSC
經典時值,單步跟,不小心的話就會進入到錯誤地址
0041BE53 8BC8 MOV ECX,EAX
0041BE55 0F31 RDTSC
0041BE57 2BC1 SUB EAX,ECX
0041BE59 3D 00050000 CMP EAX,500
0041BE5E ^ 0F8F BAF9FFFF JG 了凡第一.0041B81E
0041BE64 83F8 00 CMP EAX,0
0041BE67 ^ 0F8C C7F9FFFF JL 了凡第一.0041B834
0041BE6D 61 POPAD
0041BE6E 68 68504000 PUSH 了凡第一.00405068
0041BE73 60 PUSHAD
0041BE74 0F31 RDTSC
0041BE76 8BC8 MOV ECX,EAX
0041BE78 0F31 RDTSC
0041BE7A 2BC1 SUB EAX,ECX
0041BE7C 3D 00050000 CMP EAX,500
0041BE81 ^ 0F8F ADF9FFFF JG 了凡第一.0041B834
0041BE87 83F8 00 CMP EAX,0
0041BE8A ^ 0F8C 8EF9FFFF JL 了凡第一.0041B81E
0041BE90 61 POPAD
0041BE91 E8 305AFEFF CALL <JMP.&MSVBVM60.#100>
搬到這裡來了
0041BE96 ^ 0F85 3A5AFEFF JNZ 了凡第一.004018D6
0041BE9C ^ 0F84 345AFEFF JE 了凡第一.004018D6
效果:
如果有時間,你可以自己設計得更恐怖點,東一句西一句,讓別人無法還原
5、 註冊算法系統
這個是軟件防破解的核心內容,推薦採用 陷阱+隱藏關鍵算法到異常裡面執行+不可逆算法+公開密碼體制+算法跟核心功能模塊代碼綁定,只有正確解密後的功能代碼才能發揮因該有的功能。
經常碰到VB的註冊算法,一般共享軟件不夠重視這塊內容,只是進行簡單的加加減減,或者XOR,或者凱撒+矩陣,結果好像跟輸入的用戶名完全不一樣,似乎 很安全,其實只要破解者跟蹤到了算法,按照那樣的計算的話,基本都是明碼比較,非常容易破解,甚至根本不用瞭解你的算法是什麼。
曾經看到過有共享軟件作者在網上說:「我用的機器碼是隨機生成,保存在註冊表裡的,但是就算這樣,別人用了什麼內存註冊機就把我的註冊碼算出來了,這到底怎麼回事?太受打擊了…」
市面上出現明碼比較的多是些新手寫的軟件,而且大部分是VB程序,為什麼?因為VB本身的算法支持不是很好,大都是跟用戶名的ASCII碼綁定。這些都是 弱點,容易被發現和跟蹤,別人只要用函數斷點斷MID,LEFT,RIGHT字符函數,那麼關於ASCII取用的基本都會被發現。
在這裡,我推薦採用浮點計算,除了算法本身不可逆,強度夠大,經得起窮舉外,還要小心謹慎的隱藏掉比較代碼,因為大都初學破解VB程序的菜鳥都喜歡斷 StrComp函數,大都可以直接斷到關鍵比較位置,如果你的良好的密碼系統即將為你帶來第一桶金,但是不幸你發現菜鳥斷個比較函數,然後爆破了,呵呵, 你的心情怎樣?更不要說是明碼比較的了。
浮點計算,你要把字符串轉為DOUBLE類型,指數運算和求余運算是比較好的算法,但是VB本身又不支持大數運算,單純的指數運算和求余很可能會發生溢出錯誤。
高次指數運算和求余可採用中國剩餘定理來計算,也可以看看我寫的代碼,也許你會有啟發:
首先是MOD函數必須自己寫一個,VB自帶的MOD範圍太小
Private Function Modx(x As Double, y As Double) As Double
Dim w As Double
w = Fix(x / y) * y
Modx = x - w
End Function
這樣就實現了稍大數在Vb裡的求余動作
Private Function Rsa(p As Double) As Double
Dim b As Double
Dim rsan As Double
rsan = 99221
Rsa = 1
For b = 1 To 15935
Rsa = Rsa * p
Rsa = Modx(Rsa, rsan)
Next b
End Function
通過每次都求余,剩下的繼續執行指數運算,下次再求余,就避免的誤差和溢出
我們看下:
3^6 mod 25 = 729 mod 25 =4
等同於:
3^6 mod 25 =(((((((((3 mod 25) * 3) mod 25) * 3) mod 25) * 3) mod 25)* 3) mod 25)* 3 mod 25 = 4
可發現計算結果一致,當然這個規律是可以證明的,通過這樣的計算法則,我們可以大量減少運算強度。你不想實驗下嗎?
上面給的程序其實就是RSA算法的應用,但是只能當作理論來用,實際上N太小了,非常容易被分解,呵呵,我們以此來學習RSA算法倒是沒問題,以後用RSA的時候,只要用第三方DLL即可,比方說《共享軟件加密算法庫》即有相關應用。
這裡的E為 15935
這裡的N為 99221
這裡的加密法則為 C = P^E mod N
如果N足夠大,一般要求512位以上(二進制)才能有些安全度,要破解RSA算法,只要分解N為兩個大質數的乘積即可……
可以用RSAtool來分解,速度很快……
分解後計算出D (解密密鑰)
則解密算法為 P = C^D mod N
這裡計算出D為48767
也就是說逆運算為:
'解密過程
Private Function Jiemi(c As Double) As Double
Dim b As Double
Dim rsan As Double
rsan = 99221
Jiemi = 1
For b = 1 To 48767
Jiemi = Jiemi * c
Jiemi = Modx(Jiemi, rsan)
Next b
End Function
當然,還有其他算法也很不錯,到時有空再後續系列裡詳細演示……
關於如何隱藏關鍵算法到異常處理中去?
這個一直是Vb裡很酷的技術,今天我把自己琢磨出的東西簡單說一下,到下期系列的時候再具體演示
VB裡的異常處理機制是 通過 On error goto 這個語句進行的,這個功能可大了,配合Resume Next、Resume 等語句,基本可以實現VB裡的高級隱藏技術
大致是先在算法裡嵌入迷惑性質的算法,通過一個可行的數值來產生一個指定的,不常見的錯誤,比方說可以除零,通過 On error goto 進行 異常捕獲,判斷Err.Number 是否等於某個數值(不同數值對應不同錯誤類型)或者故意製造出一個溢出來捕獲,捕獲後可以解密一兩句算法,然後通過 Resume Next回到原程序,繼續解密,又產生其他的錯誤,然後繼續解密真正的算法……
大家可以看看具體應用的例子
http://bbs.pediy.com/showthread.php?t=71741
http://bbs.pediy.com/showthread.php?t=72017
這些技術在VB共享軟件裡出現過,但是不常見,甚至可以說是稀少了;其作用真的很不錯,因為破解者在不知道你具體用意的前提下,一步步分析下來,分析的是 正常路徑,絕對不會產生我們指定的錯誤,到最後發現總是無法解密算法,他才意識到似乎掉到一個非同尋常的陷阱裡了,然後他回回頭往上看,不停的分析,哪裡 才是正確的JNZ或者JE等跳轉指令,殊不知若這樣分析,他永遠也分析不到我們指定的正確算法
說得形象點吧,就像打RPG類單機遊戲一樣,破解者一步步玩下來,沒出現任何差池,最後通關到了打BOSS的時候,發現不管怎麼打就是要死,打得都沒信心 了,為什麼如此?因為我們這個遊戲要求在玩第一關或者前面幾關的時候要觸發某些隱藏劇情,或者隱藏劇情的任務獎勵,獎勵的東西是什麼絕世神兵,可以秒殺 BOSS,或者要觸發多個不同的隱藏劇情,獲得一組或者好幾組密鑰等,參與最後的BOSS大決戰,少了這些參數,就算遊戲順利玩下來了,最後也是徒勞的
而這個隱藏的劇情不是發現了就可以進入隱藏劇情的,我們要求多少經驗值,或者多少攻擊力,或者以前做過些什麼,比方說是幫老奶奶過馬路,撿到一分錢交給警察叔叔等,而這些事情是普通玩家和破解者所不會做,或者做不到的
比方說我要實現一個異常除零錯誤,來捕獲流程進行注射關鍵代碼(正常情況下是不會發生錯誤,也就得不到注射了,所以總是要感冒,總是要生病,總是要死的,最後他甚至認為你的程序寫的有問題,算法無解等,其實是沒有做隱藏任務)
如:
On Error GoTo chuling
Dim a As Double
Dim b As Double
a = 110
b = "&H" & Left(MD5(Right(Text2.Text, 16)), 5
a = 110 / b Xor 123456789
If a = 123 Then
MsgBox "註冊碼錯誤", , "提示"
Else
If a = 0 Then MsgBox "註冊碼正確", , "提示"
提示 :想想,正常過來的畫,a怎麼可能等於0
End If
Exit Sub
chuling:
'關鍵核心算法
噢,原來是發生了一次異常,在流程裡注射了 「a = 0」這條指令
a = 0
Resume Next
這只是個簡單的實例,MD5是MD5算法,因其逆算要窮舉所以作為隱藏劇情的加密是可以的,你事先先計算好某個數字串的MD5,轉十進制後,算出其有效片段,將該有效片段作為XOR常量,即可。
不知道要發生異常的人,只會直接看下來,到時總也無法註冊成功,就算他知道要做隱藏任務,要使得XOR後為零,使得除數為零出錯,他也無法根據已知XOR常數去反推原始數字串,除非爆破,否則難以為繼。
算法還有很多,比方說離散數學原理等都可以用上去
如果算法還可以跟具體程序功能代碼解密掛鉤,那麼效果不是一般的好
現在是總的概要來說的,總結下:
VB 加密算法要求
1、不可逆及在不知道密鑰的情況下,只能加密,不能解密
2、算法隱藏很隱蔽的陷阱和隱藏劇情,及各類觸發條件,最好是一般人都接觸不到的觸發條件
3、儘量用公開算法
4、關鍵比較必須隱蔽
5、算法採用注射式,不同的註冊碼輸入驗證會激活不同的注射代碼
6、最重要的一點是:算法跟程序很緊密,甚至是程序的大段功能代碼都必須用註冊碼來解密後才能執行正確的功能,否則解密出來的代碼執行會出錯,這樣是為了防止爆破
7、最後是非明碼,用浮點計算
6、 加殼防脫殼
單單靠自己一個人的力量很多時候完成一套完整的安全的VB防破解體系是很困難的,我們要學會「站在巨人的肩膀上」,利用已有工具和加密思想,結合自己的創 新,使得程序更加堅固。大部分保護殼都有反調試,防修改,時間限制等功能,好好利用可以增加你的軟件的強度。VB程序一般加殼有三類:
第一, 壓縮殼,然後在程序代碼裡加入檢測文件大小等校驗手法,主要目的是方修改和方便網絡傳輸,減少體積
第二, 保護殼,常見的有ASProctect、Armadillo、EXECryptor、Themida等,有些兼容性不好,有些已經別解密者摸透,不推薦用 ASProctect ,研究的人太多了。
第三, 虛擬機保護,常見的有VMProtect,將關鍵代碼和算法過程及隱藏任務代碼虛擬執行,代碼急劇擴張,讓人跟得頭痛。VB本身的P-CODE方式也是類似於虛擬機了,但是被人研究的多了,破解只是時間和精力上的問題。
7、隱蔽性設計
結合異常機制和,反調試機制,界面上進行迷惑等手段,假算法,假註冊成功提示,通過給類手段,將真正的算法和功能模塊隱藏,執行的時候是正確的流程,但是一旦有調試器存在就會朝著令一個方向,甚至是很多方向發展,無窮無盡的輪迴……
比方說我畫出兩個一模一樣的註冊按鈕,當發現調試和異常問題後,就啟動令一個模樣一樣的按鈕,原先的按鈕就此屏蔽,那麼不管破解者如何努力,他們跟蹤的算法和事件永遠是替換後的按鈕對應的算法和事件,而其是根本無法註冊成功的
參考實例:
http://bbs.pediy.com/showthread.php?t=52623
http://bbs.pediy.com/showthread.php?t=52189
8、另闢蹊徑
常規的註冊方式是用戶名對應註冊碼,或者機器碼對應註冊碼,或者機器碼+用戶名+註冊碼,或者是單獨的註冊碼;有的是KEYFILE方式,有的是網路驗證(目前網絡驗證結合本地驗證已經越來越流行,越來越難搞了)
他們有一個共同點,那都是要輸入字符,或者是處理字符串,這樣一來,都有可能被快速找到斷點字符串處理的函數進行破解
我想能不能用新的註冊方式呢?還真的有,但是是概念性的,實用價值還不夠大
我想到的另闢蹊徑是利用語音麥克風,讓用戶讀出一段語音,由電腦自動判斷是否是對應的「咒語」,這樣就避免了字符處理,而且大家對聲音的處理都不清楚,也 就不好跟蹤了,軟件作者發售軟件到時候,可以根據對方的機器碼來計算出相應的讀音,進行錄音,然後傳給消費者,或者刻錄到光盤裡郵寄給消費者,消費者在每 次使用軟件的時候,都要跟著錄音念一遍咒語,即可被自動識別。
根據這個原理,我曾經完成了一個CM,下載地址如下:
http://bbs.pediy.com/showthread.php?t=61417
朗讀咒語的時候,請按住鍵盤的「Scroll Lock」鍵,朗讀完咒語後鬆開此鍵。系統助手(一個老頭)會自動通過語音告訴你結果如何。
現在公佈相關代碼:(其實核心就是微軟的語音識別技術)
MyAgent.Characters.Load "Merlin", DATAPATH & "Merlin.acs"
'獲取與CharacterID相對應的IAgentCtlCharacter變量
Set Merlin = MyAgent.Characters("Merlin")
'顯示/隱藏動畫人物
Merlin.LanguageID = &H409
Merlin.Show
Set GenieRequest1 = Merlin.MoveTo(880, 580) '450,300
Merlin.Speak Chr(87) & Chr(101) & Chr(108) & Chr(99) & Chr(111) & Chr(109) & Chr(101) & Chr(46)
Merlin.Speak Chr(80) & Chr(108) & Chr(101) & Chr(97) & Chr(115) & Chr(101) & Chr(32) & Chr(114) & Chr(101) & Chr(97) & Chr(100) & Chr(32) & Chr(121) & Chr(111) & Chr(117) & Chr(114) & Chr(32) & Chr(112) & Chr(97) & Chr(115) & Chr(115) & Chr(119) & Chr(111) & Chr(114) & Chr(100)
Static initialized As Boolean
'添加自定義命令
If Not initialized Then
Merlin.Commands.Add " ", " ", Chr(104) & Chr(101) & Chr(108) & Chr(108) & Chr(111), True, False
Merlin.Commands.Add " ", " ", Chr(99) & Chr(108) & Chr(111) & Chr(115) & Chr(101), True, False
Merlin.Commands.Add " ", "", Chr(83) & Chr(67) & Chr(71) & Right(zhucema, 6), True, False
initialized = True
End If
Merlin.Show
以上是加載語音空間,和電腦動畫助手的代碼
Private Sub MyAgent_Command(ByVal UserInput As Object)
Dim apack As Byte
Merlin.Play "read"
Select Case UserInput.Voice
這句是捕獲麥克風語音的代碼
Case Chr(104) & Chr(101) & Chr(108) & Chr(108) & Chr(111)
Merlin.Speak Chr(104) & Chr(101) & Chr(108) & Chr(108) & Chr(111) & Chr(44) & Chr(115) & Chr(105) & Chr(114) & Chr(46)
Merlin.Speak Chr(80) & Chr(108) & Chr(101) & Chr(97) & Chr(115) & Chr(101) & Chr(32) & Chr(114) & Chr(101) & Chr(97) & Chr(100) & Chr(32) & Chr(121) & Chr(111) & Chr(117) & Chr(114) & Chr(32) & Chr(112) & Chr(97) & Chr(115) & Chr(115) & Chr(119) & Chr(111) & Chr(114) & Chr(100)
Case Chr(99) & Chr(108) & Chr(111) & Chr(115) & Chr(101)
Merlin.Speak Chr(65) & Chr(114) & Chr(101) & Chr(32) & Chr(121) & Chr(111) & Chr(117) & Chr(32) & Chr(115) & Chr(117) & Chr(114) & Chr(101) & Chr(32) & Chr(116) & Chr(111) & Chr(32) & Chr(99) & Chr(108) & Chr(111) & Chr(115) & Chr(101) & Chr(63)
apack = MsgBox("你確定要退出本程序?", 4 + 32 + 0, "退出請示...")
If apack = 6 Then End
以上是相關處理了,具體代碼不便公開了
侷限:沒有麥克風和聲卡的電腦就不要完成註冊了
所謂另闢蹊徑指的就是使用別人都沒有用過的技術,我記得以前有個軟件作者(同時也是加密解密高手)將註冊信息隱藏到了JPG或者BMP圖片裡,註冊的時候 只要把相應的圖片選中即可(當然,其本質可能是得到裡面的數據,進行處理後還原附加在裡面的信息來完成註冊,一般人就算能逆出算法,那要怎樣修改圖片才能 使之即可以打開,又可以附帶信息呢?)
這個就是一個另闢蹊徑,想他人沒有想到的,做他人沒有思路做的東西
其本質還是要使用強壯的算法了,要不然也容易被逆
好了,第一講就到這裡吧,第一講是系統的粗略的講解下VB防破解設計的思路和相關技術信息。
如果有空,有時間,有精力,有能力,我將發佈第二篇,也就是《共享軟件防破解設計技術初探(二)》 所涉及的應該都是以上講的,我會的一些具體程序設計過程和完整的代碼和成品,手把手教你寫出自己滿意的,連自己在不源代碼的情況下也不能破解的軟件。
留言
張貼留言