首页
社区
课程
招聘
[原创]动态生成代码CrackMe(De-KryptZo2)算法分析+批量注册码生成
2007-4-13 21:35 9268

[原创]动态生成代码CrackMe(De-KryptZo2)算法分析+批量注册码生成

2007-4-13 21:35
9268
【文章标题】: 动态生成代码CrackMe(De-KryptZo2)算法分析+批量注册码生成
【文章作者】: 壹只老虎
【作者邮箱】: tiger..tiger@163.com
【软件名称】: De-KryptZo2
【软件大小】: 6.00
【下载地址】: 自己搜索下载
【加壳方式】: 无
【保护方式】: 注册名+序列号+动态代码生成+程序崩溃
【编写语言】: 不知道
【使用工具】: od+peid
【操作平台】: windowsxp  sp2
【软件介绍】: http://www.crackmes.de/下载的一个crackme
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  昨天刚分析了  De-KryptZo1 感觉比较有意思,今天找到了第二版来分析看看。
  第2版当然比第一版有所加强了哦。不会那么简单了。
  
  老规矩。
  先贴一下作者关于本crackme的说明,对分析有些帮助。
  ===============================================================================
  DeKryptZo - 2
  
  Greetz PPL ...
  
  Yea ... finally a part 2 ...
  part was easy defeated with luck ...
  but here i have decided to screw up ur luck .. he he he
  
  Rules!
  no patching ... unless ur totally clueless !
  no bruteforcing
  find valid serial
  and tut plz . . .
  
  Unless you Enter a Valid Serial ... the Decryption will be wrong and the
  app will crash !
  On entering a Correct Serial ... you will get a goodboy message !
  
  Mail tut to me ...
  
  starzboy / iCU
  starzboy@gmail.com
  ===============================================================================
    作者的意思好像是说:不要补丁,不要爆破。
    当输入正确注册码时,你将得到一个"goodboy"消息框,
    当输入错误时,本程序会错误,并且崩溃。
  
    作者还说和运气有关系,看了我昨天写的De-KryptZo1文章之后,
    很明显,运气的命中概率为1/128。应该是相当低了。嘿嘿。
    作者还是,第一个太简单了。昨天搞得我还有点郁闷的。哎!
  
    我们今天的目标当然不至于像昨天一样简单,
    今天我们不但要找到注册码,还要写出注册机,呵呵,
    我保证。
  ===============================================================================
    运行一下,发现和昨天唯一不同的是多了一个key验证。估计要复杂些了。
    随便输入了一个name和key,获取hash值,这里会发现,是一个8位的hash值。
    哎!麻烦了,如果用昨天的方法,不死人才怪。有点心理恐惧了。看来的另外想办法。
    解密,ok,很好,程序崩溃了。是作者故意这么写的。
   
    peid和fi查都没有提示,不确定是否有壳。
    od载入,没有加密提示,应该没有壳。
   
    字符串参考,看一下,发现正确提示“Decryption Successfull ... Good Work !”,
    一切都很顺利,双击过去,来到这里。
  ===============================================================================
  00401396        /EB 14             jmp short De-Krypt.004013AC
  00401398        |6A 00             push 0
  0040139A        |68 81304000       push De-Krypt.00403081    ; ASCII "[iCU]"
  0040139F        |68 5A304000       push De-Krypt.0040305A    ; ASCII "Decryption Successfull ... Good Work !"
  004013A4        |FF75 08           push dword ptr ss:[ebp+8]
  004013A7        |E8 68000000       call <jmp.&user32.MessageBoxA>
  004013AC        \8D23              lea esp,dword ptr ds:[ebx]
  004013AE         8BA453 63238B7D   mov esp,dword ptr ds:[ebx+edx*2+7D8B2363>
  004013B5         53                push ebx
  004013B6         6323              arpl word ptr ds:[ebx],sp
  004013B8         2298 2B0B8B23     and bl,byte ptr ds:[eax+238B0B2B]
  004013BE         2323              and esp,dword ptr ds:[ebx]
  
  
  ===============================================================================
    根据昨天的经验,发现下面这段代码是不可能执行到的。他的目的就是提示正确的代码
    是怎么个样子的。我第一次也不知道的,昨天分析完了才明白的。如果有兴趣,可以看
    一下我昨天的那篇文章。
  ===============================================================================
  00401398        |6A 00             push 0
  0040139A        |68 81304000       push De-Krypt.00403081    ; ASCII "[iCU]"
  0040139F        |68 5A304000       push De-Krypt.0040305A    ; ASCII "Decryption Successfull ... Good Work !"
  004013A4        |FF75 08           push dword ptr ss:[ebp+8]
  004013A7        |E8 68000000       call <jmp.&user32.MessageBoxA>
  ===============================================================================
    和昨天不一样的是:
  ===============================================================================
  004013AC        \8D23              lea esp,dword ptr ds:[ebx]
  004013AE         8BA453 63238B7D   mov esp,dword ptr ds:[ebx+edx*2+7D8B2363>
  004013B5         53                push ebx
  004013B6         6323              arpl word ptr ds:[ebx],sp
  004013B8         2298 2B0B8B23     and bl,byte ptr ds:[eax+238B0B2B]
  004013BE         2323              and esp,dword ptr ds:[ebx]
  ===============================================================================
    昨天的这段代码开始的时候全部是nop.这段代码开始的时候已经有数据了,估计后面会用到。
    废话不说,按照昨天的思路,先把生成算法分析出来。如下,一共4段,一段是注册名计算。
    一段是注册码计算,一段是注册码和注册名计算结果综合计算得到hash值,最后一段是生成
    代码的算法。
  ===============================================================================
    第一段:注册名计算算法。
  ===============================================================================
  004010C6         E8 43030000       call <jmp.&user32.GetDlgItemTextA>   ; 取注册名
  004010CB         C745 FC 00000000  mov dword ptr ss:[ebp-4],0
  004010D2         8945 FC           mov dword ptr ss:[ebp-4],eax
  004010D5         83F8 03           cmp eax,3                            ; 注册名长度是否>3
  004010D8         77 17             ja short De-Krypt.004010F1           ; 必须大于3
  004010DA         68 0D304000       push De-Krypt.0040300D               ; ASCII "wtf . . .more than 4 chars plz . . ."
  004010DF         68 ED030000       push 3ED
  004010E4         FF75 08           push dword ptr ss:[ebp+8]
  004010E7         E8 34030000       call <jmp.&user32.SetDlgItemTextA>
  004010EC         E9 CF020000       jmp De-Krypt.004013C0
  004010F1         8D3D 8C304000     lea edi,dword ptr ds:[40308C]        ; edi=注册名地址
  004010F7         57                push edi                             ; 压栈
  004010F8         E8 41030000       call <jmp.&kernel32.lstrlenA>
  004010FD         33F6              xor esi,esi                          ; esi=0
  004010FF         33DB              xor ebx,ebx                          ; ebx=0
  00401101         8BF0              mov esi,eax                          ; esi=注册名长度
  00401103         33C9              xor ecx,ecx                          ; ecx=0
  00401105         33C0              xor eax,eax                          ; eax=0
  00401107         8BD7              mov edx,edi                          ; edx=注册名
  00401109         81C1 65320000     add ecx,3265                         ; ecx=3265H
  0040110F         41                inc ecx                              ; ecx=3266H
  00401110         43                inc ebx                              ; ebx=1
  00401111         03D1              add edx,ecx                          ; edx=注册名地址+3266H
  00401113         8D0C0A            lea ecx,dword ptr ds:[edx+ecx]       ; ecx=edx+3266H
  00401116         0FBE5C07 01       movsx ebx,byte ptr ds:[edi+eax+1]    ; ebx=从第2位开始取注册名
  0040111B         03DA              add ebx,edx                          ; ebx=ebx+edx
  0040111D         03CB              add ecx,ebx                          ; ecx=ecx+ebx
  0040111F         03CB              add ecx,ebx                          ; ecx=ecx+ebx
  00401121         0FAFCB            imul ecx,ebx                         ; ecx=ecx*ebx
  00401124         03C8              add ecx,eax                          ; ecx= ecx+eax
  00401126         0FAFC8            imul ecx,eax                         ; ecx=ecx*eax
  00401129         43                inc ebx                              ; ebx=ebx+1
  0040112A         81F3 56120400     xor ebx,41256                        ; ebx=ebx xor 41256H
  00401130         D1E1              shl ecx,1                            ; ecx=ecx shl 1
  00401132         81F1 6C050000     xor ecx,56C                          ; ecx=ecx xor 56CH
  00401138         81E3 0F000008     and ebx,800000F                      ; ebx=ebx and 800000F
  0040113E         03CB              add ecx,ebx                          ; ecx=ecx+ebx
  00401140         40                inc eax                              ; eax=eax+1
  00401141         3BC6              cmp eax,esi
  00401143       ^ 72 D1             jb short De-Krypt.00401116           ; eax小于注册名长度就返回
  00401145         894D F0           mov dword ptr ss:[ebp-10],ecx
  ===============================================================================
    上面这段代码把注册名计算的结果保存到[ebp-10],我们设为A.
    对应的delphi代码为:
  ===============================================================================
  /*****************************************************************************/
  function funHashName(name:string):integer;
  var
     ecx,ebx,edx,eax:integer;
     i:integer;
  begin
       eax:=0;
       edx:=$40308C+$3266;            
       ecx:=edx+$3266;                  
       for i:=2 to length(name)+1 do
        begin
           ebx:=ord(name[i])+edx;
           ecx:=ecx+ebx+ebx;
           ecx:=ecx*ebx+eax;
           ecx:=ecx*eax;
           ebx:=ebx+1;
           ebx:=ebx xor $41256;
           ecx:=ecx*2;
           ecx:=ecx xor $56C;
           ebx:=ebx and $800000F;
           ecx:=ecx+ebx;
           eax:=eax+1;
       end;
       result:=ecx;
  end;
  /*****************************************************************************/
  ===============================================================================
    第二段:注册码生成算法。
  ===============================================================================
  004011C4         33F6              xor esi,esi                              ; esi=0
  004011C6         33DB              xor ebx,ebx                              ; ebx=0
  004011C8         8BF0              mov esi,eax                              ; esi=试验码长度
  004011CA         33C9              xor ecx,ecx                              ; ecx=0
  004011CC         33C0              xor eax,eax                              ; eax=0
  004011CE         8BD7              mov edx,edi                              ; edx=[0040308C]试验码地址
  004011D0         81C1 85FF0000     add ecx,0FF85                            ; ecx=0FF85H
  004011D6         41                inc ecx                                  ; ecx=FF86H
  004011D7         43                inc ebx                                  ; ebx=1
  004011D8         03D1              add edx,ecx                              ; edx=edx+FF86H
  004011DA         8D0C0A            lea ecx,dword ptr ds:[edx+ecx]           ; ecx=edx+FF86H
  004011DD         0FBE5C07 05       movsx ebx,byte ptr ds:[edi+eax+5]        ; ebx=从第6位开始取key(多取一个结束符号)
  004011E2         03DA              add ebx,edx                              ; ebx=ebx+edx
  004011E4         03CB              add ecx,ebx                              ; 下面不写了,没意思.大家都懂
  004011E6         03CB              add ecx,ebx
  004011E8         0FAFCB            imul ecx,ebx
  004011EB         2BC8              sub ecx,eax
  004011ED         0FAFC8            imul ecx,eax
  004011F0         43                inc ebx
  004011F1         43                inc ebx
  004011F2         81F3 56120400     xor ebx,41256
  004011F8         D1E1              shl ecx,1
  004011FA         81C9 6C050000     or ecx,56C
  00401200         81E3 0F000008     and ebx,800000F
  00401206         03CB              add ecx,ebx
  00401208         40                inc eax
  00401209         3BC6              cmp eax,esi
  0040120B       ^ 72 D0             jb short De-Krypt.004011DD
  0040120D         894D EC           mov dword ptr ss:[ebp-14],ecx            ; key运算结果保存在[ebp-14H]
  ===============================================================================
    上面这段代码把注册名计算的结果保存到[ebp-14],我们设为B.
    对应的delphi代码为:
  ===============================================================================
  /*****************************************************************************/
  function funHashKey(key:string):integer;
  var
     i,eax,edx,ebx,ecx:integer;
     str:string;
  begin
     eax:=0;
     edx:=$40308C+$FF86;
     ecx:=$40308C+$FF86*2;
  
     str:=key+'xxxxxxxx';
     for i:=length(key)+1 to length(key)+5 do
         str[i]:=#0;
     for i:=6 to length(key)+5 do
         begin
            ebx:=ord(str[i])+edx;
            ecx:=ecx+ebx+ebx;
            ecx:=ecx*ebx;
            ecx:=ecx-eax;
            ecx:=ecx*eax;
            ebx:=ebx+2;
            ebx:=ebx xor $41256;
            ecx:=ecx *2;
            ecx:=ecx or $56C;
            ebx:=ebx and $800000F;
            ecx:=ecx+ebx;
            inc(eax);
         end;
     result:=ecx ;
  end;
  /*****************************************************************************/
  ===============================================================================
    第3段:注册码和注册名计算结果综合计算得到hash值
  ===============================================================================
  0040120D         894D EC           mov dword ptr ss:[ebp-14],ecx        ; key运算结果保存在[ebp-14H]
  00401210         8B55 F0           mov edx,dword ptr ss:[ebp-10]        ; edx=注册名的运算结果
  00401213         8B4D EC           mov ecx,dword ptr ss:[ebp-14]        ; ecx=key的运算结果
  00401216         8955 E8           mov dword ptr ss:[ebp-18],edx
  00401219         014D E8           add dword ptr ss:[ebp-18],ecx        ; [ebp-18]=注册名和key运算结果相加
  0040121C         0FAFCA            imul ecx,edx                         ; ecx=注册名和key运算结果相乘
  0040121F         81F2 655F0200     xor edx,25F65                        ; edx=注册名运算结果 xor 25F65H
  00401225         0155 E8           add dword ptr ss:[ebp-18],edx        ; [ebp-18]=[ebp-18]+edx
  00401228         014D E8           add dword ptr ss:[ebp-18],ecx        ; [ebp-18]=[ebp-18]+ecx
  0040122B         FF75 E8           push dword ptr ss:[ebp-18]           ; 结果压栈
  0040122E         68 57304000       push De-Krypt.00403057               ; ASCII "%x"
  00401233         68 8C344000       push De-Krypt.0040348C               ; ASCII "7d119559"
  00401238         E8 B3010000       call <jmp.&user32.wsprintfA>         ; 格式化结果为16进制的字符串
  0040123D         83C4 0C           add esp,0C                           ; 保存在0040348C(结果就是HASH值)
  00401240         68 8C344000       push De-Krypt.0040348C               ; ASCII "7d119559"
  00401245         68 ED030000       push 3ED
  0040124A         FF75 08           push dword ptr ss:[ebp+8]
  0040124D         E8 CE010000       call <jmp.&user32.SetDlgItemTextA>   ; 设置第3个文本框数据为HASH值
  ===============================================================================
    这一段代码就是HASH值得生成代码了,hash值生成后放在第3个文本框里面,
    后面再从这个文本框里面取数据。
    对应的delphi代码如下:
  ===============================================================================
  /*****************************************************************************/
  function funHash(hashname,hashkey:integer):string;
  var
     ecx,edx,temp,i:integer;
     str:string;
     p:Pchar;
  begin
       temp:=hashname+hashkey;
       ecx:=hashname*hashkey;
       edx:=hashname xor $25F65;
       temp:=temp+ecx+edx;
       str:=inttohex(temp,8);
  
       p:=@str[1];
       while p^='0'do
            inc(p);
       str:=string(p);
       for i:=1 to length(str) do
          if (ord(str[i])>64)and (ord(str[i])<91) then
            str[i]:=chr(ord(str[i])+32);
       result:=str;
  end;
  /*****************************************************************************/
  ===============================================================================
    第4段分为两个部分,我们称之为A部分和B部分。
  ===============================================================================
    A部分
  ===============================================================================
  00401319         E8 F0000000       call <jmp.&user32.GetDlgItemTextA>       ; 取得hash值
  0040131E         8945 E4           mov dword ptr ss:[ebp-1C],eax            ; 计数器=hash码长度
  00401321         BE 8C324000       mov esi,De-Krypt.0040328C                ; esi=[0040328C]=hash值地址
  00401326         33DB              xor ebx,ebx                              ; ebx=0
  00401328         8BD8              mov ebx,eax                              ; ebx=eax=hash值长度
  0040132A         8A06              mov al,byte ptr ds:[esi]                 ; al=按位取hash码
  0040132C         04 32             add al,32                                ; 下面不写了,很明白
  0040132E         FEC0              inc al
  00401330         34 56             xor al,56
  00401332         04 71             add al,71
  00401334         2C 65             sub al,65
  00401336         04 95             add al,95
  00401338         04 9C             add al,9C
  0040133A         C0E3 05           shl bl,5
  0040133D         02C3              add al,bl
  0040133F         0045 F7           add byte ptr ss:[ebp-9],al               ; [ebp-9]=[ebp-9]+al([ebp-9]初始值为0)
  00401342         8045 F7 91        add byte ptr ss:[ebp-9],91
  00401346         46                inc esi
  00401347         FF4D E4           dec dword ptr ss:[ebp-1C]
  0040134A         837D E4 00        cmp dword ptr ss:[ebp-1C],0
  0040134E       ^ 77 DA             ja short De-Krypt.0040132A               ; 计数器>0就继续循环
  ===============================================================================
    设[ebp-9]为X,A部分的作用就是根据hash码,生成一个byte类型的X,呵呵,是不是和第一个
    差不多了,第一个的hash值就是一个byte大小的.从这点上看,的确是差不多了.
  ===============================================================================
    B部分
  ===============================================================================
  00401350         33F6              xor esi,esi                              ; 设上面这个循环后[ebp-9]=A
  00401352         33FF              xor edi,edi
  00401354         BE AC134000       mov esi,De-Krypt.004013AC                ; esi=004013AC
  00401359         BF AC134000       mov edi,De-Krypt.004013AC                ; edi=004013AC
  0040135E         33C9              xor ecx,ecx                              ; ecx=0
  00401360         33C0              xor eax,eax                              ; eax=0
  00401362         8A06              mov al,byte ptr ds:[esi]                 ; al=按位取esi,esi是一个固定的表
                                                                              ;(也就是写入代码的那一段的初始数据)
  00401364         8A4D F7           mov cl,byte ptr ss:[ebp-9]               ; cl=A
  00401367         2C 71             sub al,71
  00401369         FEC0              inc al
  0040136B         04 51             add al,51
  0040136D         04 34             add al,34
  0040136F         04 46             add al,46
  00401371         02C1              add al,cl
  00401373         0245 F7           add al,byte ptr ss:[ebp-9]               ; al=al+A
  00401376         04 09             add al,9
  00401378         04 53             add al,53
  0040137A         04 54             add al,54
  0040137C         04 20             add al,20
  0040137E         2C 97             sub al,97
  00401380         2C 71             sub al,71
  00401382         8807              mov byte ptr ds:[edi],al                 ; 关键(生成代码)
  00401384         46                inc esi                                  ; esi表偏移+1
  00401385         47                inc edi                                  ; 代码写入地址+1
  00401386         FF4D FC           dec dword ptr ss:[ebp-4]
  00401389         837D FC 00        cmp dword ptr ss:[ebp-4],0
  0040138D       ^ 77 CF             ja short De-Krypt.0040135E               ; 循环20次
  0040138F         C605 BC134000 54  mov byte ptr ds:[4013BC],54
  00401396         EB 14             jmp short De-Krypt.004013AC
  ===============================================================================
    B部分的功能是根据A部分得到的X,来动态生成正确提示的代码.
    这里我不得不讲一个小插曲.我开始的时候是用PYG-OD调试的,
    后来到达这一句的时候发生了奇迹:
                                   00401362         8A06              mov al,byte ptr ds:[esi]
    什么奇迹呢, 过 00401362 之前,byte ptr ds:[esi]的数据为8D,
    过 00401362 之后,al数据为CC,把我吓了一跳,郁闷了一段时间,
    后来 在abest 兄弟的帮助下,我知道为什么了,原来是PYG-OD的BUG,
    我马上换了OllyIce来调试,没有问题.就继续我们的分析.
  
    第4部分对应的delphi代码如下:
  ===============================================================================
  /*****************************************************************************/
  function funCreateCode(hash:string):string;
  const
       table:array[1..20]of byte =($8D, $23, $8B, $A4, $53,
                                   $63, $23, $8B, $7D, $53,
                                   $63, $23, $22, $98, $2B,
                                   $0B, $8B, $23, $23, $23);
       {这段代码就被写入地址处的初始数据}
  var
     bkey,al,bl:byte;
     i:integer;
     str:string;
  begin
     bkey:=0;
     bl:=length(hash);
     for i:=1 to length(hash) do
        begin
           al:=ord(hash[i]);
           al:=al+$33;
           al:=al xor $56;
           al:=al+$71-$65+$95+$9c;
           bl:=bl*32;
           al:=al+bl;
           bkey:=bkey+al+$91;
        end;
  
  
     str:='xxxxxxxxxxxxxxxxxxxx';
     for  i:=1 to 20 do
        begin
           al:=table[i]-$70+$51+$34+$46+bkey+bkey+$9+$53+$54+$20-$97-$71;
           str[i]:=chr(al);
        end;
     str[17]:=chr($54);
     result:=str;
  end;
  /*****************************************************************************/
  ===============================================================================
    上面分析完了,现在来总结一下.
    1:从总体上看,关键决定生成代码的是根据hash生成的那个byte类型的数据,这里有256种可能,
    2:根据昨天的crackme的经验,我们知道,我们需要生成的代码为,
  ===============================================================================
    004013AC   > \6A 00         push    0
    004013AE   .  68 81304000   push    00403081                         ;  ASCII "[iCU]"
    004013B3   ?  68 5A304000   push    0040305A                         ;  ASCII "Decryption Successfull ... Good Work !"
    004013B8   .  FF75 08       push    dword ptr [ebp+8]
    004013BB   ?  E8 54000000   call    <jmp.&user32.MessageBoxA>
  ===============================================================================
    3:由于利用注册名和注册码生成hash值,在根据hash值生成成功提示代码的过程类似于
      有损压缩,是不可逆的.所以,我们这里只能采用一种办法来进行破解,那就是"暴力破解",
      注意,这里的"暴力破解"不是说修改代码,而是用程序来实现枚举.
    4:分析讨论一下,我们的"暴力破解"程序的效率怎么样,很好推理,由于成功提示代码的关键在于
      哪一个byte类型的数据,只有256中可能,也就是说,碰撞率是相当高的,所以我们的暴力破解程序
      的效率应该会很高的,如果说可能性为1000000000种,那么还是不要考虑暴力破解为妙,
      那真的是很需要运气的了.
    5:既然程序的暴力破解可行,那么我们就来设计一下这个程序吧,首先,为了方便,我们将
      name和key都设置为整型,这样方便计算.是用双循环实现,每次name和key加1,用其计算
      hash值,然后生成代码保存,我们把正确的代码与之比较,匹配的话,就保存这对数据.
    下面是我在delphi7.0下设计的代码,写的很乱,见笑乐,速度还是很不错的,一会儿就几千个了,
    毕竟碰撞率太高了.呵呵.
  ===============================================================================
  /*****************************************************************************/
  procedure TForm1.Button1Click(Sender: TObject);
  const
    bRealCode:array[1..20] of byte =($6A, $00, $68, $81, $30,
                                     $40, $00, $68, $5A, $30,
                                     $40, $00, $FF, $75, $08,
                                     $E8, $68, $00, $00, $00);
  var
     code,hash,sRealCode:string;
     i,j,hashkey,hashname,startname,endname,startkey,endkey,count,numkey:integer;
     res:tstringlist;
  begin
        sRealCode:='xxxxxxx';
        for i:=1 to 7 do
           sRealCode[i]:=chr(bRealCode[i]);
  
        label10.Caption:='已经找到了 0 组密码';
        try
           startname:=strtoint(edit5.Text);
           endname:=strtoint(edit6.Text);
           startkey:=strtoint(edit7.Text);
           endkey:=strtoint(edit8.Text);
           numkey:=strtoint(edit9.Text);
        except
          Application.MessageBox('非法输入','错误',MB_ICONINFORMATION+MB_OK);
          exit;
        end;
  
        if (startname<1000)or (endname<1000)or  (startkey<1000)or (endkey<1000) then
          begin
              Application.MessageBox('起始和结束值至少4位','错误',MB_ICONINFORMATION+MB_OK);
              exit;
          end;
  
        if (endname-startname>1000000) or (endkey-startkey>1000000) then
          begin
              Application.MessageBox('这么多,你想累死我啊!','错误',MB_ICONINFORMATION+MB_OK);
              exit;
          end;
  
        if (endname<=startname) or (endkey<=startkey) then
          begin
              Application.MessageBox('结束值必须大于开始值','错误',MB_ICONINFORMATION+MB_OK);
              exit;
          end;
  
        if (numkey<1)then
          begin
              Application.MessageBox('你至少得找出一个密码吧','提示',MB_ICONINFORMATION+MB_OK);
              exit;
          end;
  
        if (numkey>100000)then
          begin
              Application.MessageBox('密码太多太多了吧!','提示',MB_ICONINFORMATION+MB_OK);
              exit;
          end;
        edit5.Enabled:=false;
        edit6.Enabled:=false;
        edit7.Enabled:=false;
        edit8.Enabled:=false;
        edit9.Enabled:=false;
  
        res:=tstringlist.Create;
        res.Add('Name             Key');
        count:=0;
        i:=startname;
        proexit:=0;
        while i<=endname do
          begin
             j:=startkey;
             while j<=endkey do
               begin
                     hashname:=funHashName(inttostr(i));
                     hashkey:=funHashKey(inttostr(j));
                     hash:=funHash(hashname,hashkey);
                     code:=funCreateCode(hash);
                     if pos(sRealCode,code)<>0 then
                        begin
                           inc(count);
                           res.Add(inttostr(i)+'             '+inttostr(j));
                           label10.Caption:='已经找到了 '+inttostr(count)+' 组密码';
                           application.ProcessMessages;
                           if proexit=1 then
                             begin
                               Application.MessageBox('是你叫我不干了的哈!','提示',MB_ICONINFORMATION+MB_OK);
                               proexit:=0;
                               edit5.Enabled:=true;
                               edit6.Enabled:=true;
                               edit7.Enabled:=true;
                               edit8.Enabled:=true;
                               edit9.Enabled:=true;
                               res.SaveToFile('破解结果.txt');
                               Application.MessageBox('结果已经保存到  破解结果.txt 中!','提示',MB_ICONINFORMATION+MB_OK);
                               exit;
                             end;
                           if count>=numkey then
                             begin
                               Application.MessageBox(pchar('完成了,找到 '+inttostr(count)+' 组密码'),'提示',MB_ICONINFORMATION+MB_OK);
                               edit5.Enabled:=true;
                               edit6.Enabled:=true;
                               edit7.Enabled:=true;
                               edit8.Enabled:=true;
                               edit9.Enabled:=true;
                               res.SaveToFile('破解结果.txt');
                               Application.MessageBox('结果已经保存到  破解结果.txt 中!','提示',MB_ICONINFORMATION+MB_OK);
                               exit;
                             end;
                        end;
                    inc(j);
               end;
              inc(i);
          end;
       edit5.Enabled:=true;
       edit6.Enabled:=true;
       edit7.Enabled:=true;
       edit8.Enabled:=true;
       edit9.Enabled:=true;
  
       proexit:=0;
       res.SaveToFile('破解结果.txt');
       Application.MessageBox(pchar('哎!还没达标啊,只找到 '+inttostr(count)+' 组密码'),'提示',MB_ICONINFORMATION+MB_OK);
       Application.MessageBox('结果已经保存到  破解结果.txt 中!','提示',MB_ICONINFORMATION+MB_OK);
  end;
  /*****************************************************************************/
  ===============================================================================
    这是主要的处理事件,其中调用的函数前面已经写过.  
    好了,就到这里吧,搞了一天了.
  ===============================================================================
  
--------------------------------------------------------------------------------
【经验总结】
  这是我第一次真正的全自动"暴力破解",留下一个纪念,增加一点经验.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年04月13日 21:22:09

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 7
打赏
分享
最新回复 (9)
雪    币: 110
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小剑 2007-4-13 21:57
2
0
抢先顶一下,呵呵
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 4 2007-4-13 23:07
3
0
拜读了,very good
雪    币: 333
活跃值: (116)
能力值: ( LV9,RANK:570 )
在线值:
发帖
回帖
粉丝
acafeel 14 2007-4-14 01:58
4
0
厉害呀!!!!!!!!!!
太老虎了!强烈支持!
雪    币: 112
活跃值: (16)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
壹只老虎 7 2007-4-14 02:08
5
0
兄弟还没有睡觉哦!
真牛!
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qqgameban 2007-4-14 22:44
6
0
不错啊,支持你
雪    币: 264
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
playboyjin 2007-4-21 09:43
7
0
good job
雪    币: 234
活跃值: (25)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
kaien 4 2007-4-22 05:12
8
0
Nice!
雪    币: 372
活跃值: (31)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
vxin 10 2007-4-22 09:19
9
0
老虎好牛~~
雪    币: 411
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cyp2 2007-4-23 12:22
10
0
分析的很不错,学习了.
游客
登录 | 注册 方可回帖
返回