用delphiforphp来编写注册机

这是我发在看雪论坛上的一个delphiforphp的应用,与其说是delphiforphp到不如说是用php写的。呵呵。放在这里就当是做个备份吧。

【文章标题】: 用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:41:13

原文地址:https://www.cnblogs.com/dahaij/p/1409846.html