下载

3下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 易语言软件加密技术

易语言软件加密技术.doc

易语言软件加密技术

dabaiyun
2018-09-08 0人阅读 举报 0 0 暂无简介

简介:本文档为《易语言软件加密技术doc》,可适用于IT/计算机领域

易语言软件加密技术《易语言软件加密技术》序感谢朋友们的留言以下排名不分先后。何金:一定程度的防破是必要的。goomoo:收藏谢谢!!Liigo:这么经典的文章竟然不署名,佩服!笨笨啊:先收藏应该是好东西。火儿:花了两个多小时才看完……看完才发现自己的软件基本属于赤裸裸那型。icemanwd:世界上没有破解不了的软件只能延迟破解的时间而已。走随小月:易书空前的著作收藏消化吸收中……yjls:写的太好希望易公司今后发行易书里绑定。迪克:很好的文章我已经学了几招。:这个要反复学习。bbs:真的不错。雷锋的四句名言是:对待同志要象春天般的温暖(我在帮助易友们提高易语言水平)对待工作要象夏天般的火热(我是工作狂看我写这么多就知道了)对待个人主义要象秋风扫落叶一样(对支持破解的人要坚决反对)对待敌人要象严冬一样残酷无情(打击盗版是大家共同的责任)。友情广告位全中文全可视跨平台编程软件易语言http:wwwdywtcomcn全国易语言认证管理中心http:wwwcclgcn中国共享软件联盟http:wwwcnsworgbbsindexphp伟业网址:wwwwyitcomcn易容大师http:goomoocn易语言秩事(易语言博客群)http:eyuyanblogsohucomhttp:wwwyihezicom本源码由易盒子搜集提供下载易盒子搜集有大量的易程序源码和电子教程是网友学习易语言的好帮手。前言本文为全中文编写不需要有PE文件格式知识不需要掌握汇编或C语言的编程技巧一些加密算法直接由易语言提供特殊的加密算法大家可以翻译C语言代码、汇编代码或VB代码。本文中将“Cracker”一词翻译为“奸人”意为“奸邪小人”之义。本人对破解者一向深恶痛绝有人说中国的软件发展中破解者有一份功劳可我说这话不对看看因盗版而产生的微软对操作系统及软件业的垄断国内软件业在盗版的夹缝中生存……如此下去软件作者没有收益将不再会有优秀的软件推出。防止盗版匹夫有责我想通过本书的推出可以加强易语言用户的加密能力将盗版杀死在大家共同的手中。随着采用易语言编制程序的人们越来越多写一个软件易被奸人破解的情况也越来越多了有个别用户甚至于怀疑易语言是否有安全性。从技术性上来说我只能说加密技术与编程语言无关一个编程语言的安全性一般指所生成的机器码是否稳定、可靠而不是防破解方面如果想要很好地防止破解那么掌握一门加密技术是靠且是从未被破解过的加密方法。确实这种方法很难破解因为注册码始终是在作者手上的这样怎么去破解呀。加密第定理:一个好的网络验证法至今没有人能破解。.实现的原理网络验证法有些类似于网络游戏中的验证。网络验证方法即建立一个网络服务器程序由软件作者自己保管运行于服务器端客户端通过编程放在共享软件中。客户所拿到的共享软件程序中带有客户端程序当需要验证时客户端的硬件码通过网络传送到服务器中服务端程序将加密后的注册码通过网络传回给客户客户软件中的客户端组件接收到后在内存中解密进行判定如果注册了就通过否则就失败。作者的服务器端上保存了用户的注册码数据库随时供验证之用。在此可以避免以下被破解的事况:首先通过网络验证即使奸人拦截到了注册码也是加密过的如果去解密也很困难并且服务器是由软件作者保管的这样奸人可能始终接触不到注册码。或者他要去学习网络拦截也说不定。其次可以预防暴力破解软件作者可将重要数据直接放在服务器中通过不停验证取得数据从而被破解的客户端被暴力破解后立即成为无效软件。再次即使软件被破解了软件的作者也可以较轻松地升级客户端程序及升级服务器端的注册码数据库从而减少破解造成的损失让破解者阴谋失败。最后软件作者可以轻松看到监视客户端的使用情如果发现有重复名称的验证或不正常地取数据就可以立即停止客户的使用。.存在的几个问题.用户的程序必须是需要通过上网才能使用的不上网将不能验证也不能使用。.软件作者必须要保证服务器的稳定如果服务器死机或掉线那么客户机将不能使用因此也要具备一定的防攻击能力。服务器维护人员技术要求较高要有一定的服务器反黑经验。.网络验证也不能一次全部验证这样并不保险需要分段进行验证。并且给予暗桩的设计。.可能存在客户太多一个服务器接收不过来需要两个以上服务器的情况或就直接架设两个以上服务器用于备用。现在的电信与网通经常打架可考虑一个接电信网一个架网通网以备不时之需。十.加密狗加密本文的目的是让大家了解加密狗它并不是那样神密而可怕大家一定要克服恐惧感哦。加密狗是个极其好用的工具基本上如果用上一个好的型号的加密狗可以为您省不少心想想看吧有一个技术团队在身后做支持呢。易语言论坛上有人说:“不要花太多心思到加密上而是要完善软件功能!”当然将心思放在加密上我也不想这都是拜小人所赐呀。因此如果您想节约时间的话只要买个好狗加一个壳就可以了。加密第定理:如果您想不要花太多心思到加密上而想要一个很强的加密加密狗是最好的选择。说老实话现在的狗都比以前好多了以前还听说有狗被防制或模拟了现在的狗呀越做越好了。总之大家放心用吧。软件狗是一种智能型加密工具。它是一个安装在并口、串口等接口上的硬件电路同时有一套使用于各种语言的接口软件和工具软件。当被狗保护的软件运行时程序向插在计算机上的软件狗发出查询命令软件狗迅速计算查询并给出响应正确的响应保证软件继续运行。如果没有软件狗程序将不能运行复杂的软硬件技术结合在一起防止软件盗版。真正有商业价值得软件一般都用软件狗来保护。平时常见的狗主要有“洋狗”(国外狗)和“土狗”(国产狗)。这里国外狗主要指美国的彩虹和以色列的HASP国产狗主要有金天地(现在与美国彩虹合资叫“彩虹天地”)、深思、尖石。总的说来加密狗在软件接口、加壳、反跟踪等方面技术较好基本上复制很困难。.加密狗的选用加密狗一般分为串口狗与USB加密狗。串口即打印口为针口可以同进串接多个串口型加密狗。如下图所示:现在也已有一种微型加密狗的推出:USB口为直接插入USB接口每个接口只能插一个。如下图所示:从目前的资料来看一般加密狗产商都想淘汰并口型的加密狗而主推USB口的加密狗。一只USB加密狗的批发价现在大元左右。USB设备是专门为多设备连接而设计有着严格的规范从接口本身就避免了设备间的冲突。所以USB狗不会与遵守USB标准的设备有任何冲突。而因为并口只是为单设备工作设计的很多并口设备并没有考虑与其它外设公用并口的情况为降低成本往往独占了并口资源使得并口的其它设备不能正常工作。因此建议使用USB狗较好。USB接口本身具有电源线可为外设提供稳定的工作电源从而对USB狗的工作电压、功耗等要求大大降低加密狗的工作条件得到很大改善。而并口本身没有电源线并口狗要依靠并口的信号线或数据线提供电源所以在因并口负载能力低等情况下并口狗的芯片因得不到正常供电很难保证正常工作。因此建议使用USB狗较好。.加密狗加壳法一般的加密狗软件都提供傻瓜加密工具:加壳工具。这种壳是针对加密狗进行的。加密狗有内嵌和外壳两种加密方式。外壳加密就是对exe、exp、数据文件直接进行加密的方式内嵌加密是在各个语言环境中直接以函数调用形式出现的加密方式。操作系统支持Dos、WindowsxxMENTXP的各种版本如有的狗提供有种内嵌语言加密模块四种外壳加密工具。加壳式加密的软件运行界面与前述的普通壳的加密界面是类似的也是要提交需要加密的原文件然后会生成加密后的新文件这个大家不认为太神密了。内嵌一般采用供货商提供DLL就是API调用以达到调用加密模块的目的。各个狗的调用都不相同一般会提供C语言或VB语言调用的实例大家模仿这类程序即可。有论坛人士说:“心思放太多到反破解上也不是一件好事啊!”我觉得给别人破解了更不好是吧!如果不想放太多心思在反破解上建议还是采取加密狗加壳的办法方便、快捷其他时间就可以研究如何将软件完善就行了。因为有一个加密的团队在支持你呀。.加密狗写存储器法有的加密狗带有存储器大小不一有的是字节这样大家也可以将一些重要的信息放在这里面。实际上您也可以将RSA的一些数据放在这里以供程序双重检查。同样也是通过DLL调用的。十一.加密算法策略(暗桩)本章所要讲述的是:加密不要拘泥于一种形式要懂得变化之道这样才能让破解者无从下手这是我的软件加密之最精髓的一点。前文所说只是一些最基础的知识大家还需要一点变通之法,加密方法越奇怪越好,变态一些也没有关系。看过《倚天屠龙记》的话可以想想张三丰教张无忌太极拳时的那段对话哈哈。当然很多人喜欢暴破的懒得研究写注册机所以让他们多花费些时间多浪费他们的生命就要多打入一些暗桩不要用简单的“如果”、“等于”判断免得再精巧高深的加密算法成为华丽的摆设破解与反破解是一场暗战就算不能反破解也要设计多一些迷局关卡把破解者肥的拖瘦把瘦的拖死让他们痴迷、让他们上瘾、让他们欲罢不能用代码吸光他们的精血。.易数据库密码怎么泻露了易语言论坛上个别用户说自己的数据库密码被别人知道了那么我们看一下他是如何加数据库密码的代码如下:打开(取运行目录()+“工资库edb”,,,,,“KDKEKD”,)好了我们编译一下编译成一个EXE文件然后改文件后缀为TXT这样我们就可以不用PE专业工具而是直接用记事本打开了。然后在记事本中搜索这个密码大家看到了什么?看下图中反白的部分:晕死你这样编程当然数据库密码会被别人知道了。将前述代码改动一下将密码分解为若干单个字符串然后分别放于全局变量中定义一部分再在程序集变量中放一部分这样就不会有问题了。如下面的试验只改动一小部分:口令=“K”+到文本(×)+字符()+“K”+“E”+“K”+“D”+到文本(÷)+到文本(+)打开(取运行目录()+“工资库edb”,,,,,口令,)再按前述的查看方法可以看到数据库前后的密码被处理过的部分都看不到了如下图所示:大家应该明白了吧如果上述代码全部处理好的话一定不会让别人找到口令的。实际上对于重要的加密口令来说都需要分开存放并且用取字符位移或取反的方法以及加减乘除的方法都可以得到一个隐藏很深的字符串。加密第定理:相关加密的字符串一定要打乱加密。作业:制作一个“字符串搅乱器”要求如下:输入一字符串或其他类型的内容输出为经过“字符取代码取反位或位与加减乘除平方开方”等命令随机配合相加的易语言源代码。界面基本如下:作业:制作一个内窥器将你的密码或加密字存入它可以自动分解在编译好的EXE文件中查找是否有相同字符串。这是自己用易语言制作的一个工具怎么样比专用的工具还要好用吧。作业:为了不给奸人创造温馨舒适的破解环境我们要混乱我们的代码将软件中所有的子程序名全部替换成随机生成的子程序名然后加上正常的备注。例如Funcdfsafszlfv()这个函数是什么意思?恐怕只有天知道了。可以用易语言写一个易语言“名称混乱器”基本思路为:将易语言源代码复制为文本然后用混乱器将名称一一对应进行混乱然后粘贴回易语言中这样子程序名称和变量名称等都变为不可预知的字符了因此加强了保密性。但注意只有当你要发布软件时才使用之而且一定注意备份源代码。否则当你看不懂你自己的代码时可别怪我呀!字符串位置内容是否在EXE中找到是否在资源骇客中找到组件名称属性可看到组件标记属性组件内容属性组件标题属性菜单名称组件列表项目属性可看到全局变量名称看不到全局变量值内容程序集变量名称程序集变量值内容局部变量名称局部变量值内容常量名称常量值内容可看到自定义数据类型名称DLL命令名称可看到DLL库文件名在DLL库中对应命令名DLL参数名图片资源名称声音资源名称程序集名称子程序名称子程序参数名称子程序变量名称模块引用名称过滤器内容可看到信息框文本可看到.利用吴氏加密算法我们将吴涛在易语言中提供的自有加密算法称之为吴氏算法。吴涛提供了两种加自有加密算法:一种是易数据库的加密。还有一种是配置菜单中的易语言源代码口令保护。易语言的易用性就在这里了大家一定要充分利用这些现成的东西。使用易语言自带的易数据库的加密功能目前是非常可靠的这是吴涛研制的自有算法目前还没有破解易数据库的工具推出。这样就使得一些重要的东西存放在加密后的易数据库中十分安全。易语言源代码口令保护也是一个吴涛自有算法加密后的源代码连易语言公司也不能解密。因此我一般用它保护注册机和商业程序所以我的注册机和商业程序的源代码在我用过的每台电脑中都有但口令只有我知道没有口令保证打不开哈哈。下图为使用配置菜单后弹出的窗口大家可以为易语言源代码加上保护口令。.海岛挖宝听过海盗船长的故事吧故事中海盗将宝物分开存放这样即使找到一处其他地方也没有损失而且不仅如此他们也将藏宝图也分成一块一块的存放。金庸鹿鼎记的小说总看过吧皇帝将藏宝图分八册存放一一找到是非常困难的哦。韦小宝这个天才也花了两三年的时间才找到全部哦。软件中一些比较重要的文本型字符的保护也是这样你可以分开位置存放分段、分开类型存放用时再转换数据类型。分开存放是指分不同的全局变量、程序集变量与局部变量存放。加密第定理:相关加密的部分一定要分开存放。对于RSA验证也要这样不要一次性地全部验证了这样一点意义也没有。应该是软件启动时验证一部分在软件运行中验证一部分。在Debug的手册里可以看到Debug工具的局限:第一个局限是只能下个内存区域的断点每个断点不能控制超过两个字节这样内存断点不能控制超过个字节的区域。假设你的注册部分有行你可以分成个子程序调用或重复的子程序。放一些垃圾代码也不会损失什么。作业:将RSA验证的一次性验证改为分三次验证并且每次返回不同的数据类型。.随机验证随机验证很重要例如你的一处验证是一直存在的奸人就很容易地下断点跟踪了。因此在软件启动时进行一次正常验证外其他情况下的验证最好是随机的用分之一或分之一的机会进行验证这样奸人会不停地试你的软件在哪一处进行了验证因此破解的时间会相当地长。加密第定理:足够多的随机验证足以让破解者累死。随机验证包括随机进入不同的验证子程序。或随机中的最大数大一些只有分之一的机会验证。或在窗口中放上一些颜色与底图一样的图片框这样奸人不一定会点击这里但用户万一点中了就会触发验证。我们假设所有软件都能被破解包括易语言在内那么如果他破解的速度跟不上你发布新软件的速度那么他永远在破最新版而累死。或者说他破解的时间比你写一个软件的代价大这时还不如他直接写这个软件来得合算。反破解的任务之一就是让奸人累死或浪费他的生命。下面的办法也可以使用:你可以在读到待验证的注册码、公钥、注册文件后通过定义个数组存入上述同样的内容以备以后进行验证这最多浪费一些内存。验证时随机使用其中的一个进行验证由于奸人不知你用的是数组中的哪一个进行的比对而且是随机的每次验证的值都不一样不让奸人吐血才怪呢。计次循环首(计次)数组计次=“”’复制一万个公开注册码或公钥破解者知道也无所谓。计次循环尾数组取随机数()你不要立刻检查注册码份拷贝你只要以后随机找一份用就行了破解的人不知道你正在用的是那一个同时你可以事先编好且运行时不断使用一些假的读取注册码数组的调用干扰破解者。这种方法对程序的性能影响微不足到只是浪费一点内存。因为Debug对内存下断点的局限,这种情况他要下断点,累死的就是破解的人了。.不同权限验证在启动时进行一次验证是非常必要的这样让奸人知道确实是验证了以让他心理放松警惕而这次的验证只是一部分验证并没有完全验证。还有的建议在启动时将注册信息读入后不要进行验证保不定在哪里进行验证个人认为这样让破解者提高了警惕性会认为软件作者很有经验。麻痹敌人也很重要呀。例如在启动时验证通过一次验证级别加强一级然后再在其他的地方再进行验证就可以了。下面代码是确认了一个级别计次循环首(到数值(验证))已注册=计次循环尾()…………在另一个触发子程序中再通过这个级别再验证:计次循环首(已注册)计次循环首(到数值(验证))已注册=跳出循环()计次循环尾()跳出循环()计次循环尾()在其他触发子程序中再通过这个级别再验证:计次循环首(已注册)计次循环首(到数值(验证))已注册=跳出循环()计次循环尾()跳出循环()计次循环尾()有时也可以将级别降一降怎么降当然是不考虑级别直接验证了:.忽悠型的垃圾验证代码前面已讲过花指令的原理在程序中人为地再放一些垃圾代码以忽悠奸人也是一个好办法。垃圾代码就是一些假的验证代码基本上是明文的这样的代码上百上千足以让奸人累死。其实对付那些“根据跳转指令的爆破”高手来说一个办法就够他们头疼的了就是你在程序中不明显加入与判断是否正版有关的语句也不做任何提示以免让他们顺藤摸瓜而是在判断为盗版后跳转到另一个看似很合理的分支而那个分支和正版的分支代码差不多只是在计算公式或其它算法上稍动一下使其运算结果不正确这样他们就在机器码级别上就分不清哪个是对的哪个是错的了即使他们认为破解成功其实运行时得的结果错误百出他们就没兴趣了呵呵算损的吧!!!加密第定理:大量添加垃圾代码虽然是无奈之举但很管用。作业:制作一个常量迷幻器要求:制作一个常量代码自动生成器。可随机生成成百上千个易语言源代码形式可直接拷贝到易语言中成为常量。变量也可以这样制作。写好这样一个程序后就可以自动生成垃圾代码然后复制粘贴到易语言的常量表中即可。如下图所示:变量也可以这样生成不过生成的变量可以任意拷贝为全局变量或程序集变量或局部变量。制作时的名称可以为中文名称直接编译后不会在EXE文件中找到同名的中文名称。因此您可以放心地将这些名称定义为:“垃圾常量”、“垃圾变量”等等以示与正常代码进行区别。作业:制作一个代码迷乱器本次作业性质同上也是自动生成易语言的一些无用垃圾代码以迷乱奸人的破解让他找到的全是垃圾代码从而大大延长了破解时间。通过直接拷贝编辑框中的内容粘贴到您的代码中可自动完成任务如下图所示:上图所生成的是一些明文的加密方法的垃圾代码让奸人去研究这些垃圾吧。上述子程序名称最好也有时调用一下反正不会真正产生作用的用多线程调用最好。或者您平时注意多收集一些别人用于加密时的子程序拷贝到一个易语言程序中保存这样的代码作为垃圾代码放在你有用的程序中虽然增加了一些程序的体积但安全性是大大提高了。并且基本上没有牺牲软件性能与稳定性。.伪验证技术还是先举一个例子说明吧易表软件在版本前已发现有大量的注册机存在于是易表作者其后改变了加密方式易表推出后还是出现了注册机并且这种注册机注册过的软件可以使用。于是有些用户用注册机取得的注册码使用了过了一段时间当盗版用户将重要数据存入易表后突然有一天数据库被锁定了于是只好注册易表并且让易表作者为数据库解锁。从这里可以基本上判定易表新版本采用了伪验证技术即在较为明显的地方提供了一级验证这种验证方式没有经过太强的加密而二级验证在一定的条件下才触发而这个条件是检查到了用户输入了重要的数据或大量的数据或使用次数较多。基本原理是注册文件由前后两个注册码拼接而成。一般情况下只进行第一个注册码的验证而当条件成熟时进行第二个注册码验证。这是一种双赢的策略易表作者即收到了注册费付费的人还会道歉并且感谢易表作者。哈哈大家要学习这招哦。但本办法对于数据库应用及数据量大时检查最好而对于一些没有生成数据的用户无效。发布软件的时候发布自己编写的注册机弄个假破解版那么想破解的就可能不来了即使有真的破解谁会有自己给自己写假破解快啊!可能假破解版中只破解一半等用户使用了有数据了再锁定让他们注册后再给解锁付了钱还要谢谢你哈哈损招但有用!加密第定理:伪验证可以迷惑一般破解者甚至自己发布一个伪注册机。.定时验证、延时验证、客户数据集累验证过一段时间后再验证如你在年月发布一个软件那么就内定年月后触发验证机会。或您的软件是一个数据库产品那么您可以在程序中设置如果数据库大于MB时就进行验证并且最好您能确定这些数据是不重复的刻意加入的。如易表设置了伪验证这时市场上出现了新的注册机当用户用这个注册机后提示是注册成功了但当用户输入重要数据后的某个日子突然打不开数据库了用户很着急因为以为是破解成功了所以将重要的资料输入了只能拿钱向易表作者进行注册了。而且还千恩万谢后悔自己不该用破解。哈哈一举两得呀。这个方法对于数据库应用软件来说是绝好的办法。作业:制作一个算法程序放在你的数据库软件中这个子程序可以统计你的数据库软件使用时用户输入的是否是拷贝的东西还是正常的数据。当统计到时触发验证。方法思路为:可以通过查看用户有没有使用复制与粘贴快捷键或资料进行排序如果有大量重复的就说明是奸人在拷贝数据破解否则是一个资料一个资料的输入的说明是正常使用的重要资料这时进行对比就好了。本方法对有资料的破解使用者有极好的控制作用通过第条的伪验证技术与本技术结合那么就可以知道是不是正版用户并且可以锁定数据库等他注册后再给他解锁。加密第定理:加密的结果应该是双赢伪验证是一个上策。.验证与专业知识相结合技术将验证与专业知识相结合让奸人必须学习专业知识后才能真正去破解这样所花的功夫比自己写一个软件的代价还要大而有的专业知识不是专家是不知道的因此是一个较好的加密方法。前述中采用了“到数值(验证())”这样的代码返回的是或两者之间的一个数可以用乘法进行混合计算如:音量=播放位置X到数值(验证())当验证正确时返回的是这时的结果是正确的否则返回这时的结果为是错误的。这样的代码可以混合到您的专业知识中如:算命软件可将天干地支、生辰八字中的某个地方进行此类计算计算类软件可以将某种特殊的计算过程如此结合计算绘图类软件可将绘图中的算法部分加入此类计算音响设计类、机床设计软件……加密第定理:你知道的专业知识破解者不一定了解哦。让专业知识与验证相结合吧。.伪装用易语言写自有支持库大家可以将DLL文件的扩展名改为易语言的支持库文件FNE扩展名这样进行非独立编译后与其他FNE文件混合在一起甚至您可以用易语言写一个支持库将其中一部分作为验证部分。易语言的支持库文件FNE文件其实就是一个DLL文件只不过扩展名改变了而已用易语言写支持库的方法金眼睛已发过一篇贴子进行过说明请大家在易语言论坛上搜索金眼睛的贴子就可以找到了。作业:找到金眼睛关于用易语言写支持库的贴子并且自己写一个支持库。.绝妙的暗桩设置应该想到的用代码实现的暗桩前面都讲了不少下面是一些特别的暗桩供奸人品味的。大家可以在一些不起眼的地方再放一些暗桩如:在窗口最小化事件中随机验证如在某个组件鼠标被移动事件中验证有时需要将数据完整性验证放在更高一级的验证中不要一上来就检查文件是否被更改。同一验证可以使用多次这样奸人认为你已经验证过了没有必要会再验证一次而相反这时又产生了验证让奸人防不胜防。如启动时就立即检查程序完整性如果发现被更改那就立即退出程序而在一些子程序中也随机放这样的验证。更多的暗桩大家自己设计最好。加密第定理:加密重要的是暗桩的设置破解不完全就是一个无效破解。.发布不完整版本有的软件作者在发布共享软件时放在外面的是不完整版本将更多的数据资料在注册后提供。这样做也可以只是麻烦一些而已。如有的图形制作软件将图片资源另外打包用户注册后再给完全版的图片。也有的将DLL文件中的验证部分作了空处理而在注册后提供真正的注册DLL文件及注册码。还有的直接将KEY文件放在了DLL文件中另外提供。加密第定理:不要发布完整版本以静制动。.程序、数据结合加密技术把程序运行所必需要的资源放到一个数据库文件中给这个数据库设密码密码是主程序的数据摘要变换后的结果。程序运行是先验证有没有注册如果已经注册就对运行程序本身(取执行文件名())取数据摘要用自己设计的算法多次变换后形成一个字串用该字串作为数据库的密码打开数据库文件。如果打开数据库失败就说明主程序被人修改了终止程序运行即可。(不终止也没戏程序找不到运行所需的资源。)另外设计一个程序用同样的算法算出数据库密码然后给数据库加密即可。密码形成算法建议使用大数支持库。但如果是汇编高手用汇编写注册机的话会直接将支持库的所有反汇编码抄进去就可以了问题是他们有没有时间搞。.自定义算法前面讲过采用RSA与数值计算支持库交叉计算的办法这就是一种自有的算法如果能用上数值计算支持库中的矩阵、傅丽叶变换等高级功能就更好了。多重RSA交叉打乱:大家也可以多用一些RSA密钥如用个个都无所谓重要的是将这些注册码都打乱让奸人哭死。打乱的方法就是你自己独创的方法了。更多的自有算法就要靠大家自己去研究了。祝大家好运。加密第定理:加密不反对古怪和变态的方法鼓励哦。.加密框图下面给出一个加密的设计框图大家可以根据自己的实际情况改变加密的策略:图中主程序外围进行了花指令编译并且用加普通壳进行保护。脱壳了也无所谓因为设置了暗桩随机检查。图中表示主程序运行后首先进行了常规的注册码第一次验证找有没有注册文件。如果这个被破解注册码应该是一个短的RSA而真正的注册码是三个RSA的叠加。会生成伪注册机也无所谓。主程序中用暗桩的形式对窗口标题、版权信息进行验证这是考虑到如果一启动就验证这些很容易被奸人看出来从而会跳过去。因此用一些随机或分级或条件法取得不固定的验证。主程序中用暗桩的方式对加壳后主程序的完整性进行校验这个也不要放在常规的验证中否则很容易被跳过去。可以查文件长度MD或CRC都可以上。主程序中用暗桩的方式加入了反调试模块。主程序中布满垃圾验证代码。并且源代码有备注不会搞错的。主程序在某个条件下随机进行第二级验证从注册码中取第二段数据如果注册码长度不够且取不到第二段数据那么就说明已使用了伪注册机将用户的数据库锁定等他付钱来注册。主程序在一个条件下再激活验证从注册码文件中取第三段数据如果注册码长度不够且取不到第三段数据那么就说明已使用了伪注册机将用户的数据库锁定等他付钱来注册。编程中还注意将加密的字符串搅乱且分不同地方存放用吴氏加密命令加密重要数据也可加入数值计算支持库的算法也可以加入一些惩罚手段也可以再加入自己的一些算法。以下是一些人的编程体会摘录,基本未改其中的内容,在此表示感谢!附录加密已形成密码学我引用《应用密码学》作者的话:世界上有两种密码:一种是防止你的小妹妹看你的文件另一种是防止奸人阅读你的文件资料。如果把一封信锁在保险柜中把保险柜藏在纽约的某个地方…然后告诉你去看这封信。这并不是安全而是隐藏。相反如果把一封信锁在保险柜中然后把保险柜及其设计规范和许多同样的保险柜给你以便你和世界上最好的开保险柜的专家能够研究锁的装置。而你还是无法打开保险柜去读这封信这样才是安全的。意思是说一个密码系统的安全性只在于密钥的保密性而不在算法的保密性。对纯数据的加密的确是这样。对于你不愿意让他看到这些数据(数据的明文)的人用可靠的加密算法只要破解者不知道被加密数据的密码他就不可解读这些数据。但是软件的加密不同于数据的加密它只能是“隐藏”。不管你愿意不愿意让他(合法用户或Cracker)看见这些数据(软件的明文)软件最终总要在机器上运行对机器它就必须是明文。既然机器可以“看见”这些明文那么Cracker通过一些技术也可以看到这些明文。于是从理论上任何软件加密技术都可以破解。只是破解的难度不同而已。有的要让最高明的Cracker忙上几个月有的可能不费吹灰之力就被破解了。所以反盗版的任务(技术上的反盗版而非行政上的反盗版)就是增加Cracker的破解难度。让他们花费在破解软件上的成本比他破解这个软件的获利还要高。这样Cracker的破解变得毫无意义谁会花比正版软件更多的钱去买盗版软件?然而要做到“难破解”何尝容易?Sony曾宣称的超强反盗版(KeyAudio音乐CD反盗版)使用了很尖端的技术然而最近却被一枝记号笔破解了成为人们的饭后笑料!所以很多看上去很好的技术可能在Cracker面前的确不堪一击。就像马其诺防线一样Cracker不从你的防线入手而是“绕道”。这样让你的反盗版技术在你做梦也想不到的地方被Crack了。为什么会这样呢?归根到底是因为软件在机器上运行并且软件和机器是分离的这一点是关键如果软件和硬件完全绑定不能分离是可以做到象IDEA之类几乎不可破解的系统的。这将在后面谈传统软件保护技术时详细说明。对我的这个解决方案我不能保证Crack高手在几天之内不能破解它我只能说:“在这个软件中我尽量堵住了当前破解者普遍使用的方法以及“我想得到”的可能的缺口。”但是我相信倾注了我三个月心血的反盗版软件决不是一个“玩具式”的反盗版软件。附录《如何用简单方法防止破解》北极异型在Debug的手册里可以看到Debug工具的局限:第一个局限是只能下个内存区域的断点每个断点不能控制超过两个字节这样内存断点不能控制超过个字节的区域第二个局限是对多线程只能同时跟踪一个线程。假设你的注册部分有行你可以分成个子程序调用或重复的func(),func()func()。将他们随意放到程序的各个部分一定不能放在一起(自己能找到就行了)。不要用Memcpy等常用系统调用拷贝注册码尽可能自己写,像Memcpy很好写性能差点无所谓。经过编译后inline函数展开注册部分和其他代码混在一起他要写出注册机就像大海里捞针在几十万甚至上百万汇编代码里找出有用的注册部分。利用Debug的第一个局限最重要的一点是:注册码也不要放在一起假设你的注册码是位千万不要用一个位的数组放注册码你可以在程序的不同位置定义个全局字符变量每个放一位这样注册码在内存就不连续了。最好再加密处理一下(简单的字符异或就可以)验证时再解密。也不要用连续内存保存验证用到的变量尽量将用到的验证临时变量分散定义在程序的不同处再在验证中不断转移一些值到其他变量中对付暴力和Loader会比较有效。没有必要用复杂的加密算法更容易成为追踪的目标。只要你将注册部分隐藏的足够好也没有漏洞你花天写的加密算法破解者可能会花-倍的时间破解。大部分人都会放弃。你将注册做在一起就像将你的财宝放在现代保险箱里虽然非常坚固难以解密对于开锁高手两分钟就打开了。而古代海盗用的方法是将财宝埋在海岛上这样没有藏宝图对所有高手和低手都只有一条路拿一把铁撬挖可能要挖一生。程序有那么多代码反编译出来可能超过百万行,你将注册部分藏在里面藏的好就如同将财宝埋在海岛里。那些所谓的Crackme只是给高手玩儿的现代保险箱而已用原始的方法可以达到同样效果。读完注册码后不要立刻检查注册码因为读注册码肯定用到系统调用系统调用附近很容易下断点。先放到内存作为全局变量,然后你可以在程序的任何部分,任何时候,读注册码,读内存是没有任何系统调用的。.两种办法处理在内存的注册码一种方法是在检查前分散隐藏注册码这样他们无法从内存中搜索到注册码出现的位置因为他们会在注册码出现位置附近下断点。还有一种方法是正好相反你可以在读到注册码后多次将注册码在内存(用Malloc分配多处)的各个位置做大量拷贝这最多浪费一些内存。Bits的注册码做份拷贝也只用K内存。如果不用Malloc分配这些内存,那么最好和其他程序使用的全局变量交互混在一起(这样即使破解者用HEX编辑器打开并搜索你的程序中使用那部分内存的代码,也无法将正常程序数据和注册码区分出来)你不要立刻检查注册码份拷贝你只要以后随机找一份用就行了破解的人不知道你正在用的是那一个同时你可以不断生成一些假的读取内存注册码的调用干扰破解者。这种方法对程序的性能影响微不足到只是浪费一点内存。因为Debug对内存下断点的局限,这种情况他要下断点,累死的就是破解的人了。.程序多处做CRC校验文件大小检查发现不对就退出。一定要多处检查不能只检查一次。.用inline函数将注册部分分成许多小块分散到程序各处运行。最好能放在不同的线程中运行检查结束不要给任何提示在程序中的内存中做一个标志即可,提示信息要延迟一段时间出现,不要让破解者通过提示信息找到标志位置或检查结束位置否则前功尽弃。当然也可以象上面那样做个标记,随机用一个这时你不用担心破解者知道标记的位置而且标记最好不要用或,可以用一个貌似随机的值作为注册成功的标记,如何产生这个随机值只有你自己知道。什么算法无所谓最终目的就是让破解者的作用发挥不出来。和古代海岛藏宝一样你只要把检查痕迹很好擦掉分散破解高手的用处就发挥不出来。破解者玩的Crackme就是保险箱如果是开锁高手目标明确总能打开不行还可以用炸药。但到海盗的藏宝地点任何开锁高手都没有用。这种方法用的好的结果是你容易创造检查注册码的方法自我创造发挥的余地很大而对破解者会很麻烦他搞不清楚你在干什么你只要让破解者感觉象是蒙着眼睛走迷宫或者在猜没有谜题的谜语就行了而且对你来说更换算法也很容易,因为可能根本没有算法,只有谜语和迷宫。要充分利用程序反汇编后代码多这个特点,除了读注册码的时刻,其他时候根本没有系统调用,除了内存,根本无处下断点而你使用复杂的加密算法通常的结果是你麻烦破解者很容易因为各种加密算法都已经研究透了而且用复杂的加密算法的调用或系统调用立刻暴露你检查注册码的位置为暴力破解提供了方便。我和很多人一样,也是不会汇编语言,而且程序一出来就被day破解,而且几乎每一个版本它们都要破解苦于不会汇编,也不太了解破解流程,只好去看SOFTICE的手册,想了这么一个简单的方法day虽然它们经验丰富也能破解,而且似乎也逐渐了解和改进对我的程序的破解但许多破解是坏的,根本不能用而且就是被破解后,只要将这些inline调用和全局内存变量的位置稍微变一变(大概只需要个小时),它们下一次的破解又是坏的而且我还没有完全使用上面的方法,例如我还没有做份的内存拷贝或份的标记因为只是简单的用inline和将注册信息与其他全局变量混在一起,现在就已经够了,day的暴力破解就经常会破坏正常程序数据附录代码与数据结合技术《于破解过招保护你的共享软件》此文曾作为连载刊登于《电脑报》年、期如要转载请注明出自《电脑报》本人仅是一名初学者如有疏漏之处还请列位前辈们指教谢谢!crossbowcitiznet共享软件是软件业目前世界上比较热门的话题国内更是如此。成千上万的中国程序员以极大的热情投入到这个领域来都憧憬着用辛勤的劳动来获得丰厚的回报但实际并非如此绝大多数的人都弑羽而归。值得注意的是:除了选题和技术上的原因外最大的原因就是共享软件被破解(Crack)了。破解见得多了不免有些麻木。大部分作者都是新软件发布一个星期左右甚至一天之内就会在网上发现注册机或者被修改过的软件(行话称之为“爆破”)。破解者制作了英文、中文、俄文、德文等语种的注册机大肆发散不说还常常给作者寄一份外加一封挖苦辱骂的信。唉!我们得罪了谁?没日没夜地熬夜编码难道得到的就是这连绵的挖苦和不尽的羞辱吗?不!决不!我们有理由也有能力保护自己的劳动成果!但问题是:如何保护?关注国内网上关于破解资料和教程俯拾皆是而关于软件保护方面的资料则是凤毛麟角(大多都关系到什么技术垄断)这种畸形现状就导致了相当一部分朋友的加密非常脆弱甚至可以称得上是“弱智”!要知道你要面对的是已经形成团伙的众多破解高手呀国内的什么CCG、BCG国外的eGis、King、Core、TNT、DAMN和TMG皆为水平一流的破解组织。全球盗版软件不少于都是由他们的破解的技术实力连大软件公司都不可小视。看到这里你是否已经已经灰心了?别怕虽然我们理论上无法完全避免被破解但如果能够有效地拖延被破解的时间并充分打击破解者的自信心是可以让破解者无法忍受这种折磨从而最终放弃的。破解通常的做法有两种暴力破解(爆破)和写注册机。下面我就来依次讲解每种破解方法的原理和应对方法这些都是鄙人积累的一些共享软件保护经验某些关键地方还有例程讲解(Delphi代码使用C和VB的朋友可以自己稍微修改一下)希望能对新手们有些帮助能够更有效地保护自己的劳动成果。§暴力破解(爆破)这是最常见也是最简单的破解的方法。该法最适合于对付没有CRC效验的软件破解新手乐于采用。大凡共享软件验证是否注册大多数要采用if条件语句来进行判断即使你采用了什么RSA或ECC等强力加密算法也免不了使用if条件语句。呵呵这里就是共享软件最为危险的地方哦当然也是爆破手孜孜不倦所寻求的目标呀!例如你的注册子程序易语言代码类似如下:如果(签名验证(到字节集(编辑框硬件号内容),编辑框注册码内容,公匙,公共模数)=真)信息框(“注册成功!”,,)否则信息框(“注册失败!”,,)如果结束这个注册函数即使使用了强劲的RSA算法进行注册码验证可是依然很容易被破解我们只要把这里修改为:如果(签名验证(到字节集(编辑框硬件号内容),编辑框注册码内容,公匙,公共模数)=假)或如果(取反(签名验证(到字节集(编辑框硬件号内容),编辑框注册码内容,公匙,公共模数))=真))就可以破解成功了这时戏剧性的结果会产生:随便输入任何注册码都可以注册通过相反输入正确的注册码却无法通过注册。其具体操作是先反汇编或者跟踪你的程序找到判断注册码的cmp、test等汇编指令后的关键跳转指令处通常是je、jz之类的汇编指令把它们修改为jne或jnz即可这样常常只需要修改一个字节就可以完美破解之。令人遗憾的是目前大部分共享软件都是这样进行判断的这也是为什么网上被破解的软件铺天盖地的主要原因。因为这样破解实在是太简单了……难道没有什么可以防止的方法吗?当然有啊!只要把软件的关键代码嵌入到注册码或者注册文件中就可以充分防止破解。但现在问题是怎么嵌入呢?最简单的方法就是把关键代码(你的软件功能限制部分最关键而且最简单的一个函数)做成一个小Dll(动态链接库)用强力对称算法加密(密匙可以是主程序某一固定不变的部分或壳的特征值)后生成一个注册文件(License文件呵呵格式只有你知道哦!)或者Base编码后生成一个注册表文件用户可以双击导入注册表内。效验流程如下:已注册用户验证注册码时先验证有没有文件没有文件者自然受限制的功能无法使用。如果有注册文件解密之即生成一个小临时文件。如果主程序被脱壳或者被修改(爆破)自然特征值密码不符解密出来的肯定都是垃圾码没有一点用处。只有没有被修改的主程序才能正确的解码而且当然只有解密正确的文件才是一个真正的Dll文件才能被GetProcAddress函数找到欲调用的关键函数地址。这样只有已注册用户才可以享受到你软件的全部功能了。如此一来Cracker破解你的软件就变得很困难了:首先他如果没有注册文件即使他把主程序脱壳了由于受限制的部分和注册文件是关联的他也根本无法修补完整。第二即使他得到了你的注册文件由于是加密文件他也无法直接利用之这样就逼迫他去拆解你的算法这可是他们最不愿意的碰到的事情哦!如果到了这一步我想的Cracker都是会放弃的呵呵只有真正对加密算法有研究的Cracker高手才会继续破解下去。第三你是可以用些小技巧来使他的生活更加痛苦一些的呵呵。这里我推荐大家使用DSA公开密匙加密算法它和RSA一样可以进行数字签名(RSA还可以加密DSA则只能进行数字签名)。我这里选用它的原因就是它有一项非常实用的特性:随机数填充机制。即DSA每次签名都要使用一个随机数K正因为有这个K的存在即使是相同的用户名和机器识别码由DSA加密过的每份注册文件都不会相同。这对Cracker拆解你的注册文件来说是一个极大的障碍。第四即使他得到了解密后的Dll文件他也需要大幅度地修改主程序或者把你的Dll部分的关键代码拆出来填到主可执行文件中。呵呵这就看他对PE文件格式理解得如何了。即使这样如果你的程序中有大量的Hash效验和死机代码呵呵你就耐心等着我们可爱的Cracker同志吐血吧……:)所以记住啊:用完这个Dll临时文件后立即从内存中卸载此Dll并删掉而且注意在解密之前探测一下系统中有没有FileMon这个威胁极大的探测器呀!{探测FileMon} functionDetectFileMon:BooleanbeginifCreateFile(PChar('FILEVXD'),GENERICREADorGENERICWRITE,FILESHAREREADorFILESHAREWRITE,nil,OPENEXISTING,FILEATTRIBUTENORMAL,)<>INVALIDHANDLEVALUEthenResult:=True如果有就Down机!elseResult:=Falseend当然你可以保护得更好一些:可以不采用临时Dll而把解密后的关键代码用WriteProcessMemory这个API函数写入到主可执行文件自己进程被提交(Committed)的内存页面的指定位置去。这样由于磁盘上没有解密后的临时文件破解更加困难。事实上目前世界上最强劲的专业保护软件Armadillo就是用的这种方法。而且这种方法可以充分防止被调试器Dump。但实现起来比较困难尤其是在WinNT以后的操作系统中。由于这种方法将注册文件和受限制代码唯一关联爆破手拿到你的软件也只有干瞪眼。建议大家都给共享软件加上功能限制这样比时间和次数限制更加安全。§写注册机顾名思义这种方法就是模仿你的注册码生成算法或者逆向注册码验证算法而写出来的和你一模一样的注册机。这玩意威胁极大被爆破了还可以升级。如果被写出注册机呵呵你的软件只好免费了。或者你必须更换算法但以前注册过的合法用户都得被迫更换注册码了累死你!呵呵……上面的方法虽然可以避免爆破但注册机的威胁还是存在的。Cracker要写注册机必须详细研究你软件的验证模块这必须先将你的软件脱壳再反汇编或者用调试器跟踪。市面上许多加壳和保护软件都吹嘘不可能被脱壳令人可惜的是到目前为止没有一个软件兑现了它们的诺言。由于CPU最终执行的都是有效指令所以等你的程序自解压完成后再从内存中Dump出来就可以实现脱壳。因此不要在壳上面花很多功夫因为没有这个必要。反汇编是和调试器跟踪也都是不可能防止的因为所有的Win程序都是必须通过API来调用Windows系统中的关键Dll的(如Kerneldll、GDIdll等)然而API是可以Hook的。我们只能从自己的代码着手来保护我们的劳动果实了。为了自己调试和以后维护的方便我们一般采用有意义的名字给我们的函数命名可这给了Cracker可乘之机。例如这样的函数是什么意思大家应该是一目了然吧?IsRegistered(),IsLicensed(),LicenseVerify(),CheckReg()这样Cracker就可以轻松地从数千个函数中找到他的目标你的注册码效验函数!而且破解Delphi编写的软件还有一件TMG小组的破解利器DeDe它可以轻松看到你软件里的Form、Unit和函数名还可以反汇编一部分代码更是可以和WinDASM合作反汇编更多的代码对Delphi软件威胁极大。为了不给Cracker创造温馨舒适的破解环境我们要混乱(Obfuscate)我们的代码将软件中所有的函数名全部替换成随机生成的函数名。例如Funcdfsafszlfv()这个函数是什么意思?恐怕只有天知道了。网上有现成的代码混乱器你按你使用的编程语言的种类可以找到一些。但注意只有当你要发布软件时才使用之而且一定注意备份源代码。否则当你看不懂你自己的代码时可别怪我呀!另外一定要使用公开密匙算法保护你的软件RSA、DSA和ElGamal之类的算法都可以从网上找到。但注意:将你算法单元中的所有涉及到算法名称的字符串全部改名。避免被Cracker发现你用的算法而模仿写出注册机来!你还可以张冠李戴明明用的DSA将名字全部替换成RSA呵呵让他模仿去吧!其它算法如对称算法和Hash算法都也要注意改名否则这样:EncryptedCode=Blowfish(MD(UserName),MD(Key))你的加密算法使用了Blowfish(对称算法)和MD(Hash算法)虽然我不了解Blowfish和MD算法的原理也不会逆向它们但我了解你的效验算法的流程和算法名我马上就可以从网上找到类似的Blowfish和MD算法包从而模拟你的软件仿造出注册机啊?!真是……$*($#!如果你用的什么其它不常见的算法(如Skipjack(NASA美国航天局标准算法),LOKI,WAY,Safer之类不出名但强度很高的算法)并且全部改名就让他们去研究软件中成堆的如下代码是什么加密算法吧!:):BFMOVEAX,EBP:BFCALL:BFPUSHEAX:BFMOVEAX,EBP:BFCCALLC:BFLEAECX,EBP:BFPOPEDX:BFCALLBC当然最好把Hash算法也全部改名给会给他们制造更多的困难。但注意MD和SHA之类的Hash的初始值会被Cracker从内存中找到这样他就知道了你用的Hash了。所有建议同时使用MD的变形算法RipeMD(RMD)或和其它的Hash如Tiger,Haval等算法。另外请注意要经常效验你的程序是否被修改(Hash效验)如果被修改则退出。但请注意有些病毒会修改进程的句柄表和它指向的内核对象这样病毒就可以直接修改运行中的PE文件而感染之了另外还有网络传输错误的问题也会导致软件CRC出错。因此请不要认为可执行文件的CRC不符而此时程序已被脱壳了。其实程序被脱壳最明显的标志是其大小明显大于脱壳前。M的PE文件被UPX、ASPack之类的软件压缩后通常只有左右。如果你的软件在运行中发现自己的大小大于K我想你应该知道如何做了吧?呵呵还有一点调试器对我们的威胁很大我们不会肯定让Cracker们舒舒服服地使用SoftICE、TRW和OllyDbg来调试我们的程序。除了常用的MeItICE方法外这里我给一个我写的方法:{检查自己的进程的父进程是否为Explorerexe否则是被调试器加载了}{不过注意控制台程序的父进程在WinNT下是Cmdexe哦!}{注意加载TlHelppas单元}procedureCheckParentProcvar检查自己的进程的父进程Pn:TProcesseNtrysHandle:THandleH,ExplProc,ParentProc:HwndFound:BooleanBuffer:arrayofCharPath:stringbeginH:=ExplProc:=ParentProc:=得到Windows的目录SetString(Path,Buffer,GetWindowsDirectory(Buffer,Sizeof(Buffer)))Path:=UpperCase(Path)'EXPLOREREXE'得到Explorer的路径得到所有进程的列表快照sHandle:=CreateToolHelpSnapShot(THCSSNAPALL,)Found:=ProcessFirst(sHandle,Pn)查找进程whileFounddo遍历所有进程beginifPnszExeFile=ParamStr()then自己的进程beginParentProc:=PnthParentProcessID得到父进程的进程ID父进程的句柄H:=OpenProcess(PROCESSALLACCESS,True,PnthParentProcessID)endelseifUpperCase(PnszExeFile)=PaththenExplProc:=PnthProcessIDExplorer的PIDFound:=ProcessNext(sHandle,Pn)查找下一个end嗯父进程不是Explorer是调试器……ifParentProc<>ExplProcthenbeginTerminateProcess(H,)杀之!除之而后快耶!:)你还可以加上其它什么死机代码来消遣消遣这位可爱的Cracker:)endend你可以在Delphi或者VC中试试呵呵是不是把Delphi和VC杀掉了因为你现在用的是Delphi和VC的内置调试器来运行你的程序的当然它会六亲不认了呵呵!调试的时候你还是把它注释掉吧发布时别忘记激活哟!最后一个问题这也是一个非常重要的问题:保护你的字符串!!!字符串在注册模块中非常重要!当一个富有经验的Cracker破解你的软件时首先做的就是摄取你的字符串。比如他会输入错误的注册码得到你关于错误注册码的提示通常是“无效的注册码请重新输入!”或者“Invalidkey,pleaseinputagain!”等等然后用OllyDbg下断点调试或者用WinDASM、IDAPro等静态分析工具在被他脱壳后的程序中查找那个字符串找到后进行分析。因此请一定加密你的字符串!!!一定!!!使用时再临时解密出来而且要尽量少使用消息提示框避免被Cracker找到漏洞。加密字符串不需要太复杂的算法随便找一个快速的对称算法就可以了。最后提醒你一句不要在加密上花太多的功夫!你应该把更多的时间和精力都用来完善你的软件这样会更合算。借用一位前辈的话来忠告大家吧:花点时间考虑你自己的软件看看它是否值得保护?如果没人用你的软件保护也就没有意义了不要过高估计你的软件“对世界的重要性”!PAG

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/57

易语言软件加密技术

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利