首页
社区
课程
招聘
[原创]动态生成代码CrackMe(De-KryptZo1)分析
2007-4-12 23:27 7506

[原创]动态生成代码CrackMe(De-KryptZo1)分析

2007-4-12 23:27
7506
【文章标题】: 动态生成代码CrackMe(De-KryptZo1)分析
【文章作者】: 壹只老虎
【作者邮箱】: tiger..tiger@163.com
【软件名称】: De-KryptZo1
【软件大小】: 5.50 KB
【下载地址】: http://www.crackmes.de/
【加壳方式】: 无
【保护方式】: 动态代码生成+程序崩溃
【编写语言】: 不知道
【使用工具】: od+peid
【操作平台】: windowsxp  sp2
【软件介绍】: http://www.crackmes.de/下载的一个crackme
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  先贴一下作者关于本crackme的说明,对分析有些帮助。
  ===============================================================================
  De-KryptZo - 1
  
  No PATCHING
  NO BRUTE FORCING
  
  FIND SERIAL(S)
  WRITE TUT
  
  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 !
  
  starzboy / iCU
  starzboy@gmail.com
  ===============================================================================
  作者的意思好像是说:不要补丁,不要爆破。
  当输入正确注册码时,你将得到一个"goodboy"消息框,
  当输入错误时,本程序会错误,并且崩溃。
  
  非常有意思,只得分析一下。毕竟对于我来说,算是一个新东西,对里面的奥秘很是好奇。
  运行了一下,随便输入了一个密码,获取hash值,解密,ok,很好,程序崩溃了。
  如果没有看过说明,我肯定会认为是程序设计的问题。但是看了说明之后,就知道是作者故意这么写的。
  
  peid和fi查都没有提示,不确定是否有壳。
  od载入,没有加密提示,应该没有壳。
  
  字符串参考,看一下,发现正确提示“Decryption Successfull ... Good Work !”,
  一切都很顺利,双击过去,
  
  来到了这里:
  ==============================================================================
  00401215        /EB 14             jmp short De-Krypt.0040122B
  00401217        |6A 00             push 0
  00401219        |68 56304000       push De-Krypt.00403056                          ; ASCII "[iCU]"
  0040121E        |68 2F304000       push De-Krypt.0040302F                          ; ASCII "Decryption Successfull ... Good Work !"
  00401223        |FF75 08           push dword ptr ss:[ebp+8]
  00401226        |E8 6D000000       call <jmp.&user32.MessageBoxA>
  0040122B        \90                nop
  0040122C         90                nop
  0040122D         90                nop
  0040122E         90                nop
  0040122F         90                nop
  00401230         90                nop
  00401231         90                nop
  00401232         90                nop
  00401233         90                nop
  00401234         90                nop
  00401235         90                nop
  00401236         90                nop
  00401237         90                nop
  00401238         90                nop
  00401239         90                nop
  0040123A         90                nop
  0040123B         90                nop
  0040123C         90                nop
  0040123D         90                nop
  0040123E         90                nop
  0040123F         90                nop
  00401240         90                nop
  00401241         90                nop
  00401242         90                nop
  00401243         90                nop
  ===============================================================================
  上面这段空白不是为了增加篇幅的,呵呵!后面就知道这里我为什么要贴出来了。
  说明一下,上面这个00401217位置就是正确提示的入口。不要高兴的太早。
  我上下找了一下,没有一个地方是跳向这里的。也就是说,这是一段永远不可能被执行的代码,
  也就是说,永远不可能成功?
  
  当然不是,肯定另有玄机,我也不知道有什么玄机。
  我的习惯,规规矩矩的先把前面的算法分析清楚了再说吧。
  
  先在取得试验码的地方下一个断点。
  004010C0         E8 CD010000       call <jmp.&user32.GetDlgItemTextA>             ; 取得试验码
  
  开始分析吧,运行起来,输入试验码123。“hash it!”,程序断在004010C0。
  
  先看试验码处理算法:
  ===============================================================================
  004010FB        /E9 44010000       jmp De-Krypt.00401244
  00401100        |33C0              xor eax,eax                                    ; eax=0
  00401102        |33F6              xor esi,esi                                    ; esi=0
  00401104        |33C9              xor ecx,ecx                                    ; ecx=0
  00401106        |BA 94000000       mov edx,94                                     ; edx=94H
  0040110B        |33FF              xor edi,edi                                    ; edi=0
  0040110D        |B3 64             mov bl,64                                      ; bl=64h
  0040110F        |BE 60304000       mov esi,De-Krypt.00403060                      ; esi=试验码地址
  00401114        |8A06              mov al,byte ptr ds:[esi]                       ; al=按位取试验码
  00401116        |8AC8              mov cl,al                                      ; cl=al
  00401118        |32D8              xor bl,al                                      ; bl=bl xor al
  0040111A        |02C3              add al,bl                                      ; al=al+bl
  0040111C        |02C1              add al,cl                                      ; al=al+cl
  0040111E        |04 32             add al,32                                      ; al=al+32h
  00401120        |34 35             xor al,35                                      ; al=al xor 35h
  00401122        |02D0              add dl,al                                      ; dl=dl+al
  00401124        |2C F6             sub al,0F6                                     ; al=al-f6
  00401126        |02D0              add dl,al                                      ; dl=dl+al
  00401128        |46                inc esi                                        ; esi=esi+1
  00401129        |FF4D FC           dec dword ptr ss:[ebp-4]
  0040112C        |837D FC 00        cmp dword ptr ss:[ebp-4],0
  00401130       ^|77 E2             ja short De-Krypt.00401114
  00401132        |6A 00             push 0
  00401134        |8AC2              mov al,dl
  00401136        |66:0FB6C0         movzx ax,al
  0040113A        |66:50             push ax
  0040113C        |68 2C304000       push De-Krypt.0040302C                         ; ASCII "%x"
  00401141        |68 60344000       push De-Krypt.00403460
  00401146        |E8 29010000       call <jmp.&user32.wsprintfA>                   ; hash=上面的处理结果的16进制转化为字符串
  
  
  ===============================================================================
  总结一下:功能是对试验码进行计算,得到一个hash值,转化其16进制形势为字符串,保存在hash里。
  这是一段Delphi代码
  /*****************************************************************************/
       dl:=$94;
       bl:=$64;
       for i:=1 to length(pass) do
         begin
              al:=ord(name[i]);
              bl:=bl xor al;
              al:=al+bl+al+$32;
              al:=al xor $35;
              dl:=dl+al+al-$0f6;
         end;
  /*****************************************************************************/
  
  下面还有一段算法,顺便一起给写了:
  ===============================================================================
  004011C8         BE 30104000       mov esi,De-Krypt.00401030                      ; esi=00401030
  004011CD         BF 2B124000       mov edi,De-Krypt.0040122B                      ; edi=0040122b
  004011D2         8A0D 60344000     mov cl,byte ptr ds:[403460]                    ; cl=hash[0]
  004011D8         884D F7           mov byte ptr ss:[ebp-9],cl                     ; [ebp-9]=cl
  004011DB         8A0D 61344000     mov cl,byte ptr ds:[403461]                    ; cl=hash[i]
  004011E1         004D F7           add byte ptr ss:[ebp-9],cl                     ; [ebp-9]=[ebp-9]+cl
  004011E4         33C0              xor eax,eax                                    ; eax=0
  004011E6         8A06              mov al,byte ptr ds:[esi]                       ; al=按位取[esi]
  004011E8         8A4D F7           mov cl,byte ptr ss:[ebp-9]                     ; cl=[ebp-9]
  004011EB         2C 71             sub al,71                                      ; al=al-71h
  004011ED         FEC0              inc al                                         ; al=al+1
  004011EF         04 51             add al,51
  004011F1         04 34             add al,34
  004011F3         04 46             add al,46
  004011F5         02C1              add al,cl
  004011F7         04 53             add al,53
  004011F9         04 54             add al,54
  004011FB         04 20             add al,20
  004011FD         2C 97             sub al,97
  004011FF         2C 71             sub al,71
  00401201         8807              mov byte ptr ds:[edi],al                       ; 关键
  00401203         46                inc esi
  00401204         47                inc edi
  00401205         FF4D FC           dec dword ptr ss:[ebp-4]
  00401208         837D FC 00        cmp dword ptr ss:[ebp-4],0
  0040120C       ^ 77 D6             ja short De-Krypt.004011E4
  0040120E         C605 3B124000 59  mov byte ptr ds:[40123B],59
  
  ===============================================================================
  总结:这段算法里面根据00401030开始的20个字节的内容和hash值,生成一组数据保存在0040122b开始的20个字节里面。
  其实这段算法的关键在这里:
                           00401201         8807              mov byte ptr ds:[edi],al                       ; 关键
  看到这里有助于后面的分析。
  
  注意:00401030开始的20个字节内容是固定的一组数据。如下:
  /*****************************************************************************/
  const
       table:array[1..20]of byte =($B4,$4A,$B2,$A0,$7A,$8A,$4A,$B2,$79,$7A,
                                   $8A,$4A,$49,$BF,$52,$32,$CF,$4A,$4A,$4A);
  /*****************************************************************************/
  
  上面的算法改写后如下:
  /*****************************************************************************/
         key:=inttohex(dl,2);
         key:=lowercase(key);
         if key[1]='0' then
           begin
             key[1]:=key[2];
             key[2]:=#0;
           end;
  
         cl:=ord(key[1])+ord(key[2]);
         for i:=1 to 20 do
          begin
              al:=table[i];
              al:=al+26;
              al:=al+cl;
              code[i]:=al;
          end;
  /*****************************************************************************/
  
  好了,这个循环完了之后,就会发现一个很好玩的地方,你看----->
  ===============================================================================
  0040120E         C605 3B124000 59  mov byte ptr ds:[40123B],59
  00401215         EB 14             jmp short De-Krypt.0040122B
  00401217         6A 00             push 0
  00401219         68 56304000       push De-Krypt.00403056                         ; ASCII "[iCU]"
  0040121E         68 2F304000       push De-Krypt.0040302F                         ; ASCII "Decryption Successfull ... Good Work !"
  00401223         FF75 08           push dword ptr ss:[ebp+8]
  00401226         E8 6D000000       call <jmp.&user32.MessageBoxA>
  0040122B         92                xchg eax,edx
  0040122C         2890 7E586828     sub byte ptr ds:[eax+2868587E],dl
  00401232         90                nop
  00401233         57                push edi
  00401234         58                pop eax
  00401235         68 28279D30       push 309D2728
  0040123A         1059 28           adc byte ptr ds:[ecx+28],bl
  0040123D         2828              sub byte ptr ds:[eax],ch
  0040123F         90                nop
  00401240         90                nop
  00401241         90                nop
  00401242         90                nop
  00401243         90                nop
  ===============================================================================
  看得很明白,发现什么了?
  看看开始的时候这一段是什么数据。
  前面我已经贴出来了。对比一下。
  就明白,这一段代码是刚才生成的。
  动态的哦,我还是第一次玩这种东西呢。
  太有意思了。
  (脱壳那种不算哈)
  呵呵,我们慢慢的F8走吧。
  当达到这里
  0040122C         2890 7E586828     sub byte ptr ds:[eax+2868587E],dl
  的时候,程序就异常退出了。
  原因么:看看堆栈就明白了。
  dl=28 ('(')
  ds:[2868587F]=???,你说这能不异常吗?能不崩溃么?
  其实我也是后来才注意到的,呵呵。
  
  好了,现在能分析的都分析了。
  我们现在还是没多少头绪。
  我们现在需要总结一下。
  
  我们的目标是要执行那个正确提示,就是说想方设法的要跳转到这里“00401217”,
  怎么跳呢?00401215 语句是绝对跳转,只能是回跳了。
  呵呵,如果生成代码是这样该多好:
  
          push  eax
          mov   eax,x
          inc   eax
          mov   x,eax
          pop   eax
          cmp   x,1
          je   00401217
         
  
  我一直在尝试,经过多次的失败,我发现,我的尝试是徒劳的.
  在想想作者的说明,他说要找密码.再看看上面的两个算法,
  虽然说很简单,但是很明显第一个算法是一个有损压缩算法.
  所以没办法逆推到注册密码.所以只能是用注册码来推生成的代码.
  (这个时候生成码是什么也就不重要了,只要能注册成功就可以了)
  现在注册码不知道,已经是绝路了.怎么办?
  
  眼前似乎还有一丝的光明.
  注意一下:hash字符串是由dl转换来的,dl是8位的,也就是说两个16进制字母,
  也就是说hash值最多2位,(可能为1位,高位为0),也就是说可能性最多256种,
  看看hash的算法还可以知道dl只可能是偶数,可能性就减半,也就是128种,
  
  好了,我们需要分析下程序的写法,为了方便,我们就用正整数来做密码,
  每次加1来生成hash值,生成的hash值如果存在了就不保存,不存在就保存.
  
  当hash值个数>127的时候,就跳出循环.输出分析结果到文件.
  
  我也只能这么做了.
  看看下面的代码.
  /******************************************************************************/
  function CrAck(t:string):integer;
  var
     al,bl,dl:byte;
     i:integer;
  begin
       dl:=$94;
       bl:=$64;
       for i:=1 to length(t)do
         begin
              al:=ord(t[i]);
              bl:=bl xor al;
              al:=al+bl+al+$32;
              al:=al xor $35;
              dl:=dl+al+al-$0f6;
         end;
       result:=dl;
  end;
  
  tm:=tstringlist.Create();
  rs:=tstringlist.Create();
  i:=1;
  while true do
    begin
      name:=inttostr(i);
      dl:=CrAck(name);
      j:=0;
      while j<tm.Count do
        begin
           if tm[j]=inttostr(dl) then
             break;
           inc(j);
       end;
      if j=tm.Count then
        begin
          tm.Add(inttostr(dl));
          rs.Add(name+'        '+inttostr(dl));
        end;
      inc(i);
      if rs.Count>127 then
         break;
    end;
  rs.SaveToFile('res.txt');
  /******************************************************************************/
  
  上面这段代码,运行后就把结果保存到res.txt了,
  打开文件来,一个一个测试吧,笨办法,不就128个吗?
  慢慢来!下面是测试结果.
  ===============================================================================
  1------>86(异常退出)
  2------>80(异常退出)
  3------>82(异常退出)
  4------>92(异常退出)
  5------>78------------>没有反应
  6------>40(异常退出)
  7------>42(异常退出)
  8------>52(异常退出)
  9------>6(异常退出)
  10------>228---------->没有反应
  11------>250(异常退出)
  12------>240(异常退出)
  13------>246-------------------->成功了
  14------>252---------->没有反应
  15------>242(异常退出)
  16------>200(异常退出)
  17------>206(异常退出)
  18------>212(异常退出)
  19------>170(异常退出)
  20------>244(异常退出)
  22------>248(异常退出)
  23------>234---------->直接退出
  24------>236(异常退出)
  25------>238(异常退出)
  27------>194(异常退出)
  28------>164(异常退出)
  29------>166(异常退出)
  37------>198---------->没有反应
  41------>230(异常退出)
  42------>0(异常退出)
  43------>2(异常退出)
  47------>202(异常退出)
  49------>214(异常退出)
  51------>218(异常退出)
  56------>184(异常退出)
  57------>190(异常退出)
  60------>180(异常退出)
  61------>182(异常退出)
  64------>156-------------------->成功了
  65------>158(异常退出)
  66------>160(异常退出)
  67------>146(异常退出)
  71------>186(异常退出)
  75------>162(异常退出)
  77------>150(异常退出)
  84------>172(异常退出)
  91------>122(异常退出)
  92------>112(异常退出)
  93------>118(异常退出)
  94------>124(异常退出)
  95------>114(异常退出)
  96------>136(异常退出)
  97------>142(异常退出)
  98------>116(异常退出)
  99------>138---------->没有反应
  101------>168---------->没有反应
  108------>130(异常退出)
  109------>88(异常退出)
  111------>188(异常退出)
  117------>144(异常退出)
  118------>154(异常退出)
  119------>108---------->没有反应
  120------>178(异常退出)
  125------>176(异常退出)
  126------>174---------->直接退出
  127------>132(异常退出)
  128------>98(异常退出)
  129------>104(异常退出)
  138------>106(异常退出)
  143------>196(异常退出)
  146------>134(异常退出)
  147------>140(异常退出)
  149------>152(异常退出)
  156------>126-------------------->成功了
  157------>128(异常退出)
  161------>120(异常退出)
  164------>90(异常退出)
  165------>96(异常退出)
  166------>94(异常退出)
  167------>84(异常退出)
  175------>100(异常退出)
  176------>102(异常退出)
  191------>60(异常退出)
  192------>54(异常退出)
  193------>56(异常退出)
  194------>66(异常退出)
  198------>58(异常退出)
  199------>76(异常退出)
  219------>110(异常退出)
  224------>192(异常退出)
  283------>46(异常退出)
  284------>48(异常退出)
  285------>50(异常退出)
  287------>70(异常退出)
  288------>72(异常退出)
  289------>74(异常退出)
  291------>62(异常退出)
  391------>64(异常退出)
  424------>148(异常退出)
  626------>68(异常退出)
  648------>16(异常退出)
  649------>18(异常退出)
  659------>22(异常退出)
  676------>36(异常退出)
  748------>14(异常退出)
  749------>20(异常退出)
  759------>24(异常退出)
  777------>44(异常退出)
  779------>8(异常退出)
  911------>12(异常退出)
  915------>4(异常退出)
  916------>30(异常退出)
  917------>32(异常退出)
  918------>10(异常退出)
  919------>28(异常退出)
  926------>254(异常退出)
  938------>26(异常退出)
  980------>34(异常退出)
  989------>232(异常退出)
  1049------>38(异常退出)
  1067------>226(异常退出)
  1094------>208(异常退出)
  1096------>220(异常退出)
  1097------>222---------->没有反应
  1191------>224(异常退出)
  1195------>216-------------------->成功了
  1284------>204---------->直接退出
  1285------>210(异常退出)
  
  ===============================================================================
  
  通过结果,我们发现,正确的注册码有4个,还有没有反应的代码有8个,直接退出的注册码有3个,其它都是崩溃的注册码.
  现在密码找到了,我们来看看这几类密码生成的汇编代码吧.如下:
  
  ===============================================================================
  key=5------------>没有反应
  00401215        /EB 14             jmp short De-Krypt.0040122B
  00401217        |6A 00             push 0
  00401219        |68 56304000       push De-Krypt.00403056                          ; ASCII "[iCU]"
  0040121E        |68 2F304000       push De-Krypt.0040302F                          ; ASCII "Decryption Successfull ... Good Work !"
  00401223        |FF75 08           push dword ptr ss:[ebp+8]
  00401226        |E8 6D000000       call <jmp.&user32.MessageBoxA>
  0040122B        \67:FD             std
  0040122D         65:53             push ebx
  0040122F         2D 3DFD652C       sub eax,2C65FD3D
  00401234         2D 3DFDFC72       sub eax,72FCFD3D
  00401239         05 E559FDFD       add eax,FDFD59E5
  0040123E         FD                std
  0040123F         90                nop
  00401240         90                nop
  00401241         90                nop
  00401242         90                nop
  00401243         90                nop
  ===============================================================================
  key=23---------->直接退出
  00401215        /EB 14             jmp short De-Krypt.0040122B
  00401217        |6A 00             push 0
  00401219        |68 56304000       push De-Krypt.00403056                          ; ASCII "[iCU]"
  0040121E        |68 2F304000       push De-Krypt.0040302F                          ; ASCII "Decryption Successfull ... Good Work !"
  00401223        |FF75 08           push dword ptr ss:[ebp+8]
  00401226        |E8 6D000000       call <jmp.&user32.MessageBoxA>
  0040122B        \94                xchg eax,esp
  0040122C         2A92 805A6A2A     sub dl,byte ptr ds:[edx+2A6A5A80]
  00401232         92                xchg eax,edx
  00401233         59                pop ecx
  00401234         5A                pop edx
  00401235         6A 2A             push 2A
  00401237         299F 3212592A     sub dword ptr ds:[edi+2A591232],ebx
  0040123D         2A2A              sub ch,byte ptr ds:[edx]
  0040123F         90                nop
  00401240         90                nop
  00401241         90                nop
  00401242         90                nop
  00401243         90                nop
  ===============================================================================
  key=13---------->成功了
  00401215        /EB 14             jmp short De-Krypt.0040122B
  00401217        |6A 00             push 0
  00401219        |68 56304000       push De-Krypt.00403056                          ; ASCII "[iCU]"
  0040121E        |68 2F304000       push De-Krypt.0040302F                          ; ASCII "Decryption Successfull ... Good Work !"
  00401223        |FF75 08           push dword ptr ss:[ebp+8]
  00401226        |E8 6D000000       call <jmp.&user32.MessageBoxA>
  0040122B        \6A 00             push 0
  0040122D         68 56304000       push De-Krypt.00403056                          ; ASCII "[iCU]"
  00401232         68 2F304000       push De-Krypt.0040302F                          ; ASCII "Decryption Successfull ... Good Work !"
  00401237         FF75 08           push dword ptr ss:[ebp+8]
  0040123A         E8 59000000       call <jmp.&user32.MessageBoxA>
  0040123F         90                nop
  00401240         90                nop
  00401241         90                nop
  00401242         90                nop
  00401243         90                nop
  ===============================================================================
  前面两个就不分析了,没什么意思,看看正确的这个吧.
  非常遗憾,很可以,我前面猜错了,没想到作者把代码从新生成了一次,哎!
  太奇妙了.不要以为这是自符串复制哦,我试了的,把上面那一段nop掉也一样可以的.
  上面那段代码除了有一个提示作用,没有任何作用,nop掉依然可以.
  
  所以,这个crackme分析完了,得到几个密码,如下:
  13,64,156,1195(这几个数据生成的代码是完全一样的)
  
  分析完毕,有些创意,非常不错.
  

  注意:如果我们知道了生成的代码的话,那么就可以用程序来实现上面的手工测试,
       我将会在下一篇文章中仔细分析.
