一直就想用php来写一个算法注册机,因为php语言是很强大的。这段时间经常查找众多资料,终于写出了我第一个php的算法注册机, 同时也了解一些关于php对字符串,对位的操作函数。不敢独享,特写出来给大家一起分享。内容比较基础,主要用于对入门者的引见,请高手及时路过。
       话入正题,我个人觉得用php写注册机有二个好处。

       第一,发布和使用方便,只要有一个免费的发布空间就行,而需要的也不用下载。

       第二,对算法的保密,别人没有办法通过分析注册机来了解你破解的方法。同时如果原软件公司提出意见,只要关了网页就行,不象软件注册机那样无法控制。当然,这种想法是多余的。不过我在搞不定一个软件的时候,总是拿别人注册机来分析。哈哈。请高手见谅。水平有限。

       先认大家看一张效果图片。

 



这里实现了一个crackme的注册码生成。

        下面我先说说大家在开发php注册机的时候要准备的工具。

一、建议大家用delphiforphp。网上有下。工具的安装和设置我后面会讲。

二、php中文手册。要把算法写出来。不知道语法和函数是不行的。所以大家得准备一个手册在手上备用。当然我会帮助大家把常用的代码准备在一起的。

我去为大家准备一下这两个工具。为不引起不必要的麻烦,大家要的话请发短信息给我。最好大家自己去网上找。

找到了吗???

下面要开讲了。大家先安装delphiforphp,然后打开选项把界面语言设置成简体中文(有人喜欢用英文的我没有意见)然后再把php选项的默认字符集选择“ utf-8”,再把“设置php.ini中的值”前面的框里打上钩。这样delphiforphp的设置就搞定了。然后要提醒大家的是大家在调试的时候,要把工程保存在非中文的目录中。否则会出现调试不了的现象。

好了,今天就讲到这里,请大家回去准备工具吧。明天讲具体实现!!有兴趣的请大家关注我的贴。

  • 标 题: 用php来编写注册机第二节
  • 作 者:dahaij
  • 时 间:2009-01-07 13:46

