4的GPS导航连不上卫星,有什么办法解救传销人员最好办法不

>> 一个用vb编写指纹识别程序,它通过二值化图象,计算阈值和统计黑像素值来识别...
一个用vb编写指纹识别程序,它通过二值化图象,计算阈值和统计黑像素值来识别...
所属分类:
下载地址:
thresholdcalculation文件大小:253.06 kB
分享有礼! 》
请点击右侧的分享按钮,把本代码分享到各社交媒体。
通过您的分享链接访问Codeforge,每来2个新的IP,您将获得0.1 积分的奖励。
通过您的分享链接,每成功注册一个用户,该用户在Codeforge上所获得的每1个积分,您都将获得0.2 积分的分成奖励。
一个用vb编写指纹识别程序,它通过二值化图象,计算阈值和统计黑像素值来识别-vb prepared with a fingerprint identification procedures, it adopted two binary images, calculated and statistical threshold value of black pixels to identify
Sponsored links
源码文件列表
温馨提示: 点击源码文件名可预览文件内容哦 ^_^
1.jpg66.43 kB28-05-04 12:33
Form1.frm22.09 kB02-02-05 23:22
Form1.frx8.83 kB02-02-05 23:22
Form1.log153.00 B30-09-04 19:55
Form2.frm2.14 kB30-12-04 14:34
Form2.log80.00 B30-09-04 19:58
Form3.frm1.42 kB29-05-04 17:18
Form4.frm3.34 kB29-05-04 17:18
Form5.frm1.21 kB30-05-04 22:38
frmSplash.frm4.70 kB10-06-04 12:47
frmSplash.frx790.00 B10-06-04 12:47
MSSCCPRJ.SCC344.00 B02-02-05 23:24
Project1(new).vbp1.07 kB02-02-05 19:12
Project1(new).vbw309.00 B02-02-05 23:24
Project1.vbp1.08 kB14-06-04 23:48
Project1.vbw301.00 B02-02-05 23:35
zhiwen1.bmp124.30 kB10-05-04 23:29
zhiwen2.bmp135.79 kB10-06-04 12:42
库图.bmp124.30 kB13-06-04 22:10
1.jpg66.43 kB28-05-04 12:33
Thumbs.db5.00 kB02-02-05 23:15
工程.exe84.00 kB11-06-04 10:10
&打包&0.00 B02-02-05 23:15
&基于阀值计算的指纹识别&0.00 B02-02-05 23:22
(提交有效评论获得积分)
评论内容不能少于15个字,不要超出160个字。
评价成功,多谢!
下载thresholdcalculation
CodeForge积分(原CF币)全新升级,功能更强大,使用更便捷,不仅可以用来下载海量源代码马上还可兑换精美小礼品了
您的积分不足,优惠套餐快速获取 30 积分
10积分 / ¥100
30积分 / ¥200原价 ¥300 元
100积分 / ¥500原价 ¥1000 元
订单支付完成后,积分将自动加入到您的账号。以下是优惠期的人民币价格,优惠期过后将恢复美元价格。
支付宝支付宝付款
微信钱包微信付款
更多付款方式:、
您本次下载所消耗的积分将转交上传作者。
同一源码,30天内重复下载,只扣除一次积分。
鲁ICP备号-3 runtime:Elapsed:303.967ms - init:0.1;find:0.7;t:1.3;tags:0.4;related:271.6;comment:0.1; 27.69
登录 CodeForge
还没有CodeForge账号?
Switch to the English version?
^_^"呃 ...
Sorry!这位大神很神秘,未开通博客呢,请浏览一下其他的吧扫码下载APP
随时选购服务
需求发布后1小时内收到服务商响应每个需求平均有10个服务商参与95%以上的需求得到了圆满解决所有需求不向雇主收取任何佣金电商旺铺用他们在大促卖卖卖?
修改一个c++ sdk demo程序为vb6程序
修改一个c++ sdk demo程序为vb6程序
雇主预算:¥500.00
已收到 24 个服务商的文案稿件
有相似问题想解决?专业顾问来帮助您
01发布需求, 托管赏金02雇主选稿03中标公示04验收并付款05评价
通过猪八戒网实名认证,保证身份真实可靠
完成手机认证,保证能随时联系到服务商
该需求下的优秀交稿
TA的交稿:
从事软件开发十多年,精通VC++,VB语言,62&30&43&5&77
TA的交稿:
专业VB&软件开发,详细联系&2938922&
TA的交稿:
sdk程序发上来啊,看大不大
TA的交稿:
有十多年数据库经验,使用过vb等软件,详情请联系qq:
交易成功的需求
其它工具软件相关需求网站已改版,请使用新地址访问:
ccSDKOld 用vb.net 2003写的一个高度仿真windows记事本程序.并增加了支持rtf格式的功能:字体\文 Develop 238万源代码下载-
&文件名称: ccSDKOld
& & & & &&]
&&所属分类:
&&开发工具: Visual Basic
&&文件大小: 5707 KB
&&上传时间:
&&下载次数: 6
&&提 供 者:
&详细说明:用vb.net 2003写的一个高度仿真windows记事本程序.并增加了支持rtf格式的功能:字体\文字颜色\图片显示\背景颜色,添加 重复、清空、计算总字数和当前选中字数 功能,可以关联TXT文件、添加到右键菜单、文件拖放操作. -Written in vb.net 2003 with a high degree of simulation windows Notepad program. And to increase support for rtf format features: Fonts \ text color \ picture show \ the background color, add duplication, empty, calculating the total number of words and the current function selected number of words can be associated with TXT files, add to the context menu, file drag and drop.
文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):
&&ccSDKOld\ccSDK\AssemblyInfo.cs&&........\.....\bin\Debug\ccSDK.dll&&........\.....\...\.....\ccSDK.pdb&&........\.....\...\Release\ccSDK.dll&&........\.....\...\.......\CloseChina.dll&&........\.....\Bottom\BizInterface\BizTools.cs&&........\.....\......\............\DMCheckB.cs&&........\.....\......\............\DMDelB.cs&&........\.....\......\............\DMDnsB.cs&&........\.....\......\............\DMLockB.cs&&........\.....\......\............\DMPwModB.cs&&........\.....\......\............\DMRegCnB.cs&&........\.....\......\............\DMRegComB.cs&&........\.....\......\............\DMUnLockB.cs&&........\.....\......\............\DMUrlAddB.cs&&........\.....\......\............\DMUrlDelB.cs&&........\.....\......\............\DMUrlModB.cs&&........\.....\......\EMail\test.cs&&........\.....\......\Ftp\FtpControl.cs&&........\.....\......\...\FtpCreate.cs&&........\.....\......\Util\CCException.cs&&........\.....\......\....\CCTools.cs&&........\.....\......\....\DBUtility.cs&&........\.....\......\....\FileSystem.cs&&........\.....\......\VH\CreatVHB.cs&&........\.....\......\..\VHControl.cs&&........\.....\......\..\VHCreate.cs&&........\.....\ccSDKOld.csproj&&........\.....\ccSDKOld.csproj.user&&........\.....\ClassDiagram1.cd&&........\.....\manage\domain\DMCheck.cs&&........\.....\......\......\DMComReg.cs&&........\.....\......\......\DMTrue.cs&&........\.....\......\member\RegisterUser.cs&&........\.....\......\......\UserLogin.cs&&........\.....\......\......\VHLogin.cs&&........\.....\......\virtualhost\BuyVH.cs&&........\.....\......\...........\CtrlVH.cs&&........\.....\obj\ccSDK.csproj.FileList.txt&&........\.....\...\Debug\ccSDK.dll&&........\.....\...\.....\ccSDK.pdb&&........\.....\...\.....\ccSDK.projdata&&........\.....\...\Release\ccSDK.dll&&........\.....\...\.......\ccSDK.projdata&&........\.....\...\.......\CloseChina.dll&&........\web\acHe!21$^^~@12w5_\#ewcvf~w!.mdb&&........\...\.dmin\admin.htm&&........\...\.....\admin_m.aspx&&........\...\.....\Admin_M.aspx.cs&&........\...\.....\Admin_M.aspx.resx&&........\...\.....\admin_middle.htm&&........\...\.....\admin_mid_left.aspx&&........\...\.....\admin_mid_left.aspx.cs&&........\...\.....\admin_mid_left.aspx.resx&&........\...\.....\admin_mid_right.aspx&&........\...\.....\admin_mid_right.aspx.cs&&........\...\.....\admin_mid_right.aspx.resx&&........\...\.....\ce_m.aspx&&........\...\.....\CE_M.aspx.cs&&........\...\.....\CE_M.aspx.resx&&........\...\.....\ce_pro_add.aspx&&........\...\.....\CE_Pro_Add.aspx.cs&&........\...\.....\CE_Pro_Add.aspx.resx&&........\...\.....\ce_pro_md.aspx&&........\...\.....\CE_Pro_MD.aspx.cs&&........\...\.....\CE_Pro_MD.aspx.resx&&........\...\.....\csd_add.aspx&&........\...\.....\CSD_Add.aspx.cs&&........\...\.....\CSD_Add.aspx.resx&&........\...\.....\csd_m.aspx&&........\...\.....\CSD_M.aspx.cs&&........\...\.....\CSD_M.aspx.resx&&........\...\.....\csd_md.aspx&&........\...\.....\CSD_MD.aspx.cs&&........\...\.....\CSD_MD.aspx.resx&&........\...\.....\cs_add.aspx&&........\...\.....\CS_Add.aspx.cs&&........\...\.....\CS_Add.aspx.resx&&........\...\.....\cs_m.aspx&&........\...\.....\CS_M.aspx.cs&&........\...\.....\CS_M.aspx.resx&&........\...\.....\cs_md.aspx&&........\...\.....\CS_MD.aspx.cs&&........\...\.....\CS_MD.aspx.resx&&........\...\.....\cs_show.aspx&&........\...\.....\CS_Show.aspx.cs&&........\...\.....\CS_Show.aspx.resx&&........\...\.....\delete.aspx&&........\...\.....\Delete.aspx.cs&&........\...\.....\Delete.aspx.resx&&........\...\.....\dm_buy_m.aspx&&........\...\.....\DM_Buy_M.aspx.cs&&........\...\.....\DM_Buy_M.aspx.resx&&........\...\.....\dm_m.aspx&&........\...\.....\DM_M.aspx.cs&&........\...\.....\DM_M.aspx.resx&&........\...\.....\dm_pro_add.aspx&&........\...\.....\DM_Pro_Add.aspx.cs&&........\...\.....\DM_Pro_Add.aspx.resx&&........\...\.....\dm_pro_md.aspx
&近期下载过的用户:
&输入关键字,在本站238万海量源码库中尽情搜索:
&[] - 模仿Windows中的记事本和写字板的功能,自己作一个文档编辑工具。有以下功能: &#61656
文件:(新建、打开、保存、退出) &#61656
编辑:(复制、剪切、粘贴、全选) &#61656
格式:(自动换行、字体、颜色),格式的设置功能要区分是设置当前块的格式还是设置所有内容的格式;
&[] - 使用Java语言开发一个文本编辑器,实现常用的功能,如打开文件、保存、复制、粘贴、剪切、颜色、字体等。VB程序员怎么学习COM的知识,请高人指点一二 - VB当前位置:& &&&VB程序员怎么学习COM的知识,请高人指点一二VB程序员怎么学习COM的知识,请高人指点一二&&网友分享于:&&浏览:15次VB程序员如何学习COM的知识,请高人指点一二?我想自己定制一个浏览器,结果发现简单设置WebBrowser控件不能达到我的需求,结果我在论坛请教,有人指点了如下代码:这里面用到了很对COM接口的知识,如Dispatch Invoke 这些应当是COM的接口吧。我实在看不懂,我想请问:1、一个VB程序员想看懂下面的代码,需要学习些哪方面的知识?2、现在能查到的COM接口详细一点的资料,似乎都是用C++来讲解的。我对C++学过一些入手的知识,但的确只是一知半解,有没有什么专门针对VB程序员的这方面的书刊或资料可否推荐一下?3、COM技术出现也有好多年了,不知道从技述趋势上说,还值得深入学习吗?STDMETHODIMP CBrowserView::XDispatch::Invoke(& DISPID dispid, REFIID, LCID, unsigned short /*wFlags*/,& DISPPARAMS* /*pDispParams*/, VARIANT* pvarResult,& EXCEPINFO*, unsigned int*)& {&
switch (dispid)&
{& case DISPID_AMBIENT_DLCONTROL:& pvarResult-&vt = VT_I4;& pvarResult-&lVal =
0;& if (m_BrowserView-&m_bShowImages)& {//如果需要显示图片& pvarResult-&lVal |= DLCTL_DLIMAGES;& }& if(m_BrowserView-&m_bShowVideos)& {//如果需要显示视频& pvarResult-&lVal |= DLCTL_VIDEOS;& }& if(m_BrowserView-&m_bShowBgSounds)& {//如果需要播放背景音乐& pvarResult-&lVal |= DLCTL_BGSOUNDS;& }& if(!m_BrowserView-&m_bPlayFlash)& {//如果不播放flash(禁止执行OCX控件)& pvarResult-&lVal |= (DLCTL_NO_RUNACTIVEXCTLS | DLCTL_NO_DLACTIVEXCTLS | DLCTL_SILENT);& }& & default:& return DISP_E_MEMBERNOTFOUND;&
return S_OK;& }& ------解决方案--------------------
用VB6搞COM,必看Matthew Curland的Advanced Visual Basic,因为那本书主要就是讲COM的,另外Vb Hardcore里也有一点相关的东西.看你主做哪类应用软件了,如你主要做的那类应用软件本身就非常适合用vb.net搞(包括开发和部署等),那我想就没必要专门深入学COM了,先把vb.net学熟做出你要的东西赚钱最要紧.
------解决方案--------------------同意1楼。。。大实话啊!~~
------解决方案--------------------看书,我有一本,明天去找一下和你分享一下
------解决方案--------------------
COM的API是用C++实现的COM是超越面向对象的组件编程技术.搞清楚了没坏处.IDispatch是自动化(Automation)接口,VB只能使用实现了此接口的COM对象.(具体信息可参考MSDN)介绍COM/ATL的书/文章有:杨老师的《COM组件设计与应用》《COM技术内幕》《ATL开发指南》MSDN中的Platform SDK Documentation-&Component Services-&COM-&COM Fundamentals-&Guide等等
------解决方案--------------------学习中...............
------解决方案--------------------网上有很多关于COM的教材,不妨找一找!
------解决方案--------------------
从 VB 入手可以看《高级Visual Basic编程》(Advanced Visual Basic)当然 MSDN 也要结合看 /en-us/library/ms877981.aspx
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有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大小自校验设计
“小爱老师,上面的方法都要修改什么的,太麻烦了,有没

我要回帖

更多关于 交通银行降额解救办法 的文章

 

随机推荐