壹只老虎 发表于 2006-8-25 10:52:55

一个crackme的分析+注册机编写全过程!

【文章标题】: 软件破解学习笔记(算法分析8)
【文章作者】: 壹只老虎
【软件名称】: _UnPackedCrack.exe
【软件大小】: 24kb
【下载地址】: http://bbs.pediy.com/attachment.php?s=&attachmentid=2576
【加壳方式】: 无壳
【保护方式】: 序列号+注册码
【编写语言】: LCC Win32 1.x -> Jacob Navia
【使用工具】: od+peid+ windows计算器
【操作平台】: xp
【软件介绍】: 看雪的找的一个crackme,算法有点复杂!
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
看雪的找的一个crackme,算法有点复杂!不过还是挺锻炼的!嗬嗬!!!!!!!!!!!!!
声明一下!这个东西在看雪已经有人写了文章了!我自己分析之后也去看了下这片文章!写的不错!
我仔细分析了下算法!顺便写了注册机!(delphi原代码!)!写的不好!就当灌水!
感谢原作者jdxyw 提供 creakme!


1:PEID查壳,LCC Win32 1.x -> Jacob Navia,无壳,这个不是壳哈!
         
2:运行程序,填写注册资料:序列号:123456,注册码:11111111,注册,没反应,晕!
      
3:OD载入,不想了看看api断点行不行!
    ok!下GetDlgItemTextA断点!可以了!(其实有正确的字符串的!个人比较习惯api断点来段!嘿嘿!)
   
4:具体的分析过程:写的比较详细的!

第一部分:

00401533   |.50          push eax                               ; |Buffer
00401534   |.6A 65       push 65                              ; |ControlID = 65 (101.)
00401536   |.FF75 08   push dword ptr ss:            ; |hWnd
下GetDlgItemTextA断点,在这里会断下来
00401539   |.E8 FA010000 call <jmp.&USER32.GetDlgItemTextA>   ; \GetDlgItemTextA
0040153E   |.89C3      mov ebx,eax                            ;eax=ebx=注册名长度
00401540   |.09DB      or ebx,ebx
00401542   |.75 04       jnz short _UnPacke.00401548            ;ebx不等于0就跳
00401544   |.31C0      xor eax,eax
00401546   |.EB 50       jmp short _UnPacke.00401598            ;跳失败
00401548   |>BF BC020000 mov edi,2BC                            ;edi=700
0040154D   |.BE 30000000 mov esi,30                           ;esi=48
00401552   |.B8 48000000 mov eax,48                           ;eax=72
00401557   |.99          cdq
00401558   |.F7FB      idiv ebx                               ;eax=eax div ebx
0040155A   |.29C6      sub esi,eax                            ;esi=esi-eax
0040155C   |.8D34B6      lea esi,dword ptr ds:       ;esi=5*esi
0040155F   |.29F7      sub edi,esi                            ;edi=edi-esi
00401561   |.6BFF 6B   imul edi,edi,6B                        ;edi=edi*107
00401564   |.81EF 6CCF00>sub edi,0CF6C                        ;edi=edi-53100
0040156A   |.81FF 002300>cmp edi,2300                           ;edi和8960比较
00401570   |.7F 08       jg short _UnPacke.0040157A             ;>就跳,失败了
00401572   |.81FF 900100>cmp edi,190                            ;和400比较
00401578   |.7D 04       jge short _UnPacke.0040157E            ;大于等于就跳
0040157A   |>31C0      xor eax,eax                            ;eax=0
0040157C   |.EB 1A       jmp short _UnPacke.00401598            ;跳出去,失败
0040157E   |>8D85 00FFFF>lea eax,dword ptr ss:         ;eax=注册名字符串
00401584   |.50          push eax                               ;注册名压栈
00401585   |.53          push ebx                               ;注册名长度压栈
00401586   |.FF75 08   push dword ptr ss:

