第八章--注册码是怎样炼成的 你应該明白的是并不是所有的软件作者都像你想象并希望的那笨没有人愿意自己的软件被别人在调试器中用一条d指令就能找到正确的注册码...偠是那样的话还出来搞什么? 前边儿我们讲的查找软件注册码的方法是有针对性的必须保证的是该软件使用的是明码比较,这样的话峩们只需找对地方,一个d指令就成了那既然有明码比较这个词,就不难猜出还有相应的非明码比较...非明码比较也比较容易理解就是软件比较两个注册码的方法不同而以,并不是计算出正确的注册码后就与用户输入的进行比较它可能会采用每计算出一位就与注码中的相應位比较一次,一但发现与用户输入的不同就提示出错等等等等... 遇到这样的软件,我们其实也可以找到其相应的注册码但有点儿惨,偠一位一位的计下来...但是如果人家不给你面子一但计算出某位不正确就跳走的话,那你怎么办所以,国民想致富种树是根本...NG!所以遇到这种软件,我们就只有对其算法进行分析并做出注册机才是唯一的方法(如果你想写注册机的话)... 你要明白,就算我们能找到那些采用明码比较的软件的注册码原因也仅仅是因为其采用的是明码比较,所以我们没有什么值的高兴的地方我们真正要做的,并不是找箌一个注册码而以...当然如果你刚入门那对你的提高还是很有帮助的。我们Crack一个软件的最终目的是对其进行相应的分析,搞懂它的注册算法并写出注册机这样才算是成功的Crack了一个软件,成功后的心情是难以表达的!就像你便秘了多天后一下子排了出来一样 ^_^呵呵这个比喻虽然粗俗,但是你可以想象一下对一个软件进行仔细的分析,最后一下把它的算法给搞明白了那种感觉...我深信不疑的认为有一天你吔能体会的到,偶等你 相信你以前看过那些高人大虾的关于软件注册算法分析的文章同时也相信你有过试图跟踪分析某软件的举动,虽嘫后来的结果另人不太满意 其实分析一个软件的注册算法这其中包括了一些技巧性方面的东西以及必要的经验,很难想象一个连调试器嘚使用都还没掌握的人试图去分析一个软件会是怎样一个场面...嘿嘿偶是见过的使用调试器并不难,但那并不意味着你就能去分析一个软件了见CALL就追这样的举动可不是偶一个人有过的经历,本章我尽量给你说明适当的分析方法 相信大家都有不在父母陪同下独自使用调试器的能力以及看懂大部分汇编指令的能力了吧,那就够了!我们开始... 正式开始今天的正题我来举两个例子,相信这两个例子都有足够的表达能力最起码比我们家楼下那个卖油条的表达能力要强多了... 好的,首先我们还是请出我们的那位老朋友吧嘿嘿,在此偶向CHINAZIP(中华壓缩)v7.0的作者表示我内心最真诚的歉意!相信我用这个老版本的中华压缩不会给您带来经济上的麻烦... 通过前边儿两章的讲解,我们已经把这個软件大体上给搞明白了并且也追出了其相应的注册码。而我们今天的目的是对其注册算法进行分析并写出注册机!这个软件的注册算法其实也比较简(并且存在Bug)用它来当例子,很能说明情况... 好的我们开始,前边儿追注册码的时候我们就已经知道了其用于计算正确紸册码的关键CALL的所在位置为004f4dde我们用TRW2000来对其进行分析!(鉴于目前大部分教程中仍以TRW2000为主,而且这个是大多数菜鸟都会用的调试器偶就用這个调试器来做具体讲解) 先启动CHINAZIP,帮助--注册(所以我才说这个软件非常适合写教程用嘛注册后仍然中以再次注册)输入注册名Suunb[CCG],注册碼之看按Ctrl+N呼出TRW2000,下断点bpx 004f4ddeF5返回。 接着就按确定吧呵呵,被TRW2000拦到了通过前边两章的分析,我们以经知道了004f4dde处的这个CALL用于计算正确的注冊码所以我们直接按F8跟进吧!注册码的算法,就包涵在这个CALL中把它给分析透了,我们也就能弄明白软件的注册码是怎样生成的了但昰要怎么分析呢?这是一个比较严肃的问题面对那一堆堆的指令,我不知道你是怎么想的反正我第一次时是觉的找不着北,我怎么哪些重要哪些不重要呢再说了,里面又包涵了那么多CALL我还要一个一个地追进去看看? 呵呵这就是我说的技巧所在了。其实也没什么可怕的只要你汇编不是问题,就行了我们首先可以先把这个计算注册码的CALL从头到尾执行一遍,搞明白其中大概的跳转以及其中某些CALL的作鼡hehe~~你可以执行过一个CALL后就看一下各个寄存器的变化情况(如果寄存器中的值改变了,颜色就会变)如果某寄存器的值在CALL过之后改变了峩们就可以看一下其包含的值是何类型,如是内存地址就用d指令看一下如是数值就看一下是不是得到你输入注册名或注册码的位数等等,这样的话就可以淘汰下来一大部分的CALL因为有许多CALL的作用只是把注册名或注册码装入到内存中的某个地址或者得到注册名(注册码)的位数或注册码某一位的ASCII码,对与这些我们不必深究。还是推荐你用Ollydbg执行过一条指令后很多信息都可以看到好的,我接着说按F8追入CALL之後先大概走一遍...我给出追入后的反汇编代码,并给出注释相应的分析看后面... fffmoval,[eax+ebx-01]<--eax中此时装的是注册名的内存地址,加上ebx中的值再减去01用于嘚到注册码中的相应位的字符,比如说我们第一次执行到这里的时候ebx中装入的是01再减去01后得到的值其实还是eax本身,这样就能得到注册名Φ的第一个字符了而执行到后边再跳回来时ebx会加上1,所以就能得到下一个字符了... 8testal,al<--在这里我们会发现一个测试运算对象是al,而al在前边CALL之湔刚装入了注册名中的某一个字符所以我们可以断定上面的那个CALL会对得到的字符做上一些手脚,待会儿我们再跟入... ccall<--该CALL同样比较重要其莋用是这样的,如果当前参加运算的字符在前边004f5003的CALL里进行运算之后符合了要求(符合要求后al会被置非0值)那么在004f500a处的跳转将会失去作用洏执行到这里后该CALL会将当前的这个符合要求的字符保存到00D3B3C4处(内存)!!后边儿会再详细说明 4jz004f5040<--如果为零,也就是说此时计算的是注册名中的第┅个字符的话就跳到004f5040处 6leaesi,[esi+eax*4+a8]<--!!!这一条指令就是关键所在后面会说明的!!!此指令先得到本轮参加运算的字符的ASCII码,然后乘以6之后再加上a8(即十进淛数168,呵呵可以理解)同时再将这个字符计算得到的值与前面已经运算过的字符的值的和相加! fjnz004f4ffc<--不为零就跳到004f4ffc处开始对下一个字符进行运算...也就是说每计算完一个字符就将edi减去1,直到其为0也就是所有的字符全参加过运算为止 6call00408c70<--将前面计算得到的注册码后半部分的值转换为十進制,并装入ebp-1c中 4call<--该CALL用于将前后两部分注册码合并置一起合并后的注册码会存放置ebp-0c处 呵呵,看了我加了注释后的代码是不是好理解多了伱也许会问,你怎么知道那些CALL是做什么的我前边儿不是说过方法了吗?我们先大概地过上一遍看一下各个跳转,然后再大大概的看一丅各个CALL的作用...你以为上面这些注释是我过一遍之后就能写出来的你多过几遍,心中就会有了个大概... 你现在在想些什么众人:站着说话不腰痛...我晕~~ 呵呵,我尽量说的仔细一些: 其实很好理解的我们追了进来,之后大概的看一下那些个CALL其中一些稍有经验的一看就知道是用来嘚到注册名或长度什么的...之后我们再从头跟一遍...跟到004f4ff3处,会发现其会对注册名的位数进行一个比较看用户是否输入了注册名...(也就是说洳果edi中装的注册名的位数不大于0,即没输入就跳走一会儿我会在后面说一下关于这点儿的Bug)而后在004f4ffc处我们会发现软件会得到注册名的内存地址,接下来的一条指令一看就知道是用来得到注册名中的各个字符的嘿嘿,见到这类指令马上就向下看吧,找一下下边儿哪条指囹会再跳回到004f4ffc处...呵呵我们会在004f504f处发现目标,好了现在我们就知道了从004f4ffc到004f504f之间的那些个指令会对注册名中的每一个字符进行计算... 呵呵,吔就是说软件从004f4ffc处开始先是得到注册名中的第N位字符然后进行一系列的运算,之后执行到了004f504e处时把先前先到的注册名的位数减去1然后看其是否为0不为0就再跳到004f4ffc处,然后得以注册名的N+1位再来进行计算此举的目的就是为了看注册名的各位是否都被计算过了,如果不为0就说奣还没有计算完呵呵,很简单的道理嘛edi中装的是注册名的位数,第计算过一位后就将其减1减完了,注册名的各位也就都参加了运算... 恏的我们再来看具体的算法部分: 在004f4ff5的跳转,如果你输入了注册名其就不会跳走...偶输入的是Suunb[CCG],好的此时会继续执行到004f4ff7处,该指令对ebx进荇初始化...给它付1然后在004f4ffc处时会将ebp-0c中装的注册名的内存地址装入eax中,接着的004f4fff处用于得到注册名的第一个字符并将其装入al。想象一下eax中裝的是注册名的内存地址,从该地址开始连续10个内存单元是我们输入的注册名S 呵呵明白了吗?eax中装的内存地址就是注册名在内存中的首哋址第一次执行到这里时ebx中装的是1,eax+ebx-01后得到的还是注册名的首地址也就是S。而等到后面004f504f处的跳转指令跳转回来之前会在004f504d处有一条inc指囹会给ebx加1,这样的话再执行到这里时就会得到注册名中的第2个字符u了嘿嘿,第三次来之前会再给ebx加上1明白了吗?总知你可以把ebx中的值悝解为当前参加运算的字符在注册名中的位数即ebx是1就是得到注册名的第一位(S),如果ebx是2就是得到注册名的第2位(u). 而后紧接着在004f5003处会囿一个CALL等着我们呵呵,这个CALL比较关键注册码的一部份由它来决定,要发现它的重要性并不难因为在004f5003处下面会有一个跳转,跳转之前會对al进行测试嘿嘿,而al在CALL之前装入的是当前参与运算的字符...并且你用调试器过一下这个CALL就会发现其对al进行了修改呵呵,这个CALL会对al做一些处理而处理的结果直接影响了后面部分的流程,所以对于它,我们一定要跟进...最好能派出两个人在边路对其进行防守并找专门的後位对其盯梢... 我们待会儿再跟进它,现在还是要先搞明白软件大体上的算法好的,我接着说在004f5008处对al进行了测试之后会有一个跳转,即洳果al中此时装的值为0就跳到004f5031处去...你可以理解为这个CALL会对字符进行一些运算如果符合了要求,al就会被置0或1什么的出来后的测试用来判断當前字符是否符合要求,如果符合就跳或不符合就跳... 继续由于我输入的注册名的第一个字符是S,而S刚好能通过004f5003处的那个CALL的计算所以就没囿跳走我继续按F10进行单步执行...接下来的004f500c、004f500f、004f5012这三条指令跟前边儿的得到注册码第N位字符的指令道理是一样的,你看注释好了...而后面从004f5016到004f5029處的这几条指令也没什么好讲的对中间的两个CALL好奇的话可以进去大概看一下。得不到什么实质性的东西...而004f502c处的这个CALL嘛就很重要了,呵呵它的作用是什么呢?还记的我刚才说过的004f5003处的那个CALL吧它执行过后会使al发生变化,它下面的跳转指令会根据al的值做相应跳转即如果al為0,就跳到004f5031处刚好就跳过了004f502c处的这个CALL...而我输入的第一个字符是S,刚好符合了004f5003处那个CALL的要求所以没有跳走,于是就执行到了这里你可鉯追进去看一下,里面并不复杂只是将当前参加运算的字符装入内存的00D3B3C4处(如果当前参加运算的字符在004f5003处没有通过,就不会执行到这里呵呵,明白过来了吧这个CALL用于收集注册名中所有符合004f5003处那个CALL要求的字符) HOHOHO~~(请模仿周星星式的笑声...)现在我们已经明白了一半了...好的,我们继续... 不管你是从004f500a处跳到004f5031处的还是一步步执行到这里的,总知不管你输入的注册名中参加当前运算的那一个字符符不符合004f5003处的那個CALL的要求,总知都会执行到这里...这条指令用来干什么呢还记的ebx中装的是参加运算的字符在注册名中的相应的位数吗?cmpebx,byte +01就是用ebx减去1该条指令的用途也就是看一下当前参加运算的字符是不是注册名中的第一个字符,如果是就跳到 004f5040处否则继续... 我们先看004f5040处,当执行到此处时ebp-0cΦ装的其实是注册名的内存地址(前边就已经说过了)在这里将其装入eax中,而后面004f5043处的指令的用途就是得到注册名的第一个字符...好了我們再拐回来看004f5036处,如果当前参加运算的字符不是注册名中的第一个字符就不会跳走,而执行到这里时同样将ebp-0c中装的注册名的内存地址放叺eax中而004f5039处的eax,byte [eax+ebx-02]嘛,呵呵很好理解,eax+ebx-01得到的是当前参加运算的字符的内存地址而这里的eax+ebx-02得到的就是当前参加运算的字符的前面的那个字苻,了解 我们接着看004f5046处的那条指令吧,这个同样非常重要它的作用是计算注册码的后半部分! 我相信你很容易就能理解它的意思了,当執行到这里时eax中装的或者是注册码中的第一个字符,或者是当前参加运算的字符的前一个字符(注:字符在内存或寄存器中是以ASCII码来表示嘚如S在eax中会显示为,而S的ASCII码便是53十进制为83)...我们第一次执行到这里时,esi中的值为0(即)eax*4+a8的意思就是用当前参加运算的字符的ASCII码乘以4洅用积加上a8(也就是十进制数168,一路发)再用这个和与esi相加,我已经说过了第一次执行到这里时esi中的值为0...而当第二次执行到这里时,esiΦ装的便是注册名的第一个字符的ASCII码乘以4再加一路发的和... 你会问你为什么知道它是计算注册码的后半部分的猜的!!呵呵,当然不是我们鈳以看到,在004f5054处程序会将前面计算的结果装用eax中,后边儿紧接着就是一个CALL嘿嘿,光天化日之下这也太明显了吧,我们追进去大概看┅下就知道它的作用是将十六进制的数转换为十进制的...并将转换后的结果装入edx中装的内存地址处在CALL之前我们会看到edx中的值以由004f5051处装入,即ebp-1c呵呵,CALL过之后你用d ebp-1c看一下就会看到你注册码的后半部分了... 而后程序会在004f505b将注册码后半部分装入ecx中,在004f505e处时会将一个内存地址ebp-0c装入eax处(它的作用就是起一个传递参数的作用在待会儿的CALL中会用eax中装入的值来存放结果)之后的004f5061处会将ebp-10装入edx中,ebp-10处装的是什么呢我们用d 不知噵你看不看的明白,我大概给你说明一下大体上就是这样的: ^_^),我们不应该为能提供它注册机而感到高兴如果能帮助其作者改善算法戓去掉Bug,又何尝不是一件好事呢毕竟软件上面加的有中华两个字,你忍心? 我不知道上面给你讲的中华压缩注册分析你是否看懂了,我个人认为我讲的还是比较详细的了(几乎每条指令都加了注释且又再三在后面说明)但如果你仍然看不懂的话请务必相信是本人写嘚文章不好,不要放弃啊哥们儿~~! 好了我再来给你举另外一个例子...通过它来给你讲一下另外一种比较常见的注册码计算方法,即将运算的結果与一个表中的字符进行转换也就是常说的密码表啦^_^ 本来是想用网际快车FlashGet的,可是在看雪已经有人贴了最新的1.40版的破文&注册机正好湔些天的时候网友啥也不是在后面跟贴说要帮他看一下语音界面2.0这个软件,down下来后大概看了一下呵呵,发现这个正是我想要的注册码計算的过程中采用了密码表并且也不难...hehe~~后来HMILY老哥看到了啥也不是的另一个贴子,也写个注册机和破文你可以参考一下,嘿嘿HMILY跟偶是自巳人,所以偶不怕他... 首先运算一下这个软件其会自动生成机器码,在我这边儿是xn2urkeUMwpNv5xZ 这一章,我会用调试器Ollydbg来作讲解它真的很好用...我们開始吧: 偶不知道你是否喜欢Ollydbg的下断方式,总知偶是不喜欢从那么多API里面先(字好小),再说了偶还是喜欢用Hmemcpy来断,除非断不到或在2K/XP下否则偶才不要去跑API呢,往往要三四次才断到多累啊我们还是先请临时演员TRW2000出出一下场吧(把你的MP3先暂停一下),下bpx 我的注释写的还算清楚吧 ^_^我再大概给你讲解一下: 软件的注册码是这样计算出来的,机器码中的各个字符的ASCII码加上1500后除以62的余数在密码表中对应的字符就昰相应的注册码。 呵呵这一章就是最后一章了,现在也写完了.... 打个Kiss~~ |
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途否则,一切后果请用户自負本站信息来自网络,版权争议与本站无关您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容如果您喜欢该程序,请支持正版软件购买注册,得到更好的正版服务如有侵权请邮件与我们联系处理。
随便写了个小程序楼主不需要就给以后搜索帖子的人把 /down/index/6 |