【文章标题】: 用php来编写注册机第二节
【文章作者】: dahaij
【作者主页】: http://dahaij.spaces.live.com/
【作者QQ号】: 暂时不想说
【软件名称】: 加密与破解2光盘习题
【使用工具】: OD
【软件介绍】: 一个作业,大家一起分析。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教! 更希望有共同兴趣者一起来讨论讨论。
--------------------------------------------------------------------------------
【详细过程】
  昨天发的一贴,只是一个引子,今天我们要开始来实现我们第一个php语言注册机了,其实很多方法可以用在其它语言。
  希望大家一通百通。
  
  今天我拿出来的是加密与破解2光盘的第二题,书上是给出的爆破的办法,由于在调式的时候会生成完整的注册码,所以它也可以写出内存注册机。
  这里我就不讲内存注册机了,因为大家都会。用keymake写算法注册机,我不会,请高人路过时能指点点我。
  下面是我的分析过程。
  具体调试过程,我用视频教程给出,这里我只谈关健的算法分析部分。
  调试时我输入的是我的用户名
  
  进入关键函数后,我们将看到。
  
  004416F8    53              push ebx
  004416F9    56              push esi
  004416FA    57              push edi
  004416FB    83C4 DC         add esp,-24
  004416FE    891424          mov dword ptr ss:[esp],edx             将前面取得用户名数输入堆,这里是6
  00441701    8BF8            mov edi,eax                            将dahaij输入给edi
  00441703    BB 05033949     mov ebx,49390305                       将常数49390305输入给ebx
  00441708    BE 20126348     mov esi,48631220                       将常数48631220输入给esi
  0044170D    8BC7            mov eax,edi                    
  0044170F    E8 2023FCFF     call echap303.00403A34                 判断是否输入了用户名   
  00441714    85C0            test eax,eax
  00441716    7E 2E           jle short echap303.00441746
  00441718    BA 01000000     mov edx,1                              给edx 为1 ------------------------------------------------(1)
  0044171D    33C9            xor ecx,ecx
  0044171F    8A4C17 FF       mov cl,byte ptr ds:[edi+edx-1]         取出d给cl                                                                                                 
  00441723    33D9            xor ebx,ecx                            d xor 49390305=49390361
  00441725    33F3            xor esi,ebx                            49390361 xor 48631220=015A1141                             
  00441727    F6C3 01         test bl,1                              判断最后一个位是否为1
  0044172A    74 0F           je short echap303.0044173B             是则跳,不是就继续
  0044172C    D1FB            sar ebx,1                              49390361算术右移为249C81B0
  0044172E    79 03           jns short echap303.00441733            判断符号位是否为0
  00441730    83D3 00         adc ebx,0                              不为0就清0         (php中这项如何搞定,我不知道,请高人指点,我没有写段,不过不影响,因为产生这个的字付太少了。我只发出了一个“|”这个,我想用不上。
  00441733    81F3 11032001   xor ebx,1200311                         249C81B0 xor 1200311=25BC82A1
  00441739    EB 07           jmp short echap303.00441742
  0044173B    D1FB            sar ebx,1
  0044173D    79 03           jns short echap303.00441742
  0044173F    83D3 00         adc ebx,0
  00441742    42              inc edx                                 给edx加1 目的是取一下字母                                 (2)  
  00441743    48              dec eax                                 给eax减1 实现                                             (3)
  00441744  ^ 75 D7           jnz short echap303.0044171D
  00441746    8B0424          mov eax,dword ptr ss:[esp]
  00441749    50              push eax
  0044174A    8BC3            mov eax,ebx
  0044174C    25 FFFF0000     and eax,0FFFF
  00441751    894424 08       mov dword ptr ss:[esp+8],eax
  00441755    C64424 0C 00    mov byte ptr ss:[esp+C],0
  0044175A    C1EB 10         shr ebx,10
  0044175D    895C24 10       mov dword ptr ss:[esp+10],ebx
  00441761    C64424 14 00    mov byte ptr ss:[esp+14],0
  00441766    8BC6            mov eax,esi
  00441768    25 FFFF0000     and eax,0FFFF
  0044176D    894424 18       mov dword ptr ss:[esp+18],eax
  00441771    C64424 1C 00    mov byte ptr ss:[esp+1C],0
  00441776    C1EE 10         shr esi,10
  00441779    897424 20       mov dword ptr ss:[esp+20],esi
  0044177D    C64424 24 00    mov byte ptr ss:[esp+24],0
  00441782    8D5424 08       lea edx,dword ptr ss:[esp+8]
  00441786    B9 03000000     mov ecx,3
  0044178B    B8 A4174400     mov eax,echap303.004417A4                ; %.4x-%.4x-%.4x-%.4x
  00441790    E8 6F68FCFF     call echap303.00408004
  00441795    83C4 24         add esp,24
  00441798    5F              pop edi
  00441799    5E              pop esi
  0044179A    5B              pop ebx
  0044179B    C3              retn
  
  
  (1)(2)(3)共同构成一个循环结构。
  
  根据上面的分析,我就可以分析出如下算法。
  $x是输入的字符串
  
          for ($i = 0; $i <strlen($x); $i++) {
         取出的字符与ebx中49390305异或,生成的数存在ebx中
         将生成的数与esi中48631220异或,生成的数存在esi中  
         判断ebx中数最后一位是否为0,为0则右移一位,并将生成的数与1200311异或,否则只右移一位。
        
           }
  
  下面我们来写php的代码。
  
  
  function Button1Click($sender, $params)-------------------------------按钮事件
         {
          $ebx=hexdec(49390305);                                        php中的运算都是在10进制下进行的。所以先来个转换。变量$ebx这样写是为了方便在分析算法的同时写出代码
          $esi=hexdec(48631220);                                        转换esi中的值
          $a=hexdec(1200311);                                           转换常数1200311
          $x=$this->Edit1->Text;                                        取字符串
       
          for ($i = 0; $i <strlen($x); $i++) {                          写出循环
          $ebx= ord(substr($x,$i,1)) ^ $ebx ;                           将字符转成10进制后进行运算
      //    echo dechex($ebx).",";                                      此步是我为了测试生成的数与我调试过程的生成数是否一样。所以被注释了。
          $esi=$esi^$ebx;
       //   echo dechex($esi).",";
          if($ebx & 1)                                                  判断最后一位是否为0就是让它与1并就行了。
            {$ebx=$ebx >> 1;                                            移位 
          $ebx=$ebx^$a;                                                 异或 
    //        echo dechex($ebx).",";
             }
             else{
                 $ebx=$ebx >> 1;
      //    echo dechex($ebx).",";
           }
  
             }
      
        $key =substr(dechex($ebx),-4)."-".str_pad(substr(dechex($ebx),0,strlen(dechex($ebx))-4), 4, "0", STR_PAD_LEFT)."-".substr(dechex($esi),-4)."-".str_pad(substr(dechex($esi),0,strlen(dechex($esi))-4), 4, "0", STR_PAD_LEFT) ;
         
           $this->Edit2->Text=strtoupper ($key) ;                      输出
  
  
  
         }
  
  大家看算法不复杂,下面把几个函数提出来讲一下。
  php的位运算
  $a & $b And(按位与) 将把 $a 和 $b 中都为 1 的位设为 1。 
  $a | $b Or(按位或) 将把 $a 或者 $b 中为 1 的位设为 1。 
  $a ^ $b Xor(按位异或) 将把 $a 和 $b 中不同的位设为 1。 
  ~ $a Not(按位非) 将 $a 中为 0 的位设为 1,反之亦然。 
  $a << $b Shift left(左移) 将 $a 中的位向左移动 $b 次(每一次移动都表示“乘以 2”)。 
  $a >> $b Shift right(右移) 将 $a 中的位向右移动 $b 次(每一次移动都表示“除以 2”)。 
  警告 
  在 32 位系统上不要右移超过 32 位。不要在结果可能超过 32 位的情况下左移。 很庆幸我这里没有超过这个数,所以php的大数操作是个学问,我是新手,请高人指点。
  
  与字符有关的函数
  
  hexdec ()     将16进制数转换成10进制数
  dechex  ()    将10进制数转换成16进制数
  
  strlen()      取字符串长度
  substr(字符,a,b)  取字符串中从a位开始的b个数,如果a为负数则表示从后向前数第a个,b也一样。
  ord()         返回字符串的ascii码(10进制)
  str_pad()    str_pad 函数用于进行字符串的填补,第一个参数是处理的字符串对象,第二参数是总长度,第三个参数是指长度不够总长以什么符号来填补,第四个参数为填补左边还是右边(默认不写为填补右边)。 
  
  
  算法不复杂,写出来也不复杂。希望对大家有用。如果大家对有些php的处理不太明白,可以去翻php手册。
  
  今天就讲到这里,希望对大家有用。下面我原代码,crackme,实现视频都上传给大家,。
  
  
  
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于dahaij, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年01月07日 13:43:56

上传的附件 echap303.rar
test.rar