上面这一段分析一下:要想不跳失败:那么
条件如下:
         1:注册名长度不等于0
         2:((700-(48-(72 div 注册名长度))*5)*107-53100)>8960或者<400就失败,
             等价于--->嘿嘿,借不等式,大家都会把!!
             注册名长度<3或者>9就失败
   
00401589   |.E8 77FDFFFF call _UnPacke.00401305               ;进去看看
0040158E   |.83C4 0C   add esp,0C
00401591   |.09C0      or eax,eax
00401593   |.74 03       je short _UnPacke.00401598             ;eax=0就跳,失败
00401595   |.31C0      xor eax,eax
00401597   |.40          inc eax                              ;eax=1成功
00401598   |>5F          pop edi
00401599   |.5E          pop esi
0040159A   |.5B          pop ebx
0040159B   |.C9          leave
0040159C   \.C3          retn返回到0040162A(主函数体)



第二部分:

00401589   |.E8 77FDFFFF call _UnPacke.00401305               ;进去看看


00401305   /$55          push ebp
00401306   |.89E5      mov ebp,esp
00401308   |.81EC 2C0400>sub esp,42C
0040130E   |.53          push ebx
0040130F   |.56          push esi
00401310   |.57          push edi
00401311   |.8DBD FCFEFF>lea edi,dword ptr ss:
00401317   |.8D35 382040>lea esi,dword ptr ds:         
0040131D   |.B9 40000000 mov ecx,40                           
00401322   |.F3:A5       rep movs dword ptr es:,dword ptr >
00401324   |.8DBD E1FBFF>lea edi,dword ptr ss:
0040132A   |.8D35 382140>lea esi,dword ptr ds:
00401330   |.B9 40000000 mov ecx,40
00401335   |.F3:A5       rep movs dword ptr es:,dword ptr >
00401337   |.8DBD E1FDFF>lea edi,dword ptr ss:
0040133D   |.8D35 382240>lea esi,dword ptr ds:
00401343   |.B9 40000000 mov ecx,40
00401348   |.F3:A5       rep movs dword ptr es:,dword ptr >
0040134A   |.8DBD E1FCFF>lea edi,dword ptr ss:
00401350   |.8D35 382340>lea esi,dword ptr ds:
00401356   |.B9 40000000 mov ecx,40
0040135B   |.F3:A5       rep movs dword ptr es:,dword ptr >
0040135D   |.8DBD DCFBFF>lea edi,dword ptr ss:
00401363   |.8D35 382440>lea esi,dword ptr ds:
00401369   |.B9 05000000 mov ecx,5
0040136E   |.F3:A4       rep movs byte ptr es:,byte ptr ds>
00401370   |.8DBD D6FBFF>lea edi,dword ptr ss:
00401376   |.8D35 3D2440>lea esi,dword ptr ds:
0040137C   |.B9 03000000 mov ecx,3
00401381   |.F3:66:A5    rep movs word ptr es:,word ptr ds>
00401384   |.8DBD E1FEFF>lea edi,dword ptr ss:
0040138A   |.8D35 432440>lea esi,dword ptr ds:
00401390   |.B9 1B000000 mov ecx,1B
00401395   |.F3:A4       rep movs byte ptr es:,byte ptr ds>
00401397   |.C745 FC 000>mov dword ptr ss:,0
0040139E   |.68 00010000 push 100                               ; /Count = 100 (256.)
004013A3   |.8D85 E1FCFF>lea eax,dword ptr ss:         ; |
004013A9   |.50          push eax                               ; |Buffer
004013AA   |.6A 66       push 66                              ; |ControlID = 66 (102.)
004013AC   |.FF75 08   push dword ptr ss:            ; |hWnd
004013AF   |.E8 84030000 call <jmp.&USER32.GetDlgItemTextA>   ; \GetDlgItemTextA
004013B4   |.09C0      or eax,eax                           ;eax=注册码长度
004013B6   |.0F84 480100>je _UnPacke.00401504
004013BC   |.B8 CF110000 mov eax,11CF                           ;eax=4559
004013C1   |.0FB68D E1FC>movzx ecx,byte ptr ss:      ;ecx=注册码第一位ascoii码
004013C8   |.99          cdq
004013C9   |.F7F9      idiv ecx                               ;ecx=eax div ecx
004013CB   |.83FA 17   cmp edx,17                           ;(余数)edx=23?

这里分析一下:要想跳走,余数edx必须=23
所以我们就需要构造数据来进行调试分析:这个数据随便大家挑
挑选方法如下:
             4559 mod 注册码第一位ascoii码=23;都可以的
等价于
             4559-注册码第一位ascoii码*N=23;
             注册码第一位ascoii码*N=4536=2*2*2*3*3*3*3*7;这里随便构造就可以了
我开始的时候选的'6'=54,'T'也可以

004013CE   |.74 07       je short _UnPacke.004013D7             ;等于就跳(这里必须跳走)
004013D0   |.31C0      xor eax,eax                            ;eax=0
004013D2   |.E9 2D010000 jmp _UnPacke.00401504                  ;跳出去了,失败了
004013D7   |>31DB      xor ebx,ebx                            ;ebx=0

这里是一个循环

004013D9   |.EB 0B       jmp short _UnPacke.004013E6            ;小跳,开始循环了
004013DB   |>8B45 10   /mov eax,dword ptr ss:
004013DE   |.0FBE0418    |movsx eax,byte ptr ds:       ;eax=按位取注册名ascii码
004013E2   |.0145 FC   |add dword ptr ss:,eax          ;eax累加到0012f9ac
004013E5   |.43          |inc ebx
004013E6   |>3B5D 0C      cmp ebx,dword ptr ss:          ;循环是否结束
004013E9   |.^ 7C F0       \jl short _UnPacke.004013DB            ;这个循环把注册名数据各位的ascii码和防到0012f9ac

循环的分析:这个循环把注册名数据各位的ascii码和防到0012f9ac

下面又是一个循环

004013EB   |.31DB      xor ebx,ebx                            ;ebx=0
004013ED   |.E9 83000000 jmp _UnPacke.00401475                  ;循环一个
004013F2   |>8B55 10   /mov edx,dword ptr ss:         ;ebx为计数器
004013F5   |.0FBE3C1A    |movsx edi,byte ptr ds:       ;edi=按位取注册名ascii码
004013F9   |.8B75 FC   |mov esi,dword ptr ss:          ;esi=0012f9ac的数据(上次的循环结果)
004013FC   |.89D9      |mov ecx,ebx                           ;ecx=ebx
004013FE   |.C1E1 02   |shl ecx,2                           ;ecx=ecx*4
00401401   |.89DA      |mov edx,ebx                           ;edx=ebx
00401403   |.42          |inc edx                               ;edx+1
00401404   |.29D1      |sub ecx,edx                           ;ecx=ecx-edx
00401406   |.0FB68C0D E1>|movzx ecx,byte ptr ss:   ;ecx=这里根到内存里面去看看有张表(.ABCDEFGHI...XYZ)
0040140E   |.89FA      |mov edx,edi                           ;edx=edi
00401410   |.31CA      |xor edx,ecx                           ;edx=edx xor ecx
00401412   |.89F1      |mov ecx,esi                           ;ecx=esi
00401414   |.0FAFCB      |imul ecx,ebx                        ;ecx=ecx*ebx
00401417   |.29F1      |sub ecx,esi                           ;ecx=ecx-esi
00401419   |.89CE      |mov esi,ecx                           ;esi=ecx
0040141B   |.83F6 FF   |xor esi,FFFFFFFF                      ;esi=esi xor ffffffff
0040141E   |.8DB432 4D01>|lea esi,dword ptr ds:    ;esi=esi+edx+333
00401425   |.8B4D 0C   |mov ecx,dword ptr ss:          ;ecx=注册名长度
00401428   |.89DA      |mov edx,ebx                           ;edx=ebx
0040142A   |.83C2 03   |add edx,3                           ;edx=edx+3
0040142D   |.0FAFCA      |imul ecx,edx                        ;ecx=ecx*edx
00401430   |.0FAFCF      |imul ecx,edi                        ;ecx=ecx*edi
00401433   |.89F0      |mov eax,esi                           ;eax=esi
00401435   |.01C8      |add eax,ecx                           ;eax=eax+ecx
00401437   |.B9 0A000000 |mov ecx,0A                            ;ecx=10
0040143C   |.31D2      |xor edx,edx                           ;edx=0
0040143E   |.F7F1      |div ecx                               ;eax=eax div ecx
00401440   |.83C2 30   |add edx,30                            ;edx=余数+48
00401443   |.88941D FCFE>|mov byte ptr ss:,dl      ;dl存入0012f8ac开始的地址范围(后面会替换的)
0040144A   |.0FB6BC1D FC>|movzx edi,byte ptr ss:   ;edi=dl
00401452   |.81F7 ACAD00>|xor edi,0ADAC                         ;edi=edi xor 44460
00401458   |.89DE      |mov esi,ebx                           ;esi=ebx
0040145A   |.83C6 02   |add esi,2                           ;esi=esi+2
0040145D   |.89F8      |mov eax,edi                           ;eax=edi
0040145F   |.0FAFC6      |imul eax,esi                        ;eax=eax*esi
00401462   |.B9 0A000000 |mov ecx,0A                            ;ecx=10
00401467   |.99          |cdq
00401468   |.F7F9      |idiv ecx                              ;eax=eax div ecx
0040146A   |.83C2 30   |add edx,30                            ;edx=余数+48
0040146D   |.88941D FCFE>|mov byte ptr ss:,dl      ;dl-->0012f8ac开始的地质(注意这里是替换本次循环得到的这个位置的数据)
00401474   |.43          |inc ebx                               ;ebx+1
00401475   |>3B5D 0C      cmp ebx,dword ptr ss:          ;循环是否结束(次数为注册名长度)
00401478   |.^ 0F8C 74FFFF>\jl _UnPacke.004013F2

这里分析下这个循环的作用
循环注册名长度的次数,每次计算出一个值,放到0012f8ac开始的地址里面

具体算法如下:
/********************************************************************/
var
       str,code:string;
       str:="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
       code:='';
       for ebx:=0 to length(name)-1 do
         begin
               edi:=ord(name);
               esi=0012f9ac的数据(上次的循环结果);
               ecx=ebx*4-(ebx+1);
               ecx=ord(str);
               edx=edi xor ecx;
               esi=esi*ebx-esi;
               esi=esi xor ffffffff;
               esi=esi+edx+333;
               ecx=注册名长度*(ebx+3)*edi;
               eax=esi+ecx;
               ecx=eax;
               eax=eax div 10;
               edi=(ecx mod 10)+48;
               edi=edi xor 44460;
               esi=ebx+2;
               eax=edi*esi;
               ecx=eax;
               eax=eax div 10;
               edx=(ecx mod 10)+48;;
               code:=chr(edx);
         end;
/********************************************************************/

0040147E   |.8D85 FCFEFF>lea eax,dword ptr ss:         ;这是上个循环得到的数据的字符串
00401484   |.50          push eax                               ;存入eax并压栈
00401485   |.6A 54       push 54                              ;压入84

               84就表示T的意思

00401487   |.8D85 DCFBFF>lea eax,dword ptr ss:
0040148D   |.50          push eax                               ; |Format
0040148E   |.8D85 E1FBFF>lea eax,dword ptr ss:         ; |
00401494   |.50          push eax                               ; |s
00401495   |.E8 CE020000 call <jmp.&USER32.wsprintfA>         ; \在上面的字符串前面加个T
0040149A   |.8B7D 0C   mov edi,dword ptr ss:         ;edi=注册名长度
0040149D   |.89F8      mov eax,edi                            ;eax=注册名长度
0040149F   |.0FAF45 FC   imul eax,dword ptr ss:          ;eax=第一个循环的结果*eax
004014A3   |.B9 64000000 mov ecx,64                           ;ecx=100
004014A8   |.99          cdq
004014A9   |.F7F9      idiv ecx                               ;eax=eax div 100
004014AB   |.89D7      mov edi,edx                            ;edi=余数
004014AD   |.83C7 30   add edi,30                           ;edi=edi+48
004014B0   |.57          push edi                               ;edi压栈(设为num)

