首页
社区
课程
招聘
[原创]FaNtOm's Crackme #8 新手算法分析+C注册机
发表于: 2006-8-8 10:49 5455

[原创]FaNtOm's Crackme #8 新手算法分析+C注册机

2006-8-8 10:49
5455

【文章标题】: FaNtOm's Crackme #8 新手算法分析+C注册机
【文章作者】: Vcsoft
【作者邮箱】: [email]vcsoftpro@163.com[/email]
【软件名称】: FaNtOm's Crackme #8
【保护方式】: Serial Numer
【使用工具】: peid/od
【操作平台】: winxp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  首先用 PEiD 检查,发现用UPX加过壳,类型 UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo,这个壳很老了,
  用 PEiD自带的插件 "Unpacker for UPX" 就可脱之。

  OD载入脱壳后的程序,用查找字符串的方法找不出错误信息,只好下断点 bp GetDlgItemTextA
  运行程序,输入试练码,点击Verify后程序中断在USER32领空,F8单步直到返回程序领空

00401295    6A 64           push    64
00401297    68 74314000     push    00403174                         ; ASCII "87654321"
0040129C    68 EA030000     push    3EA
004012A1    FF75 08         push    dword ptr [ebp+8]
004012A4    E8 B5000000     call    <jmp.&USER32.GetDlgItemTextA>

------------------------------┬---------------------------------------返回到这里

004012A9    6A 64           push    64
004012AB    68 10314000     push    00403110                         ; ASCII "vcsoft"
004012B0    68 E9030000     push    3E9
004012B5    FF75 08         push    dword ptr [ebp+8]
004012B8    E8 A1000000     call    <jmp.&USER32.GetDlgItemTextA>
004012BD    8D05 10314000   lea     eax, [403110]                    ; 传送输入的name地址
004012C3    50              push    eax
004012C4    8D05 74314000   lea     eax, [403174]                    ; 传送输入的code地址
004012CA    50              push    eax
004012CB    FF15 0C314000   call    [40310C]                         ; CM8.dll中的产生真code的函数

---------------┴--------------------关键CALL,跟入

10001287 >  55              push    ebp
10001288    8BEC            mov     ebp, esp
1000128A    FF75 0C         push    dword ptr [ebp+C]
1000128D    E8 85000000     call    10001317                         ; 通过检查name中的结束符来计算字符串长度
                                                                       eax = 字符串长度
10001292    83F8 00         cmp     eax, 0                           ; 是否输入了name
10001295    74 71           je      short 10001308
10001297    83F8 64         cmp     eax, 64                          ; name 长度 >= 100 就失败
1000129A    7D 6C           jge     short 10001308
1000129C    50              push    eax                              ; name 长度入栈
1000129D    FF75 08         push    dword ptr [ebp+8]
100012A0    E8 72000000     call    10001317                         ; 这次计算code长度,同上一个函数
100012A5    83F8 00         cmp     eax, 0                           ; 是否输入了 code
100012A8    74 5E           je      short 10001308
100012AA    83F8 64         cmp     eax, 64                          ; 长度也不能 >= 100
100012AD    7D 59           jge     short 10001308
100012AF    8B75 0C         mov     esi, [ebp+C]                     ; esi = name 地址
100012B2    8D3D 24300010   lea     edi, [10003024]
100012B8    59              pop     ecx                              ; name 长度出栈 以下len(name)表示
100012B9    41              inc     ecx                              ; j=len(name)+1
100012BA    BB 42000000     mov     ebx, 42                          ; ebx = 0x42
100012BF    03D9            add     ebx, ecx                         ; t1 = 0x42 + len(name) + 1
100012C1    0FB606          movzx   eax, byte ptr [esi]              ; eax = name(i)
100012C4    46              inc     esi                              ; i++
100012C5    33C3            xor     eax, ebx                         ; name(i)^t1
100012C7    C1C0 05         rol     eax, 5                           ; 循环左移5位
100012CA    C1E8 02         shr     eax, 2                           ; 再逻辑右移2位
100012CD    B3 10           mov     bl, 10                           ; bl = 0x10
100012CF    F6F3            div     bl                               ; t2 / 0x10
100012D1    80C4 30         add     ah, 30                           ; 无符号除法的余数t2+0x30
100012D4    80FC 40         cmp     ah, 40                           ; 结果是否<= 0x40
100012D7    7E 03           jle     short 100012DC
100012D9    80C4 07         add     ah, 7                            ; 如果大于 则再加上7
100012DC    8827            mov     [edi], ah                        ; <= 保存
100012DE    47              inc     edi                              ;
100012DF    3C 10           cmp     al, 10                           ; 无符号除法的商 t3
100012E1    7D 08           jge     short 100012EB                   ; 如果t3  < 0x10
100012E3    66:C1E0 08      shl     ax, 8                            ; ax 逻辑左移8位

----------------------------------------------------------------------这里左移8位是为了使 ah = al,即t2=t3
100012E7    B0 11           mov     al, 11                           ; t3= al = 0x11
100012E9  ^\EB E6           jmp     short 100012D1                   ; 内层循环
100012EB    49              dec     ecx                              ; j--
100012EC    83F9 00         cmp     ecx, 0
100012EF    74 02           je      short 100012F3                   ; j=0 外层循环结束
100012F1  ^ EB C7           jmp     short 100012BA                   ; 外层循环
100012F3    C607 00         mov     byte ptr [edi], 0
100012F6    68 24300010     push    10003024                         ; 计算后真码
100012FB    FF75 08         push    dword ptr [ebp+8]                ; 输入的假码
100012FE    E8 29000000     call    1000132C                         ; jmp 到 kernel32.lstrcmpA
10001303    83F8 00         cmp     eax, 0                           ; 两字符串相同 lstrcmp返回0
10001306    74 09           je      short 10001311                     
10001308    B8 01000000     mov     eax, 1                             字串不同返回1
1000130D    C9              leave
1000130E    C2 0800         retn    8
10001311    33C0            xor     eax, eax                         相同则返回0
10001313    C9              leave
10001314    C2 0800         retn    8

-----------------------------------------------------------------------------------------------------------------
004012D1    85C0            test    eax, eax                             测试返回值是否为0
004012D3    74 08           je      short 004012DD
004012D5    8D05 A0304000   lea     eax, [4030A0]                     MessageBox失败字串地址
004012DB    EB 06           jmp     short 004012E3
004012DD    8D05 63304000   lea     eax, [403063]                     MessageBox成功字串地址
004012E3    6A 40           push    40
004012E5    68 54304000     push    00403054                         ; ASCII "Serial Results"
004012EA    50              push    eax
004012EB    6A 00           push    0
004012ED    E8 8A000000     call    <jmp.&USER32.MessageBoxA>

  小结:

  1、输入的注册名和注册码必须小于100 (谁的名字这么长?)
  2、name长度+1做为外层循环的计数器j  再加0x42的值记为t1
     name的ASCII码与t1异或,先循环左移5位,再逻辑右移2位,然后除以0x10
     余数记为t2,商记为t3
  3、t2加0x30,如果>0x40 则再加上7,否则直接保存
  4、如果t3<0x10,则t2=t3,t3=0x11, 从第3步循环,直到t3>=0x10跳出内层循环,
     j--,判断下一字符

  比如: name  vcsoft
  j=6+1=7
  t1 = j+0x42 = 0x49
  "v"ASCII为0x76   
  0x76^0x49=0x3F      0x3F<<5=0x07E0   0x07E0>>2=0x01F8    0x01F8/0x10=0x081F 08为余数记为t2 1F为商记为t3
  t2=0x08+0x30=0x38   0x38<0x40  保存结果0x38
  t3=0x1F   0x1F>0x10 跳出内层循环  j-1=6  进入下一循环计算第2位
  所以注册码第一位为0x38("8")
  
  给出3组序号:
  name: vcsoft              code:8808808
  name: !@#$%^&*()          code:0060000;80888
  name: www.pediy.com       code:80880000888088           做个广告!

--------------------------------------------------------------------------------
注册机C代码:在WinXP-SP2+Win-TC下编译通过

main()
{
    short int t1,t2,t3,namelen,i=0,j=0;
    char name[100],serial[100];
    printf("Please input your name:  ");
    scanf("%s",&name);
    namelen=strlen(name);
    for(;namelen>=0;namelen--)
    {
        t1=(name[i]^(namelen+67))<<3;
        i++;
        t2=t1%16; t3=t1/16;
        loop:
        t2+=48;
        if(t2>64) t2+=7;
        serial[j]=t2;
        j++;
        while(1)
        {
            if(t3<16)
            {
                t2=t3;
                t3=17;
                goto loop;
            }else break;
        }
    }
    printf("\n\n\n\n\nThis is your password:   %s",serial);
    getch();
    return 0;
}

本人是看雪论坛的菜鸟一只,文中如有不对的地方麻烦高手指正,向高手学习。

内附:CRACKME8.EXE    FaNtOm's Crackme #8
      CM8.DLL         CRACKME8的链接库
      KeyGen.exe      注册机

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (1)
雪    币: 338
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
分析的好!!莱鸟支持的说@!
2006-8-8 11:51
0
游客
登录 | 注册 方可回帖
返回
//