--------------------------------------------------------------------------------
【经验总结】
  这总思路用在软件加壳里面或者加密里面,应该非常不错.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年04月12日 23:20:57

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
打赏
分享
最新回复 (4)
雪    币: 214
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
仙剑太郎 2 2007-4-13 17:54
2
0
有趣,SMC``不过比较难应用在日常中
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
binbinbin 28 2007-4-13 22:31
3
0
厉害,楼主真细心
雪    币: 424
活跃值: (10)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
大菜一号 21 2007-4-14 08:45
4
0
``老虎兄又一精``牛哇`
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stones 2007-4-23 19:07
5
0
我找了一种快速破解的方法就是修改原程序的代码,让他可以输入任意字符都可成功.
00401215   .  EB 14         jmp     short 0040122B 如果你的注册码输入正确了,那么0040122B地址的内容应该是0040122B  ^\EB E8         jmp     short 00401217 回跳到正确提示那里的,想一想我们自己要是把他改成这样子呢,那岂不是所有的字符串都可以通过证了.
    那就让我开始吧,BF 2B124000   mov     edi, 0040122B  程序把生成的代码写的0040122B,其中的内容是注册码和其内部算法动态生成的好了,现在我说一下我是怎么修改的吧!

004011C8   .  BE 30104000   mov     esi, 00401030
004011CD      BF 2F124000   mov     edi, 0040122F
004011D2   .  8A0D 60344000 mov     cl, byte ptr [403460]
004011D8   .  884D F7       mov     byte ptr [ebp-9], cl
004011DB   .  8A0D 61344000 mov     cl, byte ptr [403461]
004011E1   .  004D F7       add     byte ptr [ebp-9], cl
004011E4   >  33C0          xor     eax, eax
004011E6   .  8A06          mov     al, byte ptr [esi]
004011E8   .  8A4D F7       mov     cl, byte ptr [ebp-9]
004011EB   .  2C 71         sub     al, 71
004011ED   .  FEC0          inc     al
004011EF   .  04 51         add     al, 51
004011F1   .  04 34         add     al, 34
004011F3   .  04 46         add     al, 46
004011F5   .  02C1          add     al, cl
004011F7   .  04 53         add     al, 53
004011F9   .  04 54         add     al, 54
004011FB   .  04 20         add     al, 20
004011FD   .  2C 97         sub     al, 97
004011FF   .  2C 71         sub     al, 71
00401201   .  8807          mov     byte ptr [edi], al
00401203   .  46            inc     esi
00401204   .  47            inc     edi
00401205   .  FF4D FC       dec     dword ptr [ebp-4]
00401208   .  837D FC 00    cmp     dword ptr [ebp-4], 0
0040120C   .^ 77 D6         ja      short 004011E4
0040120E   .  C605 3B124000>mov     byte ptr [40123B], 59
00401215      EB 16         jmp     short 0040122D
00401217   .  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401219   .  68 56304000   push    00403056                         ; |Title = "[iCU]"
0040121E   .  68 2F304000   push    0040302F                         ; |Text = "Decryption Successfull ... Good Work !"
00401223   .  FF75 08       push    dword ptr [ebp+8]                ; |hOwner
00401226   .  E8 6D000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
0040122B      EB 36         jmp     short 00401263
0040122D    ^ EB E8         jmp     short 00401217

0040122F      90            nop
00401230      90            nop
00401231      90            nop
00401232      90            nop
00401233   .  90            nop
00401234   .  90            nop
00401235   .  90            nop
00401236   .  90            nop

其中主要修改了四个地方(用红色标出):
1、首先0040122D    ^ EB E8         jmp     short 00401217 回跳到正确提示那里,你要问了,上面不是说了0040122B  ^\EB E8         jmp     short 00401217?不错,我一开始是这么修改的,但是结果是可注册成功,但是它进入了死循环无法正常结束了,所以我后才改到了0040122D 。
2、然后修改00401215      EB 16         jmp     short 0040122D,让他总无条件的跳到正确提示那里
3、再次修改004011CD      BF 2F124000   mov     edi, 0040122F,保证程序动态生成的代码不破坏我们所修改的。
最后,0040122B      EB 36         jmp     short 00401263,保证程序能够正常退出。。。

具体的可以到我个人网站上去看:www.cleverstones.cn
游客
登录 | 注册 方可回帖
返回