分析一下这个num的来由:(注册名数据各位的ascii码和*注册名长度 mod 100)+48

004014B1   |.8DBD E1FBFF>lea edi,dword ptr ss:         ;edi存入上面得到的字符串
004014B7   |.57          push edi                               ;edi压栈
004014B8   |.8DBD D6FBFF>lea edi,dword ptr ss:         ;%s-%d
004014BE   |.57          push edi                               ; |Format
004014BF   |.8DBD E1FDFF>lea edi,dword ptr ss:         ; |
004014C5   |.57          push edi                               ; |s
004014C6   |.E8 9D020000 call <jmp.&USER32.wsprintfA>         ; \上面的字符串+'-'+num(10)
004014CB   |.83C4 20   add esp,20
004014CE   |.8D8D E1FDFF>lea ecx,dword ptr ss:         ;ecx存入上面得到的字符串
004014D4   |.83C8 FF   or eax,FFFFFFFF
004014D7   |>40          /inc eax
004014D8   |.803C01 00   |cmp byte ptr ds:,0
004014DC   |.^\75 F9       \jnz short _UnPacke.004014D7         ;eax=上面得到的字符串长度
004014DE   |.50          push eax                               ; /eax压栈
004014DF   |.8D85 E1FCFF>lea eax,dword ptr ss:         ; |eax=假码字符串
004014E5   |.50          push eax                               ; |eax压栈
004014E6   |.8D85 E1FDFF>lea eax,dword ptr ss:         ; |eax=上面得到的字符串长度
004014EC   |.50          push eax                               ; |eax压栈
004014ED   |.E8 D0FDFFFF call _UnPacke.004012C2               ; \_UnPacke.004012C2 进去看看
004014F2   |.83C4 0C   add esp,0C
004014F5       83F8 00   cmp eax,0                              ;失败没有,=0表示失败
004014F8   |.75 07       jnz short _UnPacke.00401501
004014FA   |.B8 00000000 mov eax,0                              ;eax=0
004014FF   |.EB 03       jmp short _UnPacke.00401504            ;跳出
00401501   |>31C0      xor eax,eax
00401503   |.40          inc eax                              ;eax=1表示成功
00401504   |>5F          pop edi
00401505   |.5E          pop esi
00401506   |.5B          pop ebx
00401507   |.C9          leave
00401508   \.C3          retn

第三部分:

004014ED   |.E8 D0FDFFFF call _UnPacke.004012C2               ; \_UnPacke.004012C2 进去看看

004012C2   /$55          push ebp
004012C3   |.89E5      mov ebp,esp
004012C5   |.53          push ebx
004012C6   |.56          push esi
004012C7   |.57          push edi
004012C8   |.8B5D 10   mov ebx,dword ptr ss:          ;ebx=上面得到的字符串长度
004012CB   |.31F6      xor esi,esi                            ;esi=0
004012CD   |.46          inc esi                              ;esi+1
004012CE   |.EB 29       jmp short _UnPacke.004012F9            ;又是一个循环

