理论上不存在无法破解的软件,但也并不是说破解软件比开拓随意马虎一万倍,
防破解的目的不是要做一个无法破解的软件,而是让破解软件的本钱远大于购买软件的本钱现在笔者简单演出几个有代表性的软件破解,当然,要看懂下面的内容,须要一点点C措辞的编程根本.

我们先来一个最最大略的软件破解,假设我们写了一个软件,它的注册手段代码如下
#include "stdio.h"#include "string.h"int main(){char Key[32];printf("请输入注册码:");gets(Key);if (strcmp(Key,"abc123456")==0)printf("注册成功");elseprintf("注册失落败");}
把他编译成exe,运行一下
要破解怎么办呢?超大略的,你把这个程序后缀改成txt然后打开,搜索注册码.然后翻一翻key就找到了
别笑,就算是本日,仍旧有一大堆软件采取这种软件保护机制,不过这类软件要不大多不怎么值钱比如xx管理系统,打算器之类的,要不便是软件作者别有用心防君子不防小人.你可能会问了,问题出在那了呢,这类保护机制的问题是,目前大部分的编译器都会将字符串常量直接存储在可实行文件构造中,以是你假如硬编码key,那么上面这种破解方法险些是屡试不爽乃至不须要什么逆向破解知识就能搞定.
那么,让我们进入防破解V2.0时期,为了与时俱进,我们轻微把上面的代码改一下
#include "stdio.h"#include "string.h"#include "windows.h"#include "math.h"int main(){char iKey[32];char Key[32];char ID[32];int iID=0xabc1d3f;sprintf(Key,"%x",iID8+123456);printf("你的机器码是%x\n",iID);printf("请输入注册码:");gets(iKey);if (strcmp(Key,iKey)==0)MessageBoxA(0,"注册成功","",MB_OK);elseMessageBoxA(0,"注册失落败","",MB_OK);}
现在"TXT"破解法已经不中用了,你看,key找不到了
怎么样,这种保护手段是不是熟习的味道熟习的配方,这个机器码可以从网卡MAC,CPU型号,内存大小等等等等去天生,当然,key的算法也可以拉上MD5,SHA等等等等手段来弄而不是简大略单的乘一个8再加上123456,总之从机器码到注册码的算法你能玩出花.
但,这又有什么卵用呢,打开ollydbg,对MessageBoxA下断点(也便是弹窗的函数)
然后输入一个缺点的注册码,命中断点,很快,我们来到了判断注册码是否精确的逻辑处理代码
你猜猜,假如我们把这个判断注册码是否精确的代码给它删了)(nop指令添补)会怎么样
你会创造,握草,不管我输入什么,都是注册成功
那么问题出在哪了呢,你创造,万恶之源都始于那个MessageBox函数,正是这个函数,让我们顺藤摸瓜找到了注册码判断代码,时至今日,仍旧有非常非常大的一部分软件利用着这个二三十年前就在用的保护手段,每年去世于MessageBox被破解的软件,围起来可以绕地球三圈.也便是这个保护机制,造诣了所谓软件发布后十分钟就被破解的悲惨结局.
这个时候,你痛定思痛,mmp,有内鬼,既然MessageBox不好用,那我不用便是了,于是你把代码改成下面这样
#include "stdio.h"#include "string.h"#include "windows.h"#include "math.h"int main(){char iKey[32];char Key[32];char ID[32];int iID=0xabc1d3f;sprintf(Key,"%x",iID8+123456);printf("你的机器码是%x\n",iID);printf("请输入注册码:");gets(iKey);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);}
你看,啧.只要你注册码没输对,我直接把软件退出(或者跳到别的地方),看你怎么办
可惜,内鬼年年有,"注册成功"几个字还是出卖了你,打开ollydbg,查找字符串参考,然后双击
哦豁,塌台,换汤不换药,还是给逮住了.
你察觉到这样一个地方判断注册码实在不靠谱,以是,你改变了策略,把检讨注册码的代码复制了n遍,或者逐字符检讨注册码的准确性,还有人将注册成功等字样进行加密或稠浊,等到要用的时候再取出来
#include "stdio.h"#include "string.h"#include "windows.h"#include "math.h"int main(){char iKey[32];char Key[32];char ID[32];int iID=0xabc1d3f;sprintf(Key,"%x",iID8+123456);printf("你的机器码是%x\n",iID);printf("请输入注册码:");gets(iKey);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);}
你放心,不管你复制多少次,要找出来都是韶光问题,吃枣是会被破解的.同时只要你要用到明笔墨符串你迟早还是要解密的,这种手段类似于加upx压缩壳,只须要等待数据解压完成,所有的东西又都是明文的了。因此比较聪明的做法是,要用时解密,用完后立时把明文抹掉,这样说不定能拖延更长的韶光。但这仍旧也是韶光问题。
你开始创造,与其揪出内鬼,不如主动出击,也便是我们著名的与其办理问题不如办理提出问题的人,终于,你开始对调试器下手了,然后你成功进化到防破解V2.5时期.
这个时候,不得不先容一个老掉牙的但非常有名的函数
IsDebugPresent
你可能有点懵,这个函数是干啥子用的?,大略来说,当我们破解一个程序的时候,大部分情形下我们会打开一个叫调试器的东西来对软件进行反编译剖析,诶,重点就在这,IsDebugPresent这个函数,就能检测我们的程序有没有被一个调试器附加,你想啊,正常情形我们用软件谁会吃饱撑着附加一个调试器来用,你假如用调试器附加我,你肯定便是想干坏事.
于是,你开始把代码写成这样:
#include "stdio.h"#include "string.h"#include "windows.h"#include "math.h"int main(){char iKey[32];char Key[32];char ID[32];int iID=0xabc1d3f;if (IsDebuggerPresent()){MessageBoxA(NULL,"小样,就你还破解我的程序,回家喝奶去吧","",MB_OK);return 0;}sprintf(Key,"%x",iID8+123456);printf("你的机器码是%x\n",iID);printf("请输入注册码:");gets(iKey);if (strcmp(Key,iKey)==0)printf("注册成功");elseexit(0);}
于是,当下次再ollydbg加载调试你的程序的时候,就会涌现下面的情景
曾经很长一段韶光(包括现在),很多软件或加密壳都会检讨是否有调试器正在调试自己,比如tls段会在加载时被实行,如果检讨到自己正在被人调试破解,就会设置一个tag让程序跑到没啥用的地方去或者直接退出重新,也有利用变形的PE头让调试器无法加载,总之手段很多.
可惜这还是没什么卵用,比如IsDebugPresent可以通过修正FS寄存器的标志位来让它彻底哑火,同样的手段包括但不限于检讨int 3软中断,Raw Call,Query PEB,检讨Debug Privilege和父进程等等等等,都有绕过的办法.
暗桩嘛,只要你插,一个一个拔总是拔的完的
好了,还有啥办法不,放心道高一尺魔高一丈,现在我们来到了现在最盛行的,防破解V3.0 VMP时期,
先澄清一下,这里的VMP并不是VMP壳,它全程叫Virtual Machine Protection,大略来说,为啥我们破解软件那么得心应手,还不是由于x86 x64 arm的那堆汇编指令集我们太熟习了呗.假如我们自己发明一套指令集,然后用这个指令集写程序并运行在我们自己的虚拟机上,那么,破解者一进来,看到的不便是一脸懵逼了么
可惜的是,VM的运行机制决定了它可能造成几十倍乃至几百倍的性能丢失,以是,VMP必须用于保护那种关键且不是性能瓶颈的代码,否者你的软件跑起来就会像
那么,VMP保护机制是完美的么,当然不是,VMP说白了,也只能做到延长剖析韶光,你假如把VMP做的足够繁芜,足够让一个Cracker醉生梦去世了,但是如果这个韶光足够久,你的软件足够的值钱让人有希望来破解, 他们仍旧可以充分地剖析你VM机的运行机制,当你的VM机运行机制被摸清了,软件就离沦陷不远了.
不过你可以放心,剖析VM机实行机理,可比自己写VM机要头疼多了,毕竟一个是你须要通过代码来揣测别人的思路,而另一个本身是自己的思路转为代码,因此基于这点可以说:
破解软件比制作软件大略,在很多情形下,不存在的!
你可能会问了,为什么现在市情上那么多软件,那么多游戏,购买了那么多听起来那么牛逼的保护软件,结果还是被破解了.而且刚发出来一天就被破解了.
实在很大的问题就出在这个商业保护软件(比如保护壳)上,由于这类保护壳大多都会被卖给一大票的软件开拓商,有一句话叫树大招风,就像现在盛行的VMP保护机制,之以是能保护,是由于其运行机理破解者不明确,如果你这个软件就给自己用,而且你这软件还不怎么值钱,除非大佬空虚寂寞冷,不然谁会有那闲工夫去剖析你的虚拟机是怎么跑的,但商业保护壳不同,不论其采取什么样的保护机制,只要剖析过一遍搞清楚了,险些所有利用这类保护机制的软件都会沦陷,而且在灰色家当上.这种破解乃至还颇有利可图,只要这个保护机制不更新,一次投入,长期回报.于是只有说在第一次剖析时会花上很长的韶光,之后就都只是玩套路了.
因此,购买商业保护壳,实在其保护效果并没有想象中的那么强,很可能在灰色家傍边形同虚设,乃至一个具有反逆向根本的码农自己写的说不定还更有效果.当然一个软件是被破解概率高不高,仍旧是我之条件到的那句话:防破解不是让软件无法破解,而是让破解软件的本钱远大于购买软件的本钱
毕竟你说你一个软件拿来开源都没人爱用,你还整天琢磨着怎么才不会被破解,寒掺不老铁.
那么你会开始问了,有没有更给力点的防破解技能?彷佛之前说的说来说去,无非便是拖延韶光,诶,这个我们要摆正心态,不论是加密还是破解,实在说白了终极便是拖延韶光,你看那些加密算法,依据其数学理论,如果要破解,它的打算量就算你把全天下的打算机加起来一块算,也够你算三个天下末日了.
不过别担心,更给力的方法还是有的,你想啊,为什么我们之前说了那么多软件都被破解了,最最关键的一个缘故原由,是我们能搞到代码,纵然这个代码已经是经由编译后的一堆汇编指令,但只要我们有这堆代码,迟早我们还是能搞懂这个程序是怎么回事的,然后我们就可以对症下药干坏事.
这就像给你有一包面粉,而程序便是一个面包机,你把面粉塞进面包机做出了面包,有天你好奇啊,这面包机咋整咋整就出来一块面包了呢,你就动手把面包机拆了,然后你就知道面包机是怎么回事了.
以是有没有办法不让用户知道我们的代码是什么样的呢,就像你把面粉交给了面包师傅做面包,这个面包是怎么做的,你就只能指望看面包师傅有没有这个心情见告你了.
为此,有请早期一个相称盛行且普遍的游戏防破解工具(物理)
你现在可能表情是一脸问号,但我没和你开玩笑,在2000年时期,大部分的游戏运行在光盘CD中,但盗版也随意马虎啊,把光盘里的数据一复制下来,然后就可以复制出一万张盗版光碟,以是游戏厂商们就想办法,想来想去就想到了榔头
其操作方法很大略,拿榔头和钉子,在光盘上钉几条刮痕出来,造成人工的坏道,然后再将数据烧录到精确的扇区中,这样下来虽然程序还是可以精确运行,但是当秃顶读盘读到这个坏道的时候,就会读不过去,于是你会创造打开光盘后,没有关键的文件,这样你就没办法将游戏或者说程序拷贝出来了,同时还会对坏道的位置做一个标记,游戏运行时也会检讨这个标记,那么想要盗版你就也得拿起榔头在光盘同样的位置上砸出同样的刮痕出来,当然,这险些是不可能的.
当年这个技能当年又叫防盗环技能,但不管它的名字叫的多高大上,实质上就和榔头钉钉子一模一样是同样的东西,可惜虚拟光驱涌现后,同样有办法复刻光盘的统统数据(包括坏道),以是,这个技能拿到本日来看并没有什么卵用.不过这仍旧给了我们足够的启示.
现在让我们进入防破解V3.x时期,之以是不叫V4.0是由于这类技能很早就有并且比VMP保护盛行的韶光还早的多,而且它可能是最近接理论上不可破解的防破解手段.
我们先聊的是加密狗或者又叫Ukey保护,便是运行软件你须要插入一个U盘一样的东西到电脑上,实际上这个Ukey是一个微型电脑,软件的一些关键的算法和代码,都在这个UKey的芯片里,当我们PC上的软件运行后,当我们须要实行这类关键算法时,我们会向这个Ukey通报数据,然后UKey将结果打算出来,返回给PC的软件上,这样就避免了用户直接能够逆向取得关键的算法代码,破解也就无从谈起了.这也便是为什么到了本日,Ukey保护仍旧非常的盛行.
可惜,UKey保护仍旧有诸多的限定,首先便是带着一个Ukey贼麻烦,万一UKey丢了补办是一个麻烦事,运行软件插Ukey也是个神烦的事情,同时,UKey的性能决定了它可能不能实行一些过于花费性能和内存空间的代码,数据交互也因带宽和通讯延迟会造成性能丢失,以是它和VMP保护机制一样,同样不是一个省油的灯,同时开拓职员的水平不到位,该保护的代码没保护,保护来没啥用的代码塞了一堆,也会给Cracker带来机会,而且只要你的软件够值钱,你是不是太瞧不起我华强北了
把Ukey拆开来,利用某种"药水"剥开外层找到内部的芯片并接上已经熔断的"读引脚"(有些芯片连这步都省了,直接热风枪一吹接板读ROM) 然后再把芯片的代码给读出来
于是,UKey保护也宣告沦陷.
你创造,只假如把实体的东西交到用户的手上,迟早会出问题,以是,这个Ukey保护现在大部分情形下变成了带数字证书的网络验证模式,这类的关键代码从Ukey转移到了做事器上,数据交互通过网络来做.实在这种保护机制和Ukey保护事理是一样的并没有什么实质的差异,但同样处于网络带宽也延迟的考虑,同样具有一定的性能丢失和设计毛病.
须要重点提及的是,这类网络保护的手段必须专门设计以保护程序中的一系列关键"功能"代码而不是"防破解"代码(比如代码解密,注册验证),由于后者险些没啥卵用仍旧能够将"防破解"的代码打消或Dump解密代码或假造本地做事器实现破解.以是你指望一堆什么x盾,x宝一键能一劳永逸一键保护程序,程序必须经由专业码农而不是彩笔专门的设计才能起到其应有的保护效果
但现实情形是,处于用户离线运行和性能延迟瓶颈的考虑,这种网络保护设计的每每都有很大的毛病,因此,并不是说这东西不好,而是空想很丰满现实很骨干,实在无能为力啊.
当然,代码保护的手段很多且花样玩法大概多,本文只是初略先容几个比较有代表性的破解和反破解手段.如有兴趣想要学:







