vb步长等于0的时候还会vb运行环境吗

VB 共享软件防破解设计技术初探
标 题:VB 共享软件防破解设计技术初探(一)
作 者:爱琴海
时 间:<font color="#08-09-04 20:32 链 接:
VB&共享软件防破解设计技术初探(一)
××××××××××××××××××××××××××××××××××××××××××××××
其他文章快速链接:
VB&共享软件防破解设计技术初探(二)
VB&共享软件防破解设计技术初探(三)
××××××××××××××××××××××××××××××××××××××××××××××
作者:爱琴海[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加载;经典时值步长比较;异常处理技术(这个要当作重点)一些猛壳本身也有反调试功能。
还可以检测程序启动时间,一般调试器加载都是比正常启动程序要慢10倍左右
还可以检测内存分配,如果OD调试器启用了HIDEOD插件的话,那么程序获得的
内存分配上限和下限都是不一样的
还可以检测所有标题,枚举进程等
一般要加几个TIMER控件来时时反调试,这样可以在OD挂接到程序的时候检测出来
可参考实例:
以前看雪论坛里有篇文章,laomms大侠写的《使用VB进行反跟踪的技术点滴》一文,对我们学习VB的防破解设计是很有帮助的,为了大家观看方便,我将它引录到下文中:
原文地址:
&&&跟其它语言相比,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结构
&&&&&&&&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
&&&&&MsgBox&&ok&
&&&&&On&Error&Resume&Next
&&&&End&If
当然这个方法也不是万能的,在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
MsgBox&&没有被调试&
&&&&五、加密字符串。
比如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校验值
Private&Sub&Command1_Click()
&&&&CRC_Exe&App.Path&&&&\工程1.Exe&
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
&&&&&&&&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校验值
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
&&&&&&&&MsgBox&&文件尚未进行CRC验证!&&&&&&&'检查尾部是否已已经增加CRC校检
&&&&End&If&&&&
&&&其中的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
ERR_RaiseException:
&&&MsgBox&&没有发现调试器!&
Sub&SetHandler()
SetUnhandledExceptionFilter&AddressOf&NewExceptionHandler
Sub&RestoreHandler()
SetUnhandledExceptionFilter&0
Private&Sub&Form_Load()
SetHandler
Private&Sub&Form_Unload(Cancel&As&Integer)
RestoreHandler
'SHE模块略过。
除了上面的一些方法外,你还可以用一些密码学知识增加难度,如果技术够强,还可以借用内嵌汇编弄一些花指令和反调试SEH机制
______________________________________________________________
感谢laomms大侠给我们上了关于VB反调试的生动一课
5、&&代码混淆?加花,VM,选择P-CODE方式等,都可以起到不错的作用。
有些干脆搬出假目标(什么“注册正确”之类的提示,其实这个地方根本没有正确的算法)甚至,你可以直接修改VB的开始语句:(主要是防VBExplorer静态分析)
正常其实语句:
004018CC&&/$&&68&7C1D4000&&&PUSH&D7C
&&|.&&E8&F0FFFFFF&&&CALL&&JMP.&MSVBVM60.#100&&
这个明显透露了VB程序,我们要做的是搬走这个位置
换句话说是把这个CALL移走,移到天南海角去……
&&|.&&0000&&&&&&&&&&ADD&BYTE&PTR&DS:[EAX],AL
&&|.&&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
&&|.&&3800&&&&&&&&&&CMP&BYTE&PTR&DS:[EAX],AL
&&|.&&0000&&&&&&&&&&ADD&BYTE&PTR&DS:[EAX],AL
&&|.&&0000&&&&&&&&&&ADD&BYTE&PTR&DS:[EAX],AL
&&|.&&0000&&&&&&&&&&ADD&BYTE&PTR&DS:[EAX],AL
&&|.&&3A28&&&&&&&&&&CMP&CH,BYTE&PTR&DS:[EAX]
004018EA&&|.&&8A00&&&&&&&&&&MOV&AL,BYTE&PTR&DS:[EAX]
004018EC&&\.&&CF&&&&&&&&&&&&IRETD
修改后:———————————————————————》》》
&&004018CC&&&$&/E9&7FA50100&&&JMP&了凡第一.0041BE50
&&&&&|90&&&&&&&&&&&&NOP
&&&&&|90&&&&&&&&&&&&NOP
&&&&&|90&&&&&&&&&&&&NOP
&&&&&|90&&&&&&&&&&&&NOP
&&&&&|90&&&&&&&&&&&&NOP
0041BE50&&&&60&&&&&&&&&&&&&&PUSHAD
0041BE51&&&&0F31&&&&&&&&&&&&RDTSC
经典时值,单步跟,不小心的话就会进入到错误地址
0041BE53&&&&8BC8&&&&&&&&&&&&MOV&ECX,EAX
0041BE55&&&&0F31&&&&&&&&&&&&RDTSC
0041BE57&&&&2BC1&&&&&&&&&&&&SUB&EAX,ECX
0041BE59&&&&3D&&&&&&CMP&EAX,500
0041BE5E&&^&0F8F&BAF9FFFF&&&JG&了凡第一.0041B81E
0041BE64&&&&83F8&00&&&&&&&&&CMP&EAX,0
0041BE67&&^&0F8C&C7F9FFFF&&&JL&了凡第一.
0041BE6D&&&&61&&&&&&&&&&&&&&POPAD
0041BE6E&&&&68&&&&&&PUSH&了凡第一.
0041BE73&&&&60&&&&&&&&&&&&&&PUSHAD
0041BE74&&&&0F31&&&&&&&&&&&&RDTSC
0041BE76&&&&8BC8&&&&&&&&&&&&MOV&ECX,EAX
0041BE78&&&&0F31&&&&&&&&&&&&RDTSC
0041BE7A&&&&2BC1&&&&&&&&&&&&SUB&EAX,ECX
0041BE7C&&&&3D&&&&&&CMP&EAX,500
0041BE81&&^&0F8F&ADF9FFFF&&&JG&了凡第一.
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&了凡第一.
0041BE9C&&^&0F84&345AFEFF&&&JE&了凡第一.
如果有时间,你可以自己设计得更恐怖点,东一句西一句,让别人无法还原
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
For&b&=&1&To&15935
Rsa&=&Rsa&*&p
Rsa&=&Modx(Rsa,&rsan)
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
For&b&=&1&To&48767
Jiemi&=&Jiemi&*&c
Jiemi&=&Modx(Jiemi,&rsan)
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
b&=&&&H&&&&Left(MD5(Right(Text2.Text,&16)),&5
a&=&110&/&b&Xor&
If&a&=&123&Then
MsgBox&&注册码错误&,&,&&提示&
If&a&=&0&Then&MsgBox&&注册码正确&,&,&&提示&
提示&:想想,正常过来的画,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、隐蔽性设计
结合异常机制和,反调试机制,界面上进行迷惑等手段,假算法,假注册成功提示,通过给类手段,将真正的算法和功能模块隐藏,执行的时候是正确的流程,但是一旦有调试器存在就会朝着令一个方向,甚至是很多方向发展,无穷无尽的轮回……
比方说我画出两个一模一样的注册按钮,当发现调试和异常问题后,就启动令一个模样一样的按钮,原先的按钮就此屏蔽,那么不管破解者如何努力,他们跟踪的算法和事件永远是替换后的按钮对应的算法和事件,而其是根本无法注册成功的
参考实例:
8、另辟蹊径
常规的注册方式是用户名对应注册码,或者机器码对应注册码,或者机器码+用户名+注册码,或者是单独的注册码;有的是KEYFILE方式,有的是网路验证(目前网络验证结合本地验证已经越来越流行,越来越难搞了)
他们有一个共同点,那都是要输入字符,或者是处理字符串,这样一来,都有可能被快速找到断点字符串处理的函数进行破解
我想能不能用新的注册方式呢?还真的有,但是是概念性的,实用价值还不够大
我想到的另辟蹊径是利用语音麦克风,让用户读出一段语音,由电脑自动判断是否是对应的“咒语”,这样就避免了字符处理,而且大家对声音的处理都不清楚,也就不好跟踪了,软件作者发售软件到时候,可以根据对方的机器码来计算出相应的读音,进行录音,然后传给消费者,或者刻录到光盘里邮寄给消费者,消费者在每次使用软件的时候,都要跟着录音念一遍咒语,即可被自动识别。
根据这个原理,我曾经完成了一个CM,下载地址如下:
朗读咒语的时候,请按住键盘的“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
mands.Add&&&&,&&&&,&Chr(104)&&&Chr(101)&&&Chr(108)&&&Chr(108)&&&Chr(111),&True,&False
mands.Add&&&&&,&&&&,&Chr(99)&&&Chr(108)&&&Chr(111)&&&Chr(115)&&&Chr(101),&True,&False
mands.Add&&&&&&&,&&&,&Chr(83)&&&Chr(67)&&&Chr(71)&&&Right(zhucema,&6),&True,&False
initialized&=&True
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防破解设计的思路和相关技术信息。
如果有空,有时间,有精力,有能力,我将发布第二篇,也就是《共享软件防破解设计技术初探(二)》&所涉及的应该都是以上讲的,我会的一些具体程序设计过程和完整的代码和成品,手把手教你写出自己满意的,连自己在不源代码的情况下也不能破解的软件。
作者:爱琴海[SCG]&&(转载请保留该信息)
标 题:VB 共享软件防破解设计技术初探(二)
作 者:爱琴海
时 间:<font color="#08-09-07 02:22 链 接:
VB&共享软件防破解设计技术初探(二)
××××××××××××××××××××××××××××××××××××××××××××××
其他文章快速链接:
VB&共享软件防破解设计技术初探(一)
VB&共享软件防破解设计技术初探(三)
××××××××××××××××××××××××××××××××××××××××××××××
作者:爱琴海[SCG]&&(转载请保留该信息)
&&上个篇我粗略的讲了以下几个内容:
1、&&文件完整性,防止被非法修改
2、&&运行时的校验,防止被LOADER
3、&&反调试,防止动态跟踪和挂接
4、&&防静态反汇编分析
5、&&注册码系统(算法部分,核心内容)
6、&&加壳防脱壳
7、&&隐蔽性设计
8、&&另辟蹊径
列表在这里是为了提醒初学VB发布共享软件的朋友,在设计VB防破解的时候,不要出现“水桶效应”,也就是说,设计如水桶,任何一个角落缺失都将导致无法全部盛满水。
&&而这个水桶的捆圈恐怕就是保护文件完整性,防止修改了。
&&周末了,今天有点时间。赶快写好,等下吃晚饭,练练琴,然后陪陪女朋友。
&&接下去,我们将开始具体至微的讲解第1、2两个内容,剩下的老规矩:日后有空,有时间,有精力,有能力的话接着写。
1、&&&&文件完整性,可采用CRC32或者MD5或者哈希算法等,计算出文件的加密值,在适当的时候进行对比,判断文件被修改与否。当然那也可以加猛壳来防止文件非法修改。还有简单点的检查文件最后修改时间,看看是否是你自己设置好的时间,如果不是,则很有可能被修改过;也可以检测文件大小,往往压缩壳被脱掉后,文件的大小会增加;保护壳被脱掉后,文件大小会变小,我们可以根据这个设置好临界值来检测有没有被脱壳。常用的还有故意设计好关于算法方面的陷阱,如果是破解者会主动掉进你的陷阱,而事实上,这个跳转除非爆破,不然在算法上是永远也无法到达的,这样就检出破解者在修改程序流程。你可以无声无息的程序死掉,不要直接退出,不然会被追踪到退出函数。
还有内存镜像校验,是为了防止普通的修改内存和普通断点问题。
我们就具体演示3种VB程序的完整性校验设计。
第一种是VB的CRC32自校验设计,包含过程,代码和所有工程文件及演示;
第二种是VB程序的时间检测法则,包括过程,代码和所有工程文件及演示;
第三种是VB程序的文件大小检测法则,包括过程,代码和所有工程文件及演示。
其实还有些检测的办法,但是原理跟我们即将大曝光的三种办法差不多,都是衍生的吧。
第二章&&第一讲
VB的CRC32自校验设计
来来来…大家跟我一起做运动,抖抖手啊,抖抖脚啊,做做深呼吸,本讲将会有点长,力求做到简单明了,容易明白,学完马上上手,学会应用的要求,我会具体点讲,不会像某些高人敝帚自珍,当然如果有错误的地方还请大家多多帮忙纠正,谢谢
首先来简单复习下何谓CRC32
CRC校验实用程序库&在数据存储和数据通讯领域,为了保证数据的正确,就不得不采用检错的手段。在诸多检错手段中,CRC是最著名的一种。CRC的全称是循环冗余校验,其特点是:检错能力极强,开销小,易于用编码器及检测电路实现。从其检错能力来看,它所不能发现的错误的几率仅为0.0047%以下。
有查表和计算法,我们可以在程序中自动生成码表来查表计算,方便和快速
为了快速带过原理笔墨,节省点时间吃饭,我把网路上的一篇介绍《探究CRC32算法实现原理》引述过来,原文地址:
以下是引用部分
基于不重造轮子的原则,本文尽量不涉及网络上遍地都是的资料。
What's&CRC&?
简而言之,CRC是一个数值。该数值被用于校验数据的正确性。CRC数值简单地说就是通过让你需要做
处理的数据除以一个常数而得到的余数。当你得到这个数值后你可以将这个数值附加到你的数据后,
当数据被传送到其他地方后,取出原始数据(可能在传送过程中被破坏)与附加的CRC数值,然后将这里
的原始数据除以之前那个常数(约定好的)然后得到新的CRC值。比较两个CRC值是否相等即可确认你的
数据是否在传送过程中出现错误。
那么,如何让你的数据除以一个常数?方法是对你的数据进行必要的编码处理,逐字节处理成数字。
那么这个常数是什么?你不必关注它是什么,也不需要关注它是如何获得的。当你真的要动手写一个
CRC的实现算法时,我可以告诉你,CRC的理论学家会告诉你。不同长度的常数对应着不同的CRC实现算法。
当这个常数为32位时,也就是这里所说的CRC32。
以上内容你不必全部理解,因为你需要查阅其他资料来获取CRC完整的理论介绍。
The&mathematics&behind&CRC&?
很多教科书会把CRC与多项式关联起来。这里的多项式指的是系数为0或1的式子,例如:
a0&+&a1*x&+&a2*x^2&+&...&+&an*x^n。其中a0,&a1,&...,&an要么为0要么为1。我们并不关注x取什么值。
(如果你要关注,你可以简单地认为x为2)&这里把a0,&a1,&...,&an的值取出来排列起来,就可以表示比特
流。例如&1&+&x&+&x^3所表示的比特流就为:1101。部分资料会将这个顺序颠倒,这个很正常。
什么是生成多项式?
所谓的生成多项式,就是上面我所说的常数。注意,在这里,一个多项式就表示了一个比特流,也就是一堆
1、0,组合起来最终就是一个数值。例如CRC32算法中,这个生成多项式为:
c(x)&=&1&+&x&+&x^2&+&x^4&+&x^5&+&x^7&+&x^8&+&x^10&+&x^11&+&x^12&+&x^16&+&x^22&+&x^23&+&x^26&+&x^32。
其对应的数字就为:(x^32在实际计算时隐含给出,因此这里没有包含它
的系数),也就是0xEDB88320(多项式对应的数字可能颠倒,颠倒后得到的是0x04C11DB7,其实也是正确的)。
由此可以看出,CRC值也可以看成我们的数据除以一个生成多项式而得到的余数。
如何做这个除法?
套用大部分教科书给出的计算方法,因为任何数据都可以被处理成纯数字,因此,在某种程度上说,我们可以
直接开始这个除法。尽管事实上这并不是标准的除法。例如,我们的数据为(方便起见我直接给二进制
表示了,从这里也可以看出,CRC是按bit进行计算的),给定的生成多项式(对应的值)为10011。通常的教科书
会告诉我们在进行这个除法前,会把我们的数据左移几位(生成多项式位数-1位),从而可以容纳将来计算得到
的CRC值(我上面所说的将CRC值附加到原始数据后)。但是为什么要这样做?我也不知道。(不知道的东西不能含糊
而过)那么,除法就为:
&&&&&&&&&&&&
&&&&&&&_______________
10011&)&00&附加了几个零的新数据
&&&&&&&&10011.........&这里的减法(希望你不至于忘掉小学算术)是一个异或操作
&&&&&&&&-----.........
&&&&&&&&&10011........
&&&&&&&&&10011........
&&&&&&&&&-----........
&&&&&&&&&&00001.......&逐bit计算
&&&&&&&&&&00000.......
&&&&&&&&&&-----.......
&&&&&&&&&&&00010......
&&&&&&&&&&&00000......
&&&&&&&&&&&-----......
&&&&&&&&&&&&00101.....
&&&&&&&&&&&&00000.....
&&&&&&&&&&&&-----.....
&&&&&&&&&&&&&01011....
&&&&&&&&&&&&&00000....
&&&&&&&&&&&&&-----....
&&&&&&&&&&&&&&10110...
&&&&&&&&&&&&&&10011...
&&&&&&&&&&&&&&-----...
&&&&&&&&&&&&&&&01010..
&&&&&&&&&&&&&&&00000..
&&&&&&&&&&&&&&&-----..
&&&&&&&&&&&&&&&&10100.
&&&&&&&&&&&&&&&&10011.
&&&&&&&&&&&&&&&&-----.
&&&&&&&&&&&&&&&&&01110
&&&&&&&&&&&&&&&&&00000
&&&&&&&&&&&&&&&&&-----
&&&&&&&&&&&&&&&&&&1110&=&这个余数也就是所谓的CRC值,通常又被称为校验值。
希望进行到这里,你可以获取更多关于CRC的感性认识。而我们所要做的,也就是实现一个CRC的计算算法。
说白了,就是提供一个程序,给定一段数据,以及一个生成多项式(对于CRC32算法而言该值固定),然后
计算得出上面的1110余数。
The&simplest&algorithm.
最简单的实现算法,是一种模拟算法。我们模拟上面的除法过程,遵从网上一份比较全面的资料,我们设定
一个变量register。我们逐bit地将我们的数据放到register中。然后判断register最高位是否为1,如果是
则与生成多项式异或操作,否则继续处理。这个过程简单地模拟了上述除法过程:
引用到此结束
看来大家选择CRC32作为数据校验是有原因的,速度快,代价小,检错能力比较大。VB软件作者对CRC32有个认识就好了。
我们编写VB的CRC32自校验程序思路如下:
1、&&计算出目标文件除掉末尾8字节后的所有数据的CRC32值
2、&&将上面计算出来的结果储存在目标程序的末尾8个字节里
3、&&主体程序内置计算自身除掉末尾8字节后的所有数据的CRC32值的功能代码
4、&&主体程序读取末尾8字节内容与计算的CRC32值比较,不一致说明被修改
由1、2点我们发现,如果手动来添加CRC32值将是件麻烦的事情,所以一般我们都会写一个具备计算要求的CRC32值,及把该值添加到目标程序指定位置的程序,帮我们节省时间和体力。
为了方便记忆和理解,在这里我将它命名为VB-CRC32&注射器,顾名思义,即将计算出来的CRC32注射到目标程序里。
那么执行自校验的程序我称它为VB-CRC32&主体程序。大家记住了哦,下面开始先设计VB-CRC32注射程序。
请跟我一起来:
打开VB6.0&新建工程
新建类模块,名字改为“clsCRC”,别告诉我你不会改名,当然是在“属性窗口”改的。
将如下类模块代码复制到clsCRC类模块里去:(或者直接从我发布的附件来条用该类模块)
注意:类模块后缀名是CLS,请刚接触VB的同学注意,不要跟模块搞混了。
我是代码起始线
Option&Explicit
Public&Enum&CRCAlgorithms
Private&m_Algorithm&As&Boolean
Private&m_CRC16&As&Long
Private&m_CRC16Asm()&As&Byte
Private&m_CRC16Init&As&Boolean
Private&m_CRC16Table(0&To&255)&As&Long
Private&m_CRC32&As&Long
Private&m_CRC32Asm()&As&Byte
Private&m_CRC32Init&As&Boolean
Private&m_CRC32Table(0&To&255)&As&Long
Private&Declare&Function&CallWindowProc&Lib&&user32&&Alias&&CallWindowProcA&&(ByVal&lpPrevWndFunc&As&Long,&ByVal&hWnd&As&Long,&ByVal&Msg&As&Long,&ByVal&wParam&As&Long,&ByVal&lParam&As&Long)&As&Long
'此函数作用在这里是内联汇编之用
Public&Function&AddBytes(ByteArray()&As&Byte)&As&Variant
&&Dim&ByteSize&As&Long
&&&&'异常处理
&&On&Local&Error&GoTo&NoData
&&'计算大小
&&ByteSize&=&UBound(ByteArray)&-&LBound(ByteArray)&+&1
&&&&'异常处理
&&On&Local&Error&GoTo&0
&&'内联汇编提高处理速度
&&Select&Case&m_Algorithm
&&Case&CRC16
&&&&Call&CallWindowProc(VarPtr(m_CRC16Asm(0)),&VarPtr(m_CRC16),&VarPtr(ByteArray(LBound(ByteArray))),&VarPtr(m_CRC16Table(0)),&ByteSize)
&&Case&CRC32
&&&&Call&CallWindowProc(VarPtr(m_CRC32Asm(0)),&VarPtr(m_CRC32),&VarPtr(ByteArray(LBound(ByteArray))),&VarPtr(m_CRC32Table(0)),&ByteSize)
&&End&Select
&&'返回新值
&&AddBytes&=&Value
End&Function
Public&Function&AddString(Text&As&String)&As&Variant
&&'将字符转为数组,以便套入函数计算CRC
&&AddString&=&AddBytes(StrConv(Text,&vbFromUnicode))
End&Function
Public&Property&Let&Algorithm(New_Value&As&CRCAlgorithms)
&&'选择新算法
&&m_Algorithm&=&New_Value
&&'确定已经初始化新算法
&&Select&Case&m_Algorithm
&&Case&CRC16
&&&&If&(Not&m_CRC16Init)&Then&Call&InitializeCRC16
&&Case&CRC32
&&&&If&(Not&m_CRC32Init)&Then&Call&InitializeCRC32
&&End&Select
&&Call&Clear
End&Property
Public&Property&Get&Algorithm()&As&CRCAlgorithms
&&Algorithm&=&m_Algorithm
End&Property
Public&Function&CalculateBytes(ByteArray()&As&Byte)&As&Variant
&&'重置CRC计算
&&Call&Clear
&&CalculateBytes&=&AddBytes(ByteArray)
End&Function
Public&Function&CalculateFile(Filename&As&String)&As&Variant
&&Dim&Filenr&As&Integer
&&Dim&ByteArray()&As&Byte
&&'检测文件是否包换数据
&&If&(FileLen(Filename)&=&0)&Then&Exit&Function
&&'二进制模式读取文件储存到数组里
&&Filenr&=&FreeFile
&&Open&Filename&For&Binary&As&#Filenr
&&ReDim&ByteArray(0&To&LOF(Filenr)&-&9)
&&Get&#Filenr,&,&ByteArray()
&&Close&#Filenr
&&'将该数组交给处理函数计算出CRC
&&CalculateFile&=&CalculateBytes(ByteArray)
End&Function
Public&Property&Get&Value()&As&Variant
&&Select&Case&m_Algorithm
&&Case&CRC16
&&&&Value&=&(m_CRC16&And&65535)
&&Case&CRC32
&&&&Value&=&(Not&m_CRC32)
&&End&Select
End&Property
Public&Property&Let&Value(New_Value&As&Variant)
&&Select&Case&m_Algorithm
&&Case&CRC16
&&&&m_CRC16&=&New_Value
&&Case&CRC32
&&&&m_CRC32&=&New_Value
&&End&Select
End&Property
Private&Sub&InitializeCRC16()
&&Dim&i&As&Long
&&Dim&j&As&Long
&&Dim&k&As&Long
&&Dim&CRC&As&Long
&&Dim&sASM&As&String
&&'创建表格
&&For&i&=&0&To&255
&&&&k&=&i&*&256
&&&&CRC&=&0
&&&&For&j&=&0&To&7
&&&&&&If&(((CRC&Xor&k)&And&32768)&=&32768)&Then
&&&&&&&&CRC&=&(CRC&*&2)&Xor&&H1021
&&&&&&Else
&&&&&&&&CRC&=&(CRC&*&2)
&&&&&&End&If
&&&&&&k&=&k&*&2
&&&&m_CRC16Table(i)&=&CRC&'(CRC&And&65535)
&&'内联汇编预处理
&&sASM&=&&88B008B750C8B7D108B4DE30EC5EF25FFFFE5F89EC5DC21000&
&&ReDim&m_CRC16Asm(0&To&Len(sASM)&\&2&-&1)
&&For&i&=&1&To&Len(sASM)&Step&2
&&&&m_CRC16Asm(i&\&2)&=&Val(&&H&&&&Mid$(sASM,&i,&2))
&&m_CRC16Init&=&True
Public&Sub&Clear()
&&m_CRC16&=&0
&&m_CRC32&=&&HFFFFFFFF
Private&Sub&InitializeCRC32()
&&Dim&i&As&Long
&&Dim&sASM&As&String
&&m_CRC32Table(0)&=&&H0
&&m_CRC32Table(1)&=&&H
&&m_CRC32Table(2)&=&&HEE0E612C
&&m_CRC32Table(3)&=&&H990951BA
&&m_CRC32Table(4)&=&&H76DC419
&&m_CRC32Table(5)&=&&H706AF48F
&&m_CRC32Table(6)&=&&HE963A535
&&m_CRC32Table(7)&=&&H9E6495A3
&&m_CRC32Table(8)&=&&HEDB8832
&&m_CRC32Table(9)&=&&H79DCB8A4
&&m_CRC32Table(10)&=&&HE0D5E91E
&&m_CRC32Table(11)&=&&H97D2D988
&&m_CRC32Table(12)&=&&H9B64C2B
&&m_CRC32Table(13)&=&&H7EB17CBD
&&m_CRC32Table(14)&=&&HE7B82D07
&&m_CRC32Table(15)&=&&H90BF1D91
&&m_CRC32Table(16)&=&&H1DB71064
&&m_CRC32Table(17)&=&&H6AB020F2
&&m_CRC32Table(18)&=&&HF3B97148
&&m_CRC32Table(19)&=&&H84BE41DE
&&m_CRC32Table(20)&=&&H1ADAD47D
&&m_CRC32Table(21)&=&&H6DDDE4EB
&&m_CRC32Table(22)&=&&HF4D4B551
&&m_CRC32Table(23)&=&&H83D385C7
&&m_CRC32Table(24)&=&&H136C9856
&&m_CRC32Table(25)&=&&H646BA8C0
&&m_CRC32Table(26)&=&&HFD62F97A
&&m_CRC32Table(27)&=&&H8A65C9EC
&&m_CRC32Table(28)&=&&H14015C4F
&&m_CRC32Table(29)&=&&H63066CD9
&&m_CRC32Table(30)&=&&HFA0F3D63
&&m_CRC32Table(31)&=&&H8D080DF5
&&m_CRC32Table(32)&=&&H3B6E20C8
&&m_CRC32Table(33)&=&&H4C69105E
&&m_CRC32Table(34)&=&&HD56041E4
&&m_CRC32Table(35)&=&&HA2677172
&&m_CRC32Table(36)&=&&H3C03E4D1
&&m_CRC32Table(37)&=&&H4B04D447
&&m_CRC32Table(38)&=&&HD20D85FD
&&m_CRC32Table(39)&=&&HA50AB56B
&&m_CRC32Table(40)&=&&H35B5A8FA
&&m_CRC32Table(41)&=&&H42B2986C
&&m_CRC32Table(42)&=&&HDBBBC9D6
&&m_CRC32Table(43)&=&&HACBCF940
&&m_CRC32Table(44)&=&&H32D86CE3
&&m_CRC32Table(45)&=&&H45DF5C75
&&m_CRC32Table(46)&=&&HDCD60DCF
&&m_CRC32Table(47)&=&&HABD13D59
&&m_CRC32Table(48)&=&&H26D930AC
&&m_CRC32Table(49)&=&&H51DE003A
&&m_CRC32Table(50)&=&&HC8D75180
&&m_CRC32Table(51)&=&&HBFD06116
&&m_CRC32Table(52)&=&&H21B4F4B5
&&m_CRC32Table(53)&=&&H56B3C423
&&m_CRC32Table(54)&=&&HCFBA9599
&&m_CRC32Table(55)&=&&HB8BDA50F
&&m_CRC32Table(56)&=&&H2802B89E
&&m_CRC32Table(57)&=&&H5F058808
&&m_CRC32Table(58)&=&&HC60CD9B2
&&m_CRC32Table(59)&=&&HB10BE924
&&m_CRC32Table(60)&=&&H2F6F7C87
&&m_CRC32Table(61)&=&&H58684C11
&&m_CRC32Table(62)&=&&HC1611DAB
&&m_CRC32Table(63)&=&&HB6662D3D
&&m_CRC32Table(64)&=&&H76DC4190
&&m_CRC32Table(65)&=&&H1DB7106
&&m_CRC32Table(66)&=&&H98D220BC
&&m_CRC32Table(67)&=&&HEFD5102A
&&m_CRC32Table(68)&=&&H71B18589
&&m_CRC32Table(69)&=&&H6B6B51F
&&m_CRC32Table(70)&=&&H9FBFE4A5
&&m_CRC32Table(71)&=&&HE8B8D433
&&m_CRC32Table(72)&=&&H
&&m_CRC32Table(73)&=&&HF00F934
&&m_CRC32Table(74)&=&&H9609A88E
&&m_CRC32Table(75)&=&&HE10E9818
&&m_CRC32Table(76)&=&&H7F6A0DBB
&&m_CRC32Table(77)&=&&H86D3D2D
&&m_CRC32Table(78)&=&&H91646C97
&&m_CRC32Table(79)&=&&HE6635C01
&&m_CRC32Table(80)&=&&H6B6B51F4
&&m_CRC32Table(81)&=&&H1C6C6162
&&m_CRC32Table(82)&=&&H
&&m_CRC32Table(83)&=&&HF262004E
&&m_CRC32Table(84)&=&&H6C0695ED
&&m_CRC32Table(85)&=&&H1B01A57B
&&m_CRC32Table(86)&=&&H
&&m_CRC32Table(87)&=&&HF50FC457
&&m_CRC32Table(88)&=&&H65B0D9C6
&&m_CRC32Table(89)&=&&H12B7E950
&&m_CRC32Table(90)&=&&H8BBEB8EA
&&m_CRC32Table(91)&=&&HFCB9887C
&&m_CRC32Table(92)&=&&H62DD1DDF
&&m_CRC32Table(93)&=&&H15DA2D49
&&m_CRC32Table(94)&=&&H8CD37CF3
&&m_CRC32Table(95)&=&&HFBD44C65
&&m_CRC32Table(96)&=&&H4DB26158
&&m_CRC32Table(97)&=&&H3AB551CE
&&m_CRC32Table(98)&=&&HA3BC0074
&&m_CRC32Table(99)&=&&HD4BB30E2
&&m_CRC32Table(100)&=&&H4ADFA541
&&m_CRC32Table(101)&=&&H3DD895D7
&&m_CRC32Table(102)&=&&HA4D1C46D
&&m_CRC32Table(103)&=&&HD3D6F4FB
&&m_CRC32Table(104)&=&&H4369E96A
&&m_CRC32Table(105)&=&&H346ED9FC
&&m_CRC32Table(106)&=&&HAD678846
&&m_CRC32Table(107)&=&&HDA60B8D0
&&m_CRC32Table(108)&=&&H44042D73
&&m_CRC32Table(109)&=&&H33031DE5
&&m_CRC32Table(110)&=&&HAA0A4C5F
&&m_CRC32Table(111)&=&&HDD0D7CC9
&&m_CRC32Table(112)&=&&H5005713C
&&m_CRC32Table(113)&=&&H270241AA
&&m_CRC32Table(114)&=&&HBE0B1010
&&m_CRC32Table(115)&=&&HC90C2086
&&m_CRC32Table(116)&=&&H
&&m_CRC32Table(117)&=&&H206F85B3
&&m_CRC32Table(118)&=&&HB966D409
&&m_CRC32Table(119)&=&&HCE61E49F
&&m_CRC32Table(120)&=&&H5EDEF90E
&&m_CRC32Table(121)&=&&H29D9C998
&&m_CRC32Table(122)&=&&HB0D09822
&&m_CRC32Table(123)&=&&HC7D7A8B4
&&m_CRC32Table(124)&=&&H59B33D17
&&m_CRC32Table(125)&=&&H2EB40D81
&&m_CRC32Table(126)&=&&HB7BD5C3B
&&m_CRC32Table(127)&=&&HC0BA6CAD
&&m_CRC32Table(128)&=&&HEDB88320
&&m_CRC32Table(129)&=&&H9ABFB3B6
&&m_CRC32Table(130)&=&&H3B6E20C
&&m_CRC32Table(131)&=&&H74B1D29A
&&m_CRC32Table(132)&=&&HEAD54739
&&m_CRC32Table(133)&=&&H9DD277AF
&&m_CRC32Table(134)&=&&H4DB2615
&&m_CRC32Table(135)&=&&H73DC1683
&&m_CRC32Table(136)&=&&HE3630B12
&&m_CRC32Table(137)&=&&H94643B84
&&m_CRC32Table(138)&=&&HD6D6A3E
&&m_CRC32Table(139)&=&&H7A6A5AA8
&&m_CRC32Table(140)&=&&HE40ECF0B
&&m_CRC32Table(141)&=&&H9309FF9D
&&m_CRC32Table(142)&=&&HA00AE27
&&m_CRC32Table(143)&=&&H7D079EB1
&&m_CRC32Table(144)&=&&HF00F9344
&&m_CRC32Table(145)&=&&H
&&m_CRC32Table(146)&=&&H1E01F268
&&m_CRC32Table(147)&=&&H6906C2FE
&&m_CRC32Table(148)&=&&HF762575D
&&m_CRC32Table(149)&=&&H806567CB
&&m_CRC32Table(150)&=&&H196C3671
&&m_CRC32Table(151)&=&&H6E6B06E7
&&m_CRC32Table(152)&=&&HFED41B76
&&m_CRC32Table(153)&=&&H89D32BE0
&&m_CRC32Table(154)&=&&H10DA7A5A
&&m_CRC32Table(155)&=&&H67DD4ACC
&&m_CRC32Table(156)&=&&HF9B9DF6F
&&m_CRC32Table(157)&=&&H8EBEEFF9
&&m_CRC32Table(158)&=&&H17B7BE43
&&m_CRC32Table(159)&=&&H60B08ED5
&&m_CRC32Table(160)&=&&HD6D6A3E8
&&m_CRC32Table(161)&=&&HA1D1937E
&&m_CRC32Table(162)&=&&H38D8C2C4
&&m_CRC32Table(163)&=&&H4FDFF252
&&m_CRC32Table(164)&=&&HD1BB67F1
&&m_CRC32Table(165)&=&&HA6BC5767
&&m_CRC32Table(166)&=&&H3FB506DD
&&m_CRC32Table(167)&=&&H48B2364B
&&m_CRC32Table(168)&=&&HD80D2BDA
&&m_CRC32Table(169)&=&&HAF0A1B4C
&&m_CRC32Table(170)&=&&H36034AF6
&&m_CRC32Table(171)&=&&H41047A60
&&m_CRC32Table(172)&=&&HDF60EFC3
&&m_CRC32Table(173)&=&&HA867DF55
&&m_CRC32Table(174)&=&&H316E8EEF
&&m_CRC32Table(175)&=&&H4669BE79
&&m_CRC32Table(176)&=&&HCB61B38C
&&m_CRC32Table(177)&=&&HBC66831A
&&m_CRC32Table(178)&=&&H256FD2A0
&&m_CRC32Table(179)&=&&H
&&m_CRC32Table(180)&=&&HCC0C7795
&&m_CRC32Table(181)&=&&HBB0B4703
&&m_CRC32Table(182)&=&&H
&&m_CRC32Table(183)&=&&H5505262F
&&m_CRC32Table(184)&=&&HC5BA3BBE
&&m_CRC32Table(185)&=&&HB2BD0B28
&&m_CRC32Table(186)&=&&H2BB45A92
&&m_CRC32Table(187)&=&&H5CB36A04
&&m_CRC32Table(188)&=&&HC2D7FFA7
&&m_CRC32Table(189)&=&&HB5D0CF31
&&m_CRC32Table(190)&=&&H2CD99E8B
&&m_CRC32Table(191)&=&&H5BDEAE1D
&&m_CRC32Table(192)&=&&H9B64C2B0
&&m_CRC32Table(193)&=&&HEC63F226
&&m_CRC32Table(194)&=&&H756AA39C
&&m_CRC32Table(195)&=&&H26D930A
&&m_CRC32Table(196)&=&&H9C0906A9
&&m_CRC32Table(197)&=&&HEB0E363F
&&m_CRC32Table(198)&=&&H
&&m_CRC32Table(199)&=&&H5005713
&&m_CRC32Table(200)&=&&H95BF4A82
&&m_CRC32Table(201)&=&&HE2B87A14
&&m_CRC32Table(202)&=&&H7BB12BAE
&&m_CRC32Table(203)&=&&HCB61B38
&&m_CRC32Table(204)&=&&H92D28E9B
&&m_CRC32Table(205)&=&&HE5D5BE0D
&&m_CRC32Table(206)&=&&H7CDCEFB7
&&m_CRC32Table(207)&=&&HBDBDF21
&&m_CRC32Table(208)&=&&H86D3D2D4
&&m_CRC32Table(209)&=&&HF1D4E242
&&m_CRC32Table(210)&=&&H68DDB3F8
&&m_CRC32Table(211)&=&&H1FDA836E
&&m_CRC32Table(212)&=&&H81BE16CD
&&m_CRC32Table(213)&=&&HF6B9265B
&&m_CRC32Table(214)&=&&H6FB077E1
&&m_CRC32Table(215)&=&&H18B74777
&&m_CRC32Table(216)&=&&H88085AE6
&&m_CRC32Table(217)&=&&HFF0F6A70
&&m_CRC32Table(218)&=&&H66063BCA
&&m_CRC32Table(219)&=&&H11010B5C
&&m_CRC32Table(220)&=&&H8F659EFF
&&m_CRC32Table(221)&=&&HF862AE69
&&m_CRC32Table(222)&=&&H616BFFD3
&&m_CRC32Table(223)&=&&H166CCF45
&&m_CRC32Table(224)&=&&HA00AE278
&&m_CRC32Table(225)&=&&HD70DD2EE
&&m_CRC32Table(226)&=&&H4E048354
&&m_CRC32Table(227)&=&&H
&&m_CRC32Table(228)&=&&HA7672661
&&m_CRC32Table(229)&=&&HD06016F7
&&m_CRC32Table(230)&=&&H4969474D
&&m_CRC32Table(231)&=&&H3E6E77DB
&&m_CRC32Table(232)&=&&HAED16A4A
&&m_CRC32Table(233)&=&&HD9D65ADC
&&m_CRC32Table(234)&=&&H40DF0B66
&&m_CRC32Table(235)&=&&H37D83BF0
&&m_CRC32Table(236)&=&&HA9BCAE53
&&m_CRC32Table(237)&=&&HDEBB9EC5
&&m_CRC32Table(238)&=&&H47B2CF7F
&&m_CRC32Table(239)&=&&H30B5FFE9
&&m_CRC32Table(240)&=&&HBDBDF21C
&&m_CRC32Table(241)&=&&HCABAC28A
&&m_CRC32Table(242)&=&&H53B39330
&&m_CRC32Table(243)&=&&H24B4A3A6
&&m_CRC32Table(244)&=&&HBAD03605
&&m_CRC32Table(245)&=&&HCDD70693
&&m_CRC32Table(246)&=&&H54DE5729
&&m_CRC32Table(247)&=&&H23D967BF
&&m_CRC32Table(248)&=&&HB3667A2E
&&m_CRC32Table(249)&=&&HC4614AB8
&&m_CRC32Table(250)&=&&H5D681B02
&&m_CRC32Table(251)&=&&H2A6F2B94
&&m_CRC32Table(252)&=&&HB40BBE37
&&m_CRC32Table(253)&=&&HC30C8EA1
&&m_CRC32Table(254)&=&&H5A05DF1B
&&m_CRC32Table(255)&=&&H2D02EF8D
&&'内联汇编预处理
&&sASM&=&&B008B750C8B7D108B4DE30C3C1E975F28B4D5E5F89EC5DC21000&
&&ReDim&m_CRC32Asm(0&To&Len(sASM)&\&2&-&1)
&&For&i&=&1&To&Len(sASM)&Step&2
&&&&m_CRC32Asm(i&\&2)&=&Val(&&H&&&&Mid$(sASM,&i,&2))
&&'标记CRC32
&&m_CRC32Init&=&True
Private&Sub&Class_Initialize()
&&'默认为CRC32算法
&&Algorithm&=&CRC32
我是代码终止线
可以看到该类模块里应用了VB内联汇编的技巧,其核心是利用了CallWindowProcA,将定义好的代码串作为数值编入VB,然后通过CallWindowProcA来指定其为执行的代码进行执行。相关内容请到网上查找。
该模块是我修改来急速计算文件CRC32或者CRC16的,默认情况下是计算CRC32。
然后双击窗体Form1,在工具栏里选择“工程”,指向“部件”,选择“Microsoft&Common&Dialog&Contrll&6.0”,在工具箱中选择它,添加到窗体上。并改其名为“Openfile”。
注意:细节美观什么的,大家自己弄,我讲的一般不包含如何设置和美化界面什么的。
在窗体通用部分添加:
Private&CRC32zhi&As&String
'用作储存CRC32的值的
Private&Zhuangtai&As&Boolean
'用作标志写入文件是否成功
在窗体上添加按钮Command1,命名为“打开”,然后设计代码使通过它跟“Openfile”挂钩(别再问我Openfile是什么,也就是刚才我们使用的Common&Dialog控件)
Openfile的Action我们采用1模式,也就是常见的打开对话框;
Openfile的Dialog&Title我们命名为&&&&&请选择需要添加CRC32自校验值的目标程序&
Openfire的Filter属性我们设置为&*.exe&
Openfire的其他属性默认即可
为了计算并自动添加CRC32值到目标程序,并且方便大家复制移植代码,我们有必要给它写个过程,或者函数。这里注射写过程就好了,等下设计主体程序时我们也要写函数的。
我是代码起始线
Private&Sub&SetCRC32(Lujing&As&String)
'函数化添加CRC32
On&Error&GoTo&CRCerror
&Dim&cCRC&As&New&clsCRC,&FileCRC$
'启用类模块
&&&&cCRC.Algorithm&=&CRC32&'选择算法模式是CRC32
&&&&cCRC.Clear&&'算法初始化
&&&&FileCRC&=&Hex(cCRC.CalculateFile(Lujing))
&&&&'计算出目标程序的CRC32,忽略目标程序末尾8字节数值,末尾8字节是用来储存我们示范的CRC32值的
&&&&If&Len(FileCRC)&&&8&Then&FileCRC&=&Left(&&,&8&-&Len(FileCRC))&&&Hex(cCRC.CalculateFile(Lujing))
&&&&'如果CRC32值不足8位,那么要在前面添加零来补足位数
&&&&CRC32zhi&=&FileCRC
&&&&&&&'CRC32值储存
&&&&FileNum&=&FreeFile
&&&&'获得个文件号(通道)
&&&&Open&Lujing&For&Binary&As&#FileNum
&&&&Seek&FileNum,&FileLen(Lujing)&-&7
&&&&Put&#FileNum,&,&FileCRC
&&&&Close&FileNum
&&&&'用二进制模式打开目标程序,通过SEEK定位需要添加CRC32数值的位置,请注意:这个位置以后大家可以自己改
&&&&'通过PUT将我们计算号的CRC32写入指定位置
&&&&'通过CLOSE关闭通道
Zhuangtai&=&True
&'状态字,表示写入文件成功了
MsgBox&&发生意外错误,请检查目标程序是否正在运行?&,&,&&发生意外错误,代码:&&&&&Err.Number
我是代码终止线
SetCRC32就是特意写的直接完成计算CRC32和写入目标程序的功能过程
调用格式为:SetCRC32(目标程序路径)
看,多么简单不是吗?
接下去双击Command1按钮,给它设计功能代码如下:
我是代码起始线
Private&Sub&Command1_Click()
'选择一个待添加CRC32值的自校验程序
On&Error&GoTo&Qingjiancha
'初始化CRC32值,主要是为了清空上次的状态
CRC32zhi&=&&&
'初始化写入成功与否的标志
Zhuangtai&=&False
Dim&FilenameNo1&As&String
Openfile.DialogTitle&=&&&&&&请选择需要添加CRC32自校验值的目标程序&
Openfile.Filter&=&&*.exe&
Openfile.Action&=&1
FilenameNo1&=&Openfile.Filename
If&FilenameNo1&=&&&&Then&Exit&Sub
'检查是否选择了程序
If&FileLen(FilenameNo1)&&&16&Then&MsgBox&&请检查目标程序是否包含足够数据&,&,&&请检查NO1&:&Exit&Sub
'检查程序是否包含足够空间和数据,因为储存CRC32需要8个字节的空间,本身计算余量怎么说也要8个字节把?8+8=16
Big.Caption&=&&目标程序大小为:&&&&&FileLen(FilenameNo1)&&&&&字节&
SetCRC32&(FilenameNo1)
CRCzhi.Caption&=&&目标程序CRC32值:&&&&&CRC32zhi
If&Zhuangtai&=&True&Then
Zhuang.Caption&=&&CRC32添加状况:&添加成功,你可以启动目标程序的自校验来核实&
Zhuang.Caption&=&&CRC32添加状况:&添加失败,请你检查下目标程序是否正在运行中?&
FilenameNo1&=&&&
Qingjiancha:
MsgBox&&发生意外错误,请检查输入等情况是否正常,目标程序是否正在运行?&,&,&&发生意外错误,代码:&&&&&Err.Number
FilenameNo1&=&&&
我是代码终止线
整个程序还需要:一个名为CRCzhi的Label,一个名为Zhuang的Label
&&&&&&&&分别显示计算出来的CRC32值,和显示写入文件是否成功的信息
这样子,通过编译,生成EXE文件,执行效果如图:
这样我们就完成了VB-CRC32添加校验值到目标程序的注射端。保存工程等文件。
接下去,我们就来应用该VB-CRC32注射端配合主体程序来完成整个VB-CRC32自校验设计
下面开始写VB-CRC32自校验主体程序
打开VB6.0,新建工程
按照上文一样,建立clsCRC类模块,代码一致,或者直接添加附件里的该类模块也可以。
然后设计如下图的程序界面,注意需要一个名为Jieguo的Label,建立一个名为“检测“的Command1
然后双击窗体,进入代码设计界面
在这个主体自校验部分,大家想一下,大概需要写几个什么样的函数?方便复制和移植?
我认为是两个函数,分别计算自身的CRC32值,和获取已经写入到末尾8字节的CRC32校验值。
那么说干就干吧:
我是代码起始线
Private&Function&GetCRC32()&As&String
'函数化计算本身的CRC32
Dim&Lujing&As&String
'定义本程序自己的路径变量
On&Error&GoTo&CRCerror
Lujing&=&App.Path&&&&\&&&&App.EXEName&&&&.exe&
'这句语句就获得了程序自己的启动路径,这个技巧VB中必须掌握,用处很多
&Dim&cCRC&As&New&clsCRC,&FileCRC$
'启用类模块
&&&&cCRC.Algorithm&=&CRC32&'选择算法模式是CRC32
&&&&cCRC.Clear&&'算法初始化
&&&&FileCRC&=&Hex(cCRC.CalculateFile(Lujing))
&&&&'计算出目标程序的CRC32,忽略目标程序末尾8字节数值,末尾8字节是用来储存我们示范的CRC32值的
&&&&If&Len(FileCRC)&&&8&Then&FileCRC&=&Left(&&,&8&-&Len(FileCRC))&&&Hex(cCRC.CalculateFile(Lujing))
&&&&'如果CRC32值不足8位,那么要在前面添加零来补足位数
&&&&GetCRC32&=&FileCRC
Exit&Function
MsgBox&&发生意外错误,程序被破坏?&,&,&&发生意外错误,代码:&&&&&Err.Number
End&Function
我是代码终止线
该GetCRC32函数直接当作字符变量来使用即可,可获取自身除末尾8位外其他所有数据的CRC32值,我再强调一遍,这里是做示范,为了方便查看和记忆,特将CRC32校验值储存到目标程序末尾8字节位置,实际应用中,大家可以自己选择一个合理的位置。
我是代码起始线
Private&Function&GetZHI()&As&String
'函数化获得末尾标记值
'这个值是我们用CRC32添加工具添加进去的
'这个位置你也可以自己修改
Dim&Lujing&As&String
Dim&ArrBytes()&As&Byte
Dim&FilelenNO1
Dim&Xunhuan&As&Double
'定义本程序自己的路径变量
'On&Error&GoTo&ZHIerror
Lujing&=&App.Path&&&&\&&&&App.EXEName&&&&.exe&
'这句语句就获得了程序自己的启动路径,这个技巧VB中必须掌握,用处很多
tfile&=&FreeFile
&&&&Open&Lujing&For&Binary&As&#tfile&&&&&&&&'利用二进制打开自身
&&&&FilelenNO1&=&LOF(tfile)
&&&&ReDim&ArrBytes(1&To&FilelenNO1)&As&Byte&'将目标末尾8位储存
&&&&Get&tfile,&,&ArrBytes
&&&&Close&tfile
For&Xunhuan&=&FilelenNO1&-&7&To&FilelenNO1
'开始获取这具体的8位
GetZHI&=&GetZHI&&&Chr(ArrBytes(Xunhuan))
Next&Xunhuan
Exit&Function
MsgBox&&怀疑程序被破坏了&,&,&&错误代码:&&&&&Err.Number
End&Function
我是代码终止线
该GetZHI函数同样可以当字符形式使用,很方便,从名字上看就知道是为了获取预先储存在本身末尾8字节的CRC32预先计算的值。干什么用?当然是跟上面的GetCRC32函数返回的字符进行比较,看结果是否跟标记的一致,一致就说明程序没有被修改,不一致就说明程序被修改了。
这个两个关键函数同样可以被大家移植过去使用
很高兴能给VB共享软件带来点有趣的有用的东西。
接下去就是在主体中使用这两个函数
我们的使用代码是:
我是代码起始线
'就简单的一句话就交代了&^_^
'我们已经写好了GetCRC32函数和GetZHI函数
'两个函数返回值为字符串,当然,我们只是做测试,如果真的要
'应用到软件中去,我推荐还是用浮点计算,制造隐藏剧情
'甚至内联汇编处理,根据CRC32值来跳转,让人难以琢磨
'使用时,只要使用这两个函数就OK了
If&GetCRC32&=&GetZHI&Then
MsgBox&&程序未被修改过,恭喜你&,&,&&通过&
Jieguo.ForeColor&=&&H&'更改字体颜色为黑色
Jieguo.Caption&=&&程序未被修改&
MsgBox&&程序被修改,请不要非法修改本程序,共享软件云云...&,&,&&被修改&
Jieguo.ForeColor&=&&HFF&&'更改字体颜色为红色,表示警告
Jieguo.Caption&=&&警告:程序被修改&
我是代码终止线
这个使用代码,能看懂的就自己改写,看不懂的就添加到Private&Sub&Form_Load()事件中去,还有Private&Sub&Command1_Click()事件中。
好了,保存工程后,开始编译为EXE文件吧,编译好后,用我们写好的VB-CRC32添加校验值注射工具进行注射一下,这个时候如果有杀毒软件在的话,而且比较好的话,可能会弹出提示问你允不允许修改什么的,我用的微点就会提示和拦截,需要防行。然后运行吧。
效果如图:
可以看到这里显示的目标程序的CRC32自校验码为:60B04682
我们用UltraEdit打开注射过了的目标主体程序,在末尾看到:
可见已经添加成功了,运行主体程序:
看来校验通过了,那么我们下面来模拟下破解者修改程序的情况:
在VBExplorer中,我们找到检测按钮事件起始地址:405F90
代开OD来装载目标主体程序,CTRL+G&直接到&405F90
00405F90&&&&&\55&&&&&&&&&&&&PUSH&EBP
00405F91&&&.&&8BEC&&&&&&&&&&MOV&EBP,ESP
00405F93&&&.&&83EC&0C&&&&&&&SUB&ESP,0C
00405F96&&&.&&68&&&&PUSH&&JMP.&MSVBVM60.__vbaExceptHandler&&&;&&SE&处理程序安装
00405F9B&&&.&&64:A1&0000000&MOV&EAX,DWORD&PTR&FS:[0]
00405FA1&&&.&&50&&&&&&&&&&&&PUSH&EAX
00405FA2&&&.&&64:&MOV&DWORD&PTR&FS:[0],ESP
00405FA9&&&.&&81EC&9C000000&SUB&ESP,9C
00405FAF&&&.&&53&&&&&&&&&&&&PUSH&EBX
00405FB0&&&.&&56&&&&&&&&&&&&PUSH&ESI
0040604D&&&.&/0F84&D1000000&JE&VB防破解.
‘我们把这句改为必跳实验下,看看CRC32校验的威力
0040604D&&&&&/E9&D2000000&&&JMP&VB防破解.
&&&&&|90&&&&&&&&&&&&NOP
然后保存程序,运行修改后的程序如图:
到此我们完成了VB-CRC32自校验程序的设计全部过程,有些问题必须讲以下:
也许会有人问:“小爱老师,听说CRC32很厉害,防修改。但是我用了你的代码之后,刚发表的共享软件就被人修改了,怎么回事?”
问到点子上了,确实CRC查错能力很强,但是它本身也有脆弱性,本身防修改,但是事实恰恰相反,你可以问下身边的解密高手,当他们遇到CRC32自校验的时候怎么办?
一般都是爆破,还有些是替换,替换的话还要重新计算新的CRC32值,比较罗嗦,所以大家都喜欢爆掉CRC32的关键比较点来突破CRC32,而且以此为荣。
如果你设计VB-CRC32自校验,怎样处理这种情况?首先你要隐蔽你的比较方式,采用浮点计算,套用异常,故意设置隐藏剧情来保护CRC-32的校验,这是个好办法。也有高手说要加壳带CRC32校验。
前辈们给的办法是把校验值进行变换,分段,分开,分时,不定时,在各种场合和代码角落进行验证,尽量不给检测到非法修改的提示,而是检测到非法修改也不告诉破解者,悄悄变换程序流程,让他迷路去吧
甚至是报复破解者,这个我是不推荐的,但是我可以给个快速关机的过程,直接调用可以在几秒内关闭对方计算机,让对方来不及保存破解笔记和资料,注:往往破解者用影子系统或者虚拟机
我是代码起始线
‘在通用部分加入如下声明:
Private&Declare&Function&RtlAdjustPrivilege&&Lib&&ntdll&&(ByVal&Privilege&,&ByVal&NewValue&,&ByVal&NewThread&,&OldValue&)
Private&Declare&Function&NtShutdownSystem&&Lib&&ntdll&&(ByVal&ShutdownAction&)
Private&Const&SE_SHUTDOWN_PRIVILEGE&&=&19
Private&Const&ShutDown&&=&0
Private&Const&RESTART&&=&1
Private&Const&POWEROFF&&=&2
‘在窗体代码部分增加:
Sub&TurboShutdown(Index&As&Integer)
&&&&&RtlAdjustPrivilege&SE_SHUTDOWN_PRIVILEGE,&1,&0,&0
&&&&Select&Case&Index
&&&&&&&&Case&1&'关机
&&&&&&&&&&&&NtShutdownSystem&ShutDown
&&&&&&&&Case&2&'重启动
&&&&&&&&&&&&NtShutdownSystem&RESTART
&&&&&&&&Case&3&'关机
&&&&&&&&&&&&NtShutdownSystem&POWEROFF
&&&&End&Select
我是代码终止线
调用该快速关机指令为:
Call&TurboShutdown(1)
希望对你有用,但是不要拿来欺负正常使用你软件的顾客哦,不然把顾客都吓跑了
注意:以上VB-CRC32全部设计代码和工程文件及程序都发布在附件了,请自行下载
第二章&&第二讲
VB时间自校验设计
上一讲我们讲了使用VB进行CRC32自校验的设计,相信是能让部分VB软件作者受益的。下次见到你们发表VB软件的时候,我希望不是随便爆破修改就能破解的了。
也许你认为VB-CRC32设计有点复杂,你问“小爱老师,有没有简单点的防爆破自校验?”
当然是有的
你可以先实验下,随便编译个程序,单击右键查看属性,你会发现它包含了你的最后修改时间,一般的复制,黏贴等都不会修改它的“修改时间”属性。
然而,当破解者修改了你的软件就会被记录下最新的修改时间,如果破解者不注意,而你的设计又够隐蔽,倒是可以检查这个来判断破解者有没有修改过你的软件。
来,跟我一起做运动……
打开VB6.0&新建工程
添加一个按钮,起名为“检测”
编写一个检测自身修改时间并作比较的函数:
我是代码起始线
Private&Function&ShiJiancheck()&As&Boolean
ShiJiancheck&=&False
Dim&iFile&As&String
Dim&FileTime&As&String
iFile&=&App.Path&&&&\&&&&App.EXEName&&&&.exe&
'获取自身启动路径
FileTime&=&Format(FileDateTime(iFile),&&YYYYMMDDHHMMSS&)
'获得字符串形式的文件最后修改时间
If&FileTime&=&&08&&Then
'示范设置为日08时08分08秒,这里大家可以自己定,最好不要太特别
ShiJiancheck&=&True
ShiJiancheck&=&False
End&Function
我是代码终止线
调用该函数直接当作布尔变量用即可
如下调用:
我是代码起始线
Private&Sub&Command1_Click()
'注意,文件本身的修改时间应该不是我们设定的值,所以编译好EXE文件后,
'用文件属性修改器来修改文件最后修改时间到指定数值,这个数值不要太特殊了
'文件属性修改器已经放在同个文件夹下了,请使用
If&ShiJiancheck&=&False&Then
MsgBox&&文件被修改&,&,&&警告&
MsgBox&&文件正常&,&,&&通过&
我是代码终止线
效果如图:(正常状态)
文件被修改后:
跟CRC32比,此办法短小精悍,但是容易被识破,请隐蔽比较和检测,不要把结果显示出来,知道了吧?给破解制造一次意外事故应该不是难事吧?
第二章&&第三讲
VB大小自校验设计
“小爱老师,上面的方法都要修改什么的,太麻烦了,有没有更通用,更普遍的办法,且不用修改程序的呢?”
“当然有了,那就是VB里面的检测文件大小,但是已经见得多了,已经没什么杀伤力了”
Vb里常用检测文件大小的函数为FILELEN(路径)
跟我一起做运动……
打开VB6.0&新建工程
先编写个检测自身大小的函数:
我是代码起始线
Private&Function&FileBig()&As&Long
'如果文件巨大,那么改LONG为DOUBLE
Dim&FileLujin&As&String
filelujing&=&App.Path&&&&\&&&&App.EXEName&&&&.exe&
FileBig&=&FileLen(filelujing)
End&Function
我是代码终止线
具体使用看下面代码:
我司代码起始线
Private&Sub&Form_Load()
If&FileBig&&&27300&Then
'第一次这个数字随便设置,先编译好
'用压缩壳将它压缩,查看压缩后文件大小
'回到这里,修改数值比压缩后的大小大那儿一些就够了
'如果被脱壳了,程序体积就会膨胀
'从而被我们检测出来
'当然要注意了,如果是保护壳的话
'加壳后反而更大,这个时候,我们的判断
'语句就要反过来了
MsgBox&&程序被脱壳了&,&,&&警告&
MsgBox&&程序正常&,&,&&通过&
我是代码终止线
编译,加壳(ASPACK)程序从45056字节压缩为&27136&字节,27300略大于27136,脱壳后应该比45056可能还要大,这样就能实现检测大小来发现脱壳,也就发现修改了。
脱壳后:大小71168字节,为什么这么大呢?呵呵,可能是垃圾代码和垃圾段还没清理吧,可以用LORDPE重建,应该会小一点。
重建PE后,程序大小46261字节
运行看看:如图
实验成功,但是我还是要提醒一下,这种方法隐蔽点,不要提示的话,也许还能存活,对于VB程序,一旦发现自校验,初学者或者有点基础的人都会想到去断点FILELEN函数,直接捕获你的对比关键点。
所以自校验的设计最关键在于隐蔽和起到误导作用为好,不知不觉中就到了羊肠小道,永远没有回头路……
另外要介绍的是同样是检测文件大小以确定是否被脱壳,有些软件作者把数值通过计算好,通过注射方法,写入到主体程序的文件头,这种方法可以比较准确的限定文件大小,而且不容易被发现哦,比方说“超级硬盘搜索正式版”,它就是这么检测的。
有点作者把VB程序的数据全部加在一起,比较最后的和,这也是种办法,所以大家要学会思考和创新,没有什么是做不到的。
第二章&&第四讲
VB防LOADER设计金蝉脱壳
《加密解密技术内幕》一书里提到过两种方法防LOADER
其指的是防SMARTCHECK,WKTVB&DEBUGGER等
这些技术已经为人所熟知,起不到多么好的作用,我们就了解一下吧,为我们的“金蝉脱壳”做铺垫。
1.&&查找特定的窗口标题&&就像第一讲里提到的:
我是引用起始线
二、反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
我是引用终止线
2.&&设置步长和时值计算法
其原理是软件正常执行的某一块过程是很快的,基本没多少延时;而通过调试器加载,其加载时间往往要多出十几倍。
这种方法其实应该是反调试反跟踪里用到的,这里就只提下原理,讲到反调试的时候,我再把我知道的写出来。
目前还有异常SHE处理,使得调试器无碍继续加载。还有其他的办法,但是我涉及较浅,以后有机会都放到反调试一块讲。
讲完常见的VB反LOADER,你是不是觉得不够好使?如查标题,我改标题你不久查不到了吗?&如步长记时,现在的电脑配置参差不齐,这步长时值该怎么时值好呢?
左思右想,终于被我想到了个办法金蝉脱壳
所谓金蝉脱壳指的是核心的东西在你眼皮底下溜走了,抓不到。留下的是一层幻灭的轮回。
VB金蝉脱壳反LOADER技术基于程序迭代SHELL,第一次运行不会真的开始,而是为了调用本身进行第二次运行,就此结束掉第一次运行,以此类推,知道几百几千次,需要的时间大概在半秒到左右。
形象点讲就像小孩子走路,故意跌倒,然后爬起来,又故意跌倒,让你永远把握不到他,知道他再起来的时候,你早就离开那里了。
比如A实例,运行后,重新调用A,然后本次A实例自动结束,第二次A实例启动,再次调用A实例,然后又关闭自己。这样调试器第一跟踪,如果不爆破的话,势必无法继续跟了,到后来,调试器里显示的是父本程序已经结束了,但实际中,经过几百到几千次迭代SHELL后,程序已经打开。
就像人生一样,调试器跟踪的只是你的上一世,甚至是几百几千世以前的你,而现在的你还好好得活着。这个时候,如果不爆破的话,调试器大概还可以用附加来强行钻入程序空间。
这样的思路是可行的,但是你有没有想到过如何判断本次运行已经达到要求,可以正常开始?还是继续轮回?
要求程序依靠自己的标记,而不依靠外界的标记,不然容易被人发现且从外界修改是非常容易攻破的。
因为程序是同一个程序,凭什么上一辈子要立刻轮回,而这辈子就可以正常存活呢?判断的标准在哪里?同样的程序,同样的标准,为什么会产生不同的轮回结果?
答案呼之欲出了,对了,就是随机数。
通过概率,每次轮回的概率是一样的,是同样的标准,但是概率本身又可以导致不同的方向和结果。
于是我想到设置一个循环取随机数的结构,循环7次,每次产生一个随机数,要么是1,要么是零,然后把这七个数相加来判断是否等于零,如果等于零就不必继续轮回了,如果不等于零,那么SHELL自己,然后马上死掉。因为每次随机数取0活着取1的概率是一样的,都是0.5,所以,7次随机数取值全部为零的概率是0.5^7=0.0078125,倒数为128,即大概需要轮回128次才可以正常运行程序,否则都是SHELL自己,然后父本死掉。
单单靠解释可能还是有朋友看不明白,没关系,我们先写程序先,慢慢测试调试,你就发现其巧妙的地方了。
首先写一个7次循环取0或取1的结构,然后把7次结果相加,与0作比较,将轮回金蝉脱克功能嵌入进去。以后程序在运行开头,只要调用一次我的这个SUB过程即可实现防LOADER,等会我们还要测试下效果呢。
我是代码起始线
Private&Sub&JinChan()
On&Error&GoTo&ANTI
'只有在被调试的时候才有可能出错,恰好被我们捕获,呵呵
Dim&Lujing&As&String
'储存程序自身路径
Dim&Suiji(7)&As&Byte
'7个元素数组,用于储存每次随机数
Dim&n&As&Long
'循环计数器
Dim&Panduan&As&Double
Lujing&=&App.Path&&&&\&&&&App.EXEName&&&&.exe&
'获得程序自身路径
For&n&=&1&To&7
'每次都初始化随机数生成器
Suiji(n)&=&Int(Rnd&*&2)
‘取随机数0或者1
Panduan&=&Panduan&+&Suiji(n)
If&Panduan&&&0&Then
'如果累加总结果不为零,那就SHELL自己一次,然后通过END结束自己
Shell&Lujing,&1
'进入下一个轮回哦
'结束这一世
'如果上面的累加器等于零,则说明达到了0.5^7的概率了,其倒数为128,即我们已经轮'回128是世了。'调试器跟踪的只是我们的第一世。
'到这里来的话也就是不执行SHELL内容,也不执行END,直接到这里来了
MsgBox&&发现调试器,请关闭调试器&,&,&&警告&
我是代码终止线
以后只要把JinChan写入到主窗体LOAD事件中,就实现了金蝉脱壳效果。
大家跟我来做运动:
打开VB6.0&新建工程
在窗体代码里,拷贝上面的代码进去
然后在Private&Sub&Form_Load()里输入JinChan,编译生成EXE
Private&Sub&Form_Load()
先运行一下EXE,看看速度如何,然后再用OD或者SMARTCHECK等测试下,看看是不是无法跟踪到轮回后的这一世,前提是不能爆破。
效果还是很好的,OD如果开着HIDEOD插件的话,那么在执行SHELL的时候,会自动捕获错误以发现调试器,然后程序自动结束,也相当于起到了防LOADER作用。如果OD关闭HIDEOD插件,那么就可以直接体现出“金蝉脱壳”的效果了。
如图:通过捕获异常发现调试器
如果没有异常,那么金蝉脱克将发挥作用,轮回百世。调试器里已经结束,但是程序其实轮回转世了。
好了,没想到随便写写可以写这么多,看的我头晕了。
希望你也别头晕,我们来总结下,《VB&共享软件防破解涉及技术初探(二)》都讲了那些内容:
1、&&设计思想:水桶原理
2、&&完整性校验,包括VB-CRC32注射器和主体的编写;文件修改时间自校验;文件大小自校验等
3、&&防LOADER设计,包括查找标题,经典时值,还有重点的“金蝉脱壳”反LOADER
这一期就到这里了,熬夜写教程很累,呵呵
还是老规矩,如果有时间,有精力,有空,有能力,我将接着写《VB&共享软件防破解设计
技术初探(三)》,感谢大家的支持。
希望大家能多顶顶,尤其是学习VB写软件的朋友,希望对你有用。上传的附件
[解压密码:pediy]
标 题:VB 共享软件防破解设计技术初探(三)更新
作 者:爱琴海
时 间:<font color="#08-09-10 23:05 链 接:
VB&共享软件防破解设计技术初探(三)
××××××××××××××××××××××××××××××××××××××××××××××
其他文章快速链接:
VB&共享软件防破解设计技术初探(一)
VB&共享软件防破解设计技术初探(二)
××××××××××××××××××××××××××××××××××××××××××××××
作者:爱琴海[SCG]&&(转载请保留该信息)
第一篇我粗略的讲了以下几个内容:
1、&&文件完整性,防止被非法修改
2、&&运行时的校验,防止被LOADER
3、&&反调试,防止动态跟踪和挂接
4、&&防静态反汇编分析
5、&&注册码系统(算法部分,核心内容)
6、&&加壳防脱壳
7、&&隐蔽性设计
8、&&另辟蹊径
第二篇我详细得讲解了以下内容:
1、设计思想:水桶原理
2、完整性校验,包括VB-CRC32注射器和主体的编写;文件修改时间自校验;文件大小自校验等
3、防LOADER设计,包括查找标题,经典时值,还有重点的“金蝉脱壳”反LOADER
上节课我忘讲了种常见的反LOADER的方法:释放程序法(借鸡生蛋)
这里赶紧补上:
释放程序法(借鸡生蛋)
原理:讲需要保护的程序作为自定义资源添加到新的VB程序里,新程序一运行就自动释放内部包含的程序到特定位置,然后通过SHELL调用,自身则结束运行,怀疑就是“借鸡生蛋”,也是常用的木马病毒免杀技术。
打开VB6.0&新建工程,然后单击“外接程序”——“外接程序管理器”——“VB&6&资源编辑器”,在右下角选项里选择“加载/卸载”,然后单击“确定”
这时,在VB6.0主程序窗口上方的工具条最后,就会出现一个跟注册表编辑程序挺像的绿色图标,单击它。
选择自定义添加图标,然后在出现的窗口里,选择你要保护的EXE程序。
添加完资源后,按下“保存”按钮
这样,资源就被添加为代号为101的数据,同理,就绪添加,就从102开始,一直增长上去,你也可以自己修改代号,方便记忆。
下面我们来写一个自动释放子体的过程SUB
我是代码启示线
Private&Sub&Shifang()
On&Error&GoTo&TakeError
Dim&Lujing&As&String
Lujing&=&&C:\WINDOWS\system32\缓存.exe&
'定义缓存路径
If&Dir(Lujing)&=&&&&Then
'检测子体是否已经存在
'不是的话就直接释放一个即可
Dim&Shuzu()&As&Byte
'定义一个数组储存数据
Shuzu()&=&LoadResData(101,&&CUSTOM&)
'加载数据,101代号指的就是我们添加的EXE子体
Open&Lujing&For&Binary&As&#1
'定义一个缓存路径
Put&#1,&,&Shuzu()
Kill&Lujing
'发现已经存在就删除它,然后就重新创建;目的是为了防止有人故意同名替换
'定义一个数组储存数据
Shuzu()&=&LoadResData(101,&&CUSTOM&)
'加载数据,101代号指的就是我们添加的EXE子体
Open&Lujing&For&Binary&As&#1
'定义一个缓存路径
Put&#1,&,&Shuzu()
Shell&Lujing,&vbNormalFocus
'释放好后就SHELL使其运行,接下去就结束掉自己
TakeError:
'一般发生错误是因为子体正在运行,无法删除或者覆盖,或者是因为OD的HIDEOD插件引起SHELL错误
MsgBox&&请检查我是否正在运行?或者,是因为调试器?请检查&,&,&&发现问题了&
我是代码终止线
调用的话,在FORM的LOAD事件里,或者其他启动事件里即可,如下:
Private&Sub&Form_Load()
看看效果吧!
正常运行,跟运行一个程序感觉上没有什么差别
如果加载OD调试器的话,如果OD刚好加载HIDEOD插件的话,就会提示错误,发现调试器:
如果关闭HIDEOD插件,就会自动借鸡生蛋,使调试器无法加载正确的子体程序
需要注意一点,只要够小心的人,一定会发现真正的程序所在,所以子体程序最好加上自删除代码,也就是检测到UNLOAD事件后,自动删除自己,或者调用批处理,隐藏删除自己。
我碰到过的一些用VB写的外挂也就是用这种技术来逃避调试器的。
这种技术就讲解到这里,我们开始新的篇章喽
第三篇我将具体介绍&1、VB反调试反跟踪&2、防静态反汇编分析
设计加密解密不久,能力有限,见识短浅,请各位高手见谅,有错误和不足之处敬请原谅,并请你阐述你自己的见解,共同完成《VB&共享软件防破解设计技术初探》系列文章,您的参与和支持是我的荣幸和骄傲。
这篇开篇前我把自己想到的VB程序防破解设计图展示下,看看大家想到了什么?自由发挥
我心中总有个声音:你设计的只是针对技术层面,无法真的长久的保证你的软件不被破解
实际生活中,我们需要八卦一样的“阴阳鱼”,一切造化的根本。(我在故弄玄虚吧?)
一个是阳刚的“法律”保障,一个是怀柔的“道义”安抚。
在这里引述一篇文章里的片段,具体作者是谁,大家自己查
原文是《如何让你的共享软件在国内赚到}

我要回帖

更多关于 vb6运行库 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信