下面是个循环
004012D0   |>8B55 08   /mov edx,dword ptr ss:          ;edx=上面得到的字符串
004012D3   |.0FBE3C32    |movsx edi,byte ptr ds:       ;edi=从第2位开始取上面得到的字符串数据的ascii码
004012D7   |.89F8      |mov eax,edi                           ;eax=edi
004012D9   |.83F0 20   |xor eax,20                            ;eax=eax xor 32
004012DC   |.B9 0A000000 |mov ecx,0A                            ;ecx=10
004012E1   |.99          |cdq
004012E2   |.F7F9      |idiv ecx                              ;eax=eax div 10
004012E4   |.89D7      |mov edi,edx
004012E6   |.83C7 30   |add edi,30                            ;edi=余数+48
004012E9   |.8B55 0C   |mov edx,dword ptr ss:          ;edx=假码
004012EC   |.0FBE1432    |movsx edx,byte ptr ds:       ;从第2位开始取
004012F0   |.39D7      |cmp edi,edx                           ;相等
004012F2   |.74 04       |je short _UnPacke.004012F8            ;继续
004012F4   |.31C0      |xor eax,eax                           ;不等则eax=0,失败
004012F6   |.EB 08       |jmp short _UnPacke.00401300         ;跳出
004012F8   |>46          |inc esi
004012F9   |>39DE         cmp esi,ebx                           ;esi是计数器
004012FB   |.^ 7C D3       \jl short _UnPacke.004012D0

分析下这个循环的作用:

这里就是注册码的真假的比较了,但是注意!绝对不是直接比较的!
这里还进行了一些运算!

看看算法:------------>
/*********************************************/
str=上面得到的字符串;

realcode:string//真码
realcode:='6';//T也可以!就是前面写了的对于第一位的要求
for esi:=2 to length(str) do
      begin
         eax:=ord(str) xor 32;
         edi:=(eax mod 10)+48;
         realcode:=chr(edi);
      end;
/*********************************************/
004012FD   |.31C0      xor eax,eax
004012FF   |.40          inc eax                              ;eax=1
00401300   |>5F          pop edi
00401301   |.5E          pop esi
00401302   |.5B          pop ebx
00401303   |.5D          pop ebp
00401304   \.C3          retn


第四部分:(主程序体部分)
返回到这里
0040162A   |.59          pop ecx                              ;00130698
0040162B   |.09C0      or eax,eax                           ;关键比较哦
0040162D   |.74 53       je short _UnPacke.00401682             ;关键跳转
0040162F   |.6A 40       push 40                              ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401631   |.8D45 C7   lea eax,dword ptr ss:          ; |
00401634   |.50          push eax                               ; |Title
00401635   |.8D45 D3   lea eax,dword ptr ss:          ; |
00401638   |.50          push eax                               ; |Text
00401639   |.FF75 08   push dword ptr ss:            ; |hOwner
0040163C   |.E8 1B010000 call <jmp.&USER32.MessageBoxA>         ; \MessageBoxA 正确了
00401641   |.EB 3D       jmp short _UnPacke.00401680
00401643   |>8D05 0E2640>lea eax,dword ptr ds:
00401649   |.8945 F8   mov dword ptr ss:,eax
0040164C   |.8D05 932540>lea eax,dword ptr ds:
00401652   |.8945 F4   mov dword ptr ss:,eax
00401655   |.6A 40       push 40                              ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401657   |.FF75 F8   push dword ptr ss:            ; |Title
0040165A   |.50          push eax                               ; |Text => "You have to make an own working keygen!
Send the solutions to: [email protected]
Patching is not allowed!

Enjoy !"
0040165B   |.FF75 08   push dword ptr ss:            ; |hOwner
0040165E   |.E8 F9000000 call <jmp.&USER32.MessageBoxA>         ; \MessageBoxA
00401663   |.EB 1B       jmp short _UnPacke.00401680
00401665   |>6A 01       push 1                                 ; /Result = 1
00401667   |.FF75 08   push dword ptr ss:            ; |hWnd
0040166A   |.E8 B1000000 call <jmp.&USER32.EndDialog>         ; \EndDialog
0040166F   |.EB 0F       jmp short _UnPacke.00401680
00401671   |>6A 00       push 0                                 ; /Result = 0
00401673   |.FF75 08   push dword ptr ss:            ; |hWnd
00401676   |.E8 A5000000 call <jmp.&USER32.EndDialog>         ; \EndDialog
0040167B   |.31C0      xor eax,eax
0040167D   |.40          inc eax
0040167E   |.EB 02       jmp short _UnPacke.00401682
00401680   |>31C0      xor eax,eax
00401682   |>5F          pop edi
00401683   |.5E          pop esi
00401684   |.5B          pop ebx
00401685   |.C9          leave
00401686   \.C2 1000   retn 10



