欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

VB共享软件防破解设计技术初探(一)

程序员文章站 2022-06-23 09:45:53
作者:爱琴海[SCG]     一转眼又过去了一年,回头一看,今年我没发表过任何破解类文章,没有任何有价值的文章,名下的精华只是徒有其表的7个,也许太忙,也许读大学读得...
作者:爱琴海[SCG]
 
  一转眼又过去了一年,回头一看,今年我没发表过任何破解类文章,没有任何有价值的文章,名下的精华只是徒有其表的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挂接到程序的时候检测出来
 
 
以前看雪论坛里有篇文章,laomms大侠写的《使用VB进行反跟踪的技术点滴》一文,对我们学习VB的防破解设计是很有帮助的,为了大家观看方便,我将它引录到下文中:http://www.2cto.com/Article/201202/120343.html
———————————————————————————————————————
   跟其它语言相比,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) & 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
 
效果:
 
 VB共享软件防破解设计技术初探(一)
VB共享软件防破解设计技术初探(一)
 
 
 
 
如果有时间,你可以自己设计得更恐怖点,东一句西一句,让别人无法还原
 
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回到原程序,继续解密,又产生其他的错误,然后继续解密真正的算法……
 
这些技术在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防破解设计的思路和相关技术信息。
 
如果有空,有时间,有精力,有能力,我将发布第二篇,也就是《共享软件防破解设计技术初探(二)》 所涉及的应该都是以上讲的,我会的一些具体程序设计过程和完整的代码和成品,手把手教你写出自己满意的,连自己在不源代码的情况下也不能破解的软件。