飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 2724|回复: 8

一个比较有代表的虚拟方法保护软件

[复制链接]
  • TA的每日心情
    开心
    2017-4-4 09:40
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2005-4-5 10:28:45 | 显示全部楼层 |阅读模式
    【软件名称】:互联网点歌台 V3.91
    【软件大小】:1.46M
    【下载地址】:http://mpt.zj.com/
    【软件简介】:随着宽带网的普及,网速越来越快,网上听音乐已不成问题。使用互联网点歌台,只用鼠标轻轻一“点歌”,就能让您听遍全世界的音乐,免去寻找下载歌曲的麻烦。
      互联网点歌台是国内第一款高度集成歌曲搜索及播放功能的音乐软件。把自己想要听的歌曲输入,就能一下子听到你想要的歌曲,看你想要的歌词。支持几乎所有歌曲类型,如mp3、wma、rm等,可编程播放。音质媲美winamp。

    第19届全国科技创新大赛(CASTIC Computer Science)获奖作品   中国·成都
      
    【功能介绍】:
    1.  搜索播放网络歌曲,支持mp3、wma等搜索,广泛的歌曲搜索量(“全部”类型歌曲更多,更强大),支持Windows Media Player格式、Real Player格式。  
    2.  最新版本完全采用了MPT-Link第二代技术,最大限度保证了搜索的成功率,支持同名歌曲的智能区分,点歌率>97%。
    3.  支持点歌单系统,可编程搜索播放,并能保存点歌单。点歌单文件具有地址自动记忆功能,可直接双击启动互联网点歌台顺序播放。
    4.  歌曲同步批量下载(断点续传)。
    5.  自动搜索权威音乐排行榜TOP100,搜索播放歌手与专辑。
    6.  同步显示歌词。  
    7.  能最小化至托盘播放,悬浮窗显示,方便快捷。

    【软件限制】:

    V3.9 未注册版与注册版的区别:
    1.全部类型选择(更多的歌曲数量,更快的点歌速度).
    2.享受歌手与专辑/网络广播电台/历史记录导入/候选地址导入功能.
    3.未注册版在搜索歌词后歌词不能保存,且会在歌词底部增加注册信息.
    4.未注册版不具有批量下载功能.
    5.注册版可查看全部排行榜.
    6.注册版可以享有所有售后服务.

    【保护方式】:注册码保护
    破解声明】:初学Crack,只是感兴趣,失误之处敬请诸位大侠赐教!
    【破解工具】:OllyDbg.V1.10聆风听雨汉化第二版、PeID 0.93

    --------------------------------------------------------------------------------------------------------------

    【破解过程】:
    先用PEID 0.93汉化增强版查壳,Borland Delphi 6.0 - 7.0,无壳?  OD 直接载入MusicPoint.exe,查找参考字符串"感谢你的注册..."双击后向上查找,来到这里:
    005189B5    55              push ebp
    005189B6    68 6B8A5100     push <MusicPoi.->System.@HandleFinally>
    005189BB    64:FF30         push dword ptr fs:[eax]
    005189BE    64:8920         mov dword ptr fs:[eax],esp
    005189C1    8D55 FC         lea edx,dword ptr ss:[ebp-4]
    005189C4 >  8B83 F8020000   mov eax,dword ptr ds:[ebx+2F8]         ; *Tfrmreg.Edit1:TLabeledEdit
    005189CA >  E8 AD49F4FF     call MusicPoi.0045D37C                 ; ->Controls.TControl.GetText(TControl):TCaption;
    005189CF    837D FC 00      cmp dword ptr ss:[ebp-4],0             ; 机器码不能为空
    005189D3    74 11           je short MusicPoi.005189E6
    005189D5 >  8B83 04030000   mov eax,dword ptr ds:[ebx+304]         ; *Tfrmreg.btnget:TBitBtn
    005189DB    66:BE EBFF      mov si,0FFEB
    005189DF >  E8 0CB6EEFF     call MusicPoi.00403FF0                 ; ->System.@CallDynaInst 本破文关键所在!!!
    005189E4    EB 0C           jmp short MusicPoi.005189F2
    005189E6    B8 808A5100     mov eax,MusicPoi.00518A80              ; 机器码为空提示"请生成机器码"
    005189EB >  E8 FCD0F1FF     call MusicPoi.00435AEC                 ; ->Dialogs.ShowMessage(AnsiString);
    005189F0    EB 5E           jmp short MusicPoi.00518A50
    005189F2    8D55 F8         lea edx,dword ptr ss:[ebp-8]
    005189F5 >  8B83 FC020000   mov eax,dword ptr ds:[ebx+2FC]         ; *Tfrmreg.Edit2:TLabeledEdit
    005189FB >  E8 7C49F4FF     call MusicPoi.0045D37C                 ; ->Controls.TControl.GetText(TControl):TCaption;
    00518A00    8B45 F8         mov eax,dword ptr ss:[ebp-8]           ; 注册码
    00518A03    8B15 3C415200   mov edx,dword ptr ds:[52413C]          ; 计算后的机器码
    00518A09 >  E8 42C6EEFF     call MusicPoi.00405050                 ; ->System.@LStrCmp;
    00518A0E    75 2C           jnz short MusicPoi.00518A3C            ; 明码比较,可以爆破或制作内存注册机 ^_^
    00518A10    6A 40           push 40
    00518A12    68 908A5100     push MusicPoi.00518A90
    00518A17    68 A08A5100     push MusicPoi.00518AA0                 ; 感谢你的注册...
    00518A1C    8BC3            mov eax,ebx
    00518A1E >  E8 A5B2F4FF     call MusicPoi.00463CC8                 ; ->QForms.TCustomForm.GetClientHandle(TCustomForm):QWorkspaceH;
    00518A23    50              push eax
    00518A24 >  E8 5BF1EEFF     call <jmp.&user32.MessageBoxA>         ; ->user32.MessageBoxA()
    00518A29    8BC3            mov eax,ebx                            ; 提示注册成功。
    00518A2B    E8 AC000000     call MusicPoi.00518ADC                 ; 保存注册信息到注册表中
    00518A30    A1 38415200     mov eax,dword ptr ds:[524138]
    00518A35 >  E8 1A13F6FF     call MusicPoi.00479D54                 ; ->Forms.TCustomForm.Close(TCustomForm);
    00518A3A    EB 14           jmp short MusicPoi.00518A50
    00518A3C    B8 D08A5100     mov eax,MusicPoi.00518AD0
    00518A41 >  E8 A6D0F1FF     call MusicPoi.00435AEC                 ; ->Dialogs.ShowMessage(AnsiString);
    00518A46    A1 38415200     mov eax,dword ptr ds:[524138]
    00518A4B >  E8 0413F6FF     call MusicPoi.00479D54                 ; ->Forms.TCustomForm.Close(TCustomForm);
    00518A50    33C0            xor eax,eax
    00518A52    5A              pop edx
    00518A53    59              pop ecx
    00518A54    59              pop ecx
    00518A55    64:8910         mov dword ptr fs:[eax],edx
    00518A58    68 728A5100     push MusicPoi.00518A72
    00518A5D    8D45 F8         lea eax,dword ptr ss:[ebp-8]
    00518A60    BA 02000000     mov edx,2
    00518A65 >  E8 FEC1EEFF     call MusicPoi.00404C68                 ; ->System.@LStrArrayClr(void;void;Integer);
    00518A6A    C3              retn
    00518A6B >^ E9 18BBEEFF     jmp MusicPoi.00404588                  ; ->System.@HandleFinally;
    00518A70  ^ EB EB           jmp short MusicPoi.00518A5D
    00518A72    5E              pop esi
    00518A73    5B              pop ebx
    00518A74    59              pop ecx
    00518A75    59              pop ecx
    00518A76    5D              pop ebp
    00518A77    C3              retn

    一看是明码比较,晕。本想注册一下能用就行了,但发现作者使用虚拟方法保护,兴趣来了……


    从互联网上查的有关System.@CallDynaInst 函数的一些资料,方便大家参考:


                                                虚拟方法表格和动态方法表格

       Delphi 中虚方法是通过类的虚拟方法表格(Virtul Method Table,简称 VMT)或者动态方法表格(Dynamic Method Table,简称 DMT)实现的。VMT 中存放着类及其基类声明的所有虚方法的指针[4]。每个类都具有一个唯一的 VMT,并且是在编译期间就确定的,所有由该类创建的对象都共享同一个 VMT,VMT 中除了一个虚方法表外,还包括其他有关一个类的信息[4]。

       DMT 是 Delphi 中实现虚方法的另一种方式。利用 DMT 可以有效减小 VMT 的体积,但执行效率稍差。
       DMT 中存有类所声明的动态方法和消息句柄,但并不包括从祖先类继承的方法。用关键字 dynamic 或者 message 声明的方法都会以动态方法实现。从 VMT + vmtDynamicTable 偏移处取出的 DWORD 值就是指向类的 DMT 指针。DMT 的结构在 Delphi 中是 Undocumented 的,但通过阅读 VCL 源码和 Debug 很容易写出 DMT 在内存中的逻辑布局:

    type
      TDynmethodTable = packed record
        Count: Word;
        Indexes: packed array[1..Count] of SmallInt;
        Addresses: packed array[1..Count] of Pointer;
      end;
       假如我们声明了如下的类:
      TMyObject = class
      private
        procedure DM1; dynamic;
        procedure DM2; dynamic;
        procedure WMCommand(var Message); message WM_COMMAND;
      public
        procedure DM3; dynamic;
      end;

       凡是带 dynamic 的关键字的方法都会被编译器按照在它们在类中声明的顺序赋予一个编号,或者说 ID,编号用一个 SmallInt 值表示,顺序为 $FFFF,$FFFE,$FFFD...当编译器遇到 message 时,方法的编号则用消息 ID 表示,例如 WM_COMMAND 代表 $0111,有了这些分析我们很容易把这个类的 DMT 按照上面的内存布局描述出来:

      4     // Count =4,即包括4个动态方法
      $FFFF // DM1 的编号
      $FFFE // DM2 的编号
      $0111 // WMCommand 的消息 ID
      $FFFD // DM3 的编号
      DM1 入口地址
      DM2 入口地址
      WMCommand 入口地址
      DM3 入口地址

       这些方法是如何被调用的呢?对于带 dynamic 关键字的方法是通过调用 System._CallDynaInst 实现的。通常这样:

    mov eax,ebx        ; eax = point to current object
    mov si,$ffff       ; si 为方法编号
    call @CallDynaInst

    而System._CallDynaInst 继而会调用 System.GetDynaMethod 获得对应方法编号的方法入口地址,并直接跳到方法入口地址,执行该方法:

    procedure _CallDynaInst;
    asm
            PUSH    EAX
            PUSH    ECX
            MOV     EAX,[EAX] ;注意调用时传递的是 VMT
            CALL    GetDynaMethod
            POP     ECX
            POP     EAX
            JE      @@Abstract
            JMP     ESI ; ESI 指向动态方法入口地址
    @@Abstract:
            POP     ECX
            JMP     _AbstractError
    end;


       System.GetDynaMethod 则在 DMT 中寻找该动态方法的编号,如果找到了,就从 DMT 中取得该方法的入口地址;如果找不到,则继续在父类的 DMT 中寻找该方法编号直至 TObject 的 DMT(TObject 中指向 DMT 的指针为 nil,循环到这里自然会停止):
    procedure GetDynaMethod;
    {       function        GetDynaMethod(vmt: TClass; selector: Smallint) : Pointer;       }
    asm
            { ->    EAX     vmt of class            }
            {       SI      dynamic method index    }
            { <-    ESI pointer to routine  }
            {       ZF = 0 if found         }
            {       trashes: EAX, ECX               }

            PUSH    EDI
            XCHG    EAX,ESI
            JMP     @@haveVMT
    @@outerLoop:
            MOV     ESI,[ESI]
    @@haveVMT:
            MOV     EDI,[ESI].vmtDynamicTable
            TEST    EDI,EDI
            JE      @@parent
            MOVZX   ECX,word ptr [EDI]
            PUSH    ECX
            ADD     EDI,2
            REPNE   SCASW
            JE      @@found
            POP     ECX
    @@parent:
            MOV     ESI,[ESI].vmtParent
            TEST    ESI,ESI
            JNE     @@outerLoop
            JMP     @@exit

    @@found:
            POP     EAX
            ADD     EAX,EAX
            SUB     EAX,ECX         { this will always clear the Z-flag ! }
            MOV     ESI,[EDI+EAX*2-4]

    @@exit:
            POP     EDI
    end;


    大家再看看上面的注册验证代码中的几行代码:
    --------------------------------------------------------------------------------------------------------------
    005189D5 >  8B83 04030000   mov eax,dword ptr ds:[ebx+304]         ; *Tfrmreg.btnget:TBitBtn
    005189DB    66:BE EBFF      mov si,0FFEB
    005189DF >  E8 0CB6EEFF     call MusicPoi.00403FF0                 ; ->System.@CallDynaInst
    --------------------------------------------------------------------------------------------------------------


    跟进005189DF >  E8 0CB6EEFF     call MusicPoi.00403FF0   
    --------------------------------------------------------------------------------------------------------------
    00403FF0    50              push eax
    00403FF1    51              push ecx
    00403FF2    8B00            mov eax,dword ptr ds:[eax]
    00403FF4    E8 C7FFFFFF     call MusicPoi.00403FC0        //这就是 GetDynaMethod 啦
    00403FF9    59              pop ecx
    00403FFA    58              pop eax
    00403FFB    74 02           je short MusicPoi.00403FFF
    00403FFD    FFE6            jmp esi                      //看牢这里,它可是指向动态方法入口地址哦
    00403FFF    59              pop ecx
    00404000  ^ E9 53ECFFFF     jmp MusicPoi.00402C58
    00404005    C3              retn
    --------------------------------------------------------------------------------------------------------------
    和上面的理论一一对应了,继续……


    0043CDB0    53              push ebx                               ; 动态方法入口地址
    0043CDB1    8BD8            mov ebx,eax
    0043CDB3    8A83 21020000   mov al,byte ptr ds:[ebx+221]
    0043CDB9    2C 03           sub al,3
    0043CDBB    74 1F           je short MusicPoi.0043CDDC
    0043CDBD    2C 03           sub al,3
    0043CDBF    75 52           jnz short MusicPoi.0043CE13
    0043CDC1    8BC3            mov eax,ebx
    0043CDC3    E8 80790300     call MusicPoi.00474748
    0043CDC8    85C0            test eax,eax
    0043CDCA    74 07           je short MusicPoi.0043CDD3
    0043CDCC    E8 83CF0300     call MusicPoi.00479D54
    0043CDD1    EB 47           jmp short MusicPoi.0043CE1A
    0043CDD3    8BC3            mov eax,ebx
    0043CDD5    E8 5E710100     call MusicPoi.00453F38
    0043CDDA    5B              pop ebx
    0043CDDB    C3              retn
    0043CDDC    8BC3            mov eax,ebx
    0043CDDE    EB 03           jmp short MusicPoi.0043CDE3
    0043CDE0    8B40 30         mov eax,dword ptr ds:[eax+30]
    0043CDE3    85C0            test eax,eax
    0043CDE5    74 09           je short MusicPoi.0043CDF0
    0043CDE7    83B8 58010000 0>cmp dword ptr ds:[eax+158],0
    0043CDEE  ^ 74 F0           je short MusicPoi.0043CDE0
    0043CDF0    85C0            test eax,eax
    0043CDF2    74 16           je short MusicPoi.0043CE0A
    0043CDF4    8B15 0C2C5200   mov edx,dword ptr ds:[522C0C]          ; MusicPoi.00523BF0
    0043CDFA    8B12            mov edx,dword ptr ds:[edx]
    0043CDFC    8B80 58010000   mov eax,dword ptr ds:[eax+158]
    0043CE02    92              xchg eax,edx
    0043CE03    E8 2C0C0400     call MusicPoi.0047DA34
    0043CE08    EB 10           jmp short MusicPoi.0043CE1A
    0043CE0A    8BC3            mov eax,ebx
    0043CE0C    E8 27710100     call MusicPoi.00453F38
    0043CE11    5B              pop ebx
    0043CE12    C3              retn
    0043CE13    8BC3            mov eax,ebx
    0043CE15    E8 1E710100     call MusicPoi.00453F38                 ; 注册算法,关键跟进
    0043CE1A    5B              pop ebx
    0043CE1B    C3              retn



    call MusicPoi.00453F38函数,注册码关键算法:
    --------------------------------------------------------------------------------------------------------------
    005188D0 >  55              push ebp                               ; <-Tfrmreg@btngetClick
    005188D1    8BEC            mov ebp,esp
    005188D3    6A 00           push 0
    005188D5    6A 00           push 0
    005188D7    53              push ebx
    005188D8    56              push esi
    005188D9    57              push edi
    005188DA    8BD8            mov ebx,eax
    005188DC    33C0            xor eax,eax
    005188DE    55              push ebp
    005188DF    68 8B895100     push <MusicPoi.->System.@HandleFinally>
    005188E4    64:FF30         push dword ptr fs:[eax]
    005188E7    64:8920         mov dword ptr fs:[eax],esp
    005188EA    B8 3C415200     mov eax,MusicPoi.0052413C
    005188EF >  E8 50C3EEFF     call MusicPoi.00404C44                 ; ->System.@LStrClr(void;void);
    005188F4    8D55 FC         lea edx,dword ptr ss:[ebp-4]
    005188F7 >  8B83 F8020000   mov eax,dword ptr ds:[ebx+2F8]         ; *Tfrmreg.Edit1:TLabeledEdit
    005188FD >  E8 7A4AF4FF     call MusicPoi.0045D37C                 ; ->Controls.TControl.GetText(TControl):TCaption;
    00518902    8B45 FC         mov eax,dword ptr ss:[ebp-4]           ; 机器码 MachineCode
    00518905 >  E8 FAC5EEFF     call MusicPoi.00404F04                 ; ->System.@LStrLen(String):Integer;<+>
    0051890A    8BF0            mov esi,eax                            ; 机器码长度 Length
    0051890C    85F6            test esi,esi
    0051890E    7E 4B           jle short MusicPoi.0051895B            ; 如果长度<=0 则Over!
    00518910    BF 01000000     mov edi,1                              ; i=1
    00518915    8B45 FC         mov eax,dword ptr ss:[ebp-4]           ; 机器码
    00518918    33DB            xor ebx,ebx
    0051891A    8A5C38 FF       mov bl,byte ptr ds:[eax+edi-1]         ; MachineCode
    0051891E    83FB 41         cmp ebx,41                             ; 假如  MachineCode<'A' 则MachineCode+1E
    00518921    7C 14           jl short MusicPoi.00518937
    00518923    83FB 5A         cmp ebx,5A                             ; 假如  MachineCode>'Z' 则MachineCode+1E
    00518926    7F 0F           jg short MusicPoi.00518937
    00518928    83FB 49         cmp ebx,49                             ; 假如  MachineCode>='I' 则MachineCode-5
    0051892B    7D 05           jge short MusicPoi.00518932
    0051892D    83C3 07         add ebx,7                              ; 假如  MachineCode<'I'  则MachineCode+7
    00518930    EB 08           jmp short MusicPoi.0051893A
    00518932    83EB 05         sub ebx,5
    00518935    EB 03           jmp short MusicPoi.0051893A
    00518937    83C3 1E         add ebx,1E
    0051893A    8D45 F8         lea eax,dword ptr ss:[ebp-8]
    0051893D    8BD3            mov edx,ebx
    0051893F >  E8 E8C4EEFF     call MusicPoi.00404E2C                 ; ->System.@LStrFromChar(String;String;Char);<+>
    00518944    8B55 F8         mov edx,dword ptr ss:[ebp-8]
    00518947    B8 3C415200     mov eax,MusicPoi.0052413C
    0051894C    8B0D 3C415200   mov ecx,dword ptr ds:[52413C]
    00518952 >  E8 F9C5EEFF     call MusicPoi.00404F50                 ; 字符串的连接->System.@LStrCat3;注意是倒序
    00518957    47              inc edi
    00518958    4E              dec esi
    00518959  ^ 75 BA           jnz short MusicPoi.00518915            ; 循环
    0051895B    B8 3C415200     mov eax,MusicPoi.0052413C
    00518960    8B0D 3C415200   mov ecx,dword ptr ds:[52413C]          ; 连接后的字符串
    00518966    BA A4895100     mov edx,MusicPoi.005189A4              ; 字符 '8'
    0051896B >  E8 E0C5EEFF     call MusicPoi.00404F50                 ; ->System.@LStrCat3;
    00518970    33C0            xor eax,eax                            ; '8'+连接后的字符串,即为有效注册码
    00518972    5A              pop edx
    00518973    59              pop ecx
    00518974    59              pop ecx
    00518975    64:8910         mov dword ptr fs:[eax],edx
    00518978    68 92895100     push MusicPoi.00518992
    0051897D    8D45 F8         lea eax,dword ptr ss:[ebp-8]
    00518980    BA 02000000     mov edx,2
    00518985 >  E8 DEC2EEFF     call MusicPoi.00404C68                 ; ->System.@LStrArrayClr(void;void;Integer);
    0051898A    C3              retn
    0051898B >^ E9 F8BBEEFF     jmp MusicPoi.00404588                  ; ->System.@HandleFinally;
    00518990  ^ EB EB           jmp short MusicPoi.0051897D
    00518992    5F              pop edi
    00518993    5E              pop esi
    00518994    5B              pop ebx
    00518995    59              pop ecx
    00518996    59              pop ecx
    00518997    5D              pop ebp
    00518998    C3              retn
    --------------------------------------------------------------------------------------------------------------

    【算法总结】:

    注册算法很简单,虚拟方法保护这方法不错,我也会了!

    Delphi 7.0 注册机源代码如下:
    Procedure TForm1.btn1Click(Sender: TObject);
    Var
      i: Integer;
      SN, MachineCode: String;
    Begin
      MachineCode := edt1.Text;
      SetLength(SN, Length(MachineCode));
      For i := 1 To Length(MachineCode) Do
      Begin
        If (Ord(MachineCode) < $41) Or (Ord(MachineCode) > $5A) Then
          SN := Char(Ord(MachineCode) + $1E)
        Else If (Ord(MachineCode) >= $49) Then
          SN := Char(Ord(MachineCode) - 5)
        Else
          SN := Char(Ord(MachineCode) + 7);
      End;
      edt2.Text := '8' + ReverseString(SN);
    End;


    我的机器码='14      60-206'    (不包括引号)
        注册码=8TNPKNT>>>>>>RO
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2005-4-6 11:22:55 | 显示全部楼层
    好文章!!!
    楼主能不能再说说这种虚拟动态方法如果没有正确的注册码,就得不到正确的地址,
    那要爆破该怎么作?
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-4-4 09:40
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2005-4-6 12:59:32 | 显示全部楼层
    那就需要继续努力学习了^_^^_^
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2005-4-6 13:56:49 | 显示全部楼层
    ^_^,这么说爆破没活路了。
    呜呜呜,偶碰到的东东怎么都是用这个虚拟动态方法,难道都要算出注册码才能获的正确的资源,苦啊。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-4-4 09:40
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2005-4-7 13:43:42 | 显示全部楼层
    对啊,学习算法才是正道,以前我都是太依奈爆破了~~~~~~~
    至少你现在对明码比较的应该能搞定啊~~~
    关于算法建议你从飘云兄的算法第一课学起,过几天我也发几篇我以前学习过的简单算法~~~
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2005-4-9 00:22:39 | 显示全部楼层
    啊,高手
    在看学看过
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2005-4-9 12:49:37 | 显示全部楼层
    ^_^,这么说爆破没活路了
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2017-4-4 09:40
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2005-4-9 19:29:29 | 显示全部楼层
    Originally posted by hyd009 at 2005-4-9 12:22 AM:
    啊,高手
    在看学看过



    我只是觉得这个软件比较有代表性所以发来大家学习,我没有说是原创啊;)~~~~~
    PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    2024-3-21 21:06
  • 签到天数: 1489 天

    [LV.10]以坛为家III

    发表于 2005-4-11 21:27:02 | 显示全部楼层
    Crack的目的就是学习别人的代码。当然附带着做出精美的算法注册机也是非常不错的。:)
    要想做出算法注册机,弄懂软件的注册算法是必然。
    我正在向这个目的努力前进。
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表