5:算法分析:上面都写得很清楚了!这里就不说了

6:注册机编写如下:

procedure TForm1.Button1Click(Sender: TObject);
var
   name_asc:integer;
   i,edi,esi,ecx,edx,ebx,eax:integer;
   name,code,table,realcode:string;
begin
       name:=edit1.Text;
       if (length(name)<3)or(length(name)>9) then
         begin
                showmessage('注册名长度必须大于2小于10');
                exit;
         end;
       code:='6';
       name_asc:=0;
       for i:=1 to length(name) do
         name_asc:=name_asc+ord(name);

       table:='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
       for ebx:=0 to length(name)-1 do
         begin
               edi:=ord(name);
               esi:=name_asc;
               ecx:=ebx*4-(ebx+1);
               ecx:=ord(table);
               edx:=edi xor ecx;
               esi:=esi*ebx-esi;
               esi:=esi xor -1;
               esi:=esi+edx+333;
               ecx:=length(name)*(ebx+3)*edi;
               eax:=esi+ecx;
               edi:=(eax mod 10)+48;
               edi:=edi xor 44460;
               eax:=edi*(ebx+2);
               edx:=(eax mod 10)+48;;
               code:=code+chr(edx);
         end;
      code:=code+'-'+inttostr(((length(name)*name_asc)mod 100)+48);
      realcode:='6';
      for esi:=2 to length(code) do
      begin
         eax:=ord(code) xor 32;
         edi:=(eax mod 10)+48;
         realcode:=realcode+chr(edi);
      end;
      edit2.Text:=realcode+'   BY:壹只老虎2006-8-25';
end;

嘿嘿!说明一下!这个注册码只要前面参加运算的几位比较正确了!后面你随便写什么都可以!嘿嘿
比如说!

123456-->68921253768   BY:壹只老虎2006-8-25
123456-->68921253768 也可以的!嘿嘿!

好了就这样了!大家破解愉快!

--------------------------------------------------------------------------------
【经验总结】
坚持就是胜利!睡觉去了!!!!!!!!!!!

--------------------------------------------------------------------------------
【版权声明】: BY:壹只老虎

                                                       2006年08月25日 10:39:17

[ 本帖最后由 风飘雪 于 2007-1-13 21:13 编辑 ]

傲月游居 发表于 2006-8-25 20:14:38

正点的算法.支持一下拉登兄弟!

agang 发表于 2006-8-26 14:35:18

太强了!好文,学习了

网游难民 发表于 2006-8-26 16:30:51

兄弟好强,学习滴说~

黑夜彩虹 发表于 2006-8-26 18:00:59

嘿嘿,又一delphi的兄弟~~,支持

weiruan198 发表于 2006-8-26 19:56:31

收下啦~~呵呵

zyhxhw 发表于 2006-8-26 20:31:23

唉,跟了一阵,把头都跟昏了,不过,一定要学会!

壹只老虎 发表于 2006-8-27 10:52:44

嘿嘿!谢谢兄弟们支持哈!我会加油的!! /:D

zyhxhw 发表于 2006-8-27 16:00:08

终于跟完了,最后得到这样一个注册码:用户名:zyh;注册码:T480-89,可惜的是,一点反应也没有,不知道到底是哪个地方出了问题!

壹只老虎 发表于 2006-8-28 09:02:29

6046345   BY:壹只老虎2006-8-25
这是zyh对应的正确的注册码
你仔细看看,别看花眼了!
页: [1] 2 3
查看完整版本: 一个crackme的分析+注册机编写全过程!