首页
社区
课程
招聘
LC4注册算法分析
发表于: 2006-4-10 20:57 8650

LC4注册算法分析

2006-4-10 20:57
8650
        万里长征第二步:LC4注册算法分析

解密者:冲天剑@pediy.com
工具:peid 0.94, Ollyice 1.10

0. 导言

  近来本地机器系统密码丢失,为了将其破解出来,到网上下载了据说很著名
的LC4,但却要求注册,否则暴力破解功能不可用。LC4顾名思义是4代的
版本,目前据说5代都出来了,官网上肯定下不到了。可下载的页面位于:

  hxxp://www.hackchina.cn/Soft/hacktools/jmjm/200511/54.html

(老规矩,要访问这个网页的请自行改成正确格式URL。)

1. 反向工程

  (1) 用PEID查壳,显示为Microsoft Visual C++ 6.0。

  (2) 运行程序试注册,可知注册流程是程序自己显示机器号然后要求输入序
列号的类型。机器号显示:15859a29d,输入假码1234567试注册,显示字符串:

   You have entered an invalid code. Please try again.

然后Ollyice载入,查找此字串。(首次运行会遇到异常,应在调试设置选项中
忽略所有异常并将所遇到的异常添加进去,重新运行)

//////////////  以下是代码  ////////////////

00411BF3  |.  50            |push    eax                             ;  断点
00411BF4  |.  E8 B722FFFF   |call    00403EB0
00411BF9  |.  8B07          |mov     eax, [edi]                      ;  真码指针
00411BFB >|.  8D5424 28     |lea     edx, [esp+28]                   ;  假码指针
00411BFF  |.  52            |push    edx
00411C00  |.  50            |push    eax
00411C01  |.  E8 955C0100   |call    0042789B
00411C06  |.  83C4 10       |add     esp, 10
00411C09  |.  85C0          |test    eax, eax
00411C0B  |.  75 23         |jnz     short 00411C30                  ;  关键跳转
00411C0D  |.  8B07          |mov     eax, [edi]
00411C0F  |.  50            |push    eax                             ; /Arg3
00411C10  |.  68 50134700   |push    00471350                        ; |Arg2 = 00471350 ASCII "Unlock Code"
00411C15  |.  68 5C134700   |push    0047135C                        ; |Arg1 = 0047135C ASCII "Registration"
00411C1A  |.  8BCE          |mov     ecx, esi                        ; |
00411C1C  |.  899E 3C010000 |mov     [esi+13C], ebx                  ; |
00411C22  |.  E8 9AB20300   |call    0044CEC1                        ; \lc4.0044CEC1
00411C27  |.  53            |push    ebx
00411C28  |.  53            |push    ebx
00411C29  |.  68 34144700   |push    00471434                        ;  ASCII "You have successfully registered LC4."
00411C2E  |.  EB 07         |jmp     short 00411C37
00411C30  |>  53            |push    ebx                             ; /Arg3
00411C31  |.  53            |push    ebx                             ; |Arg2
00411C32  |.  68 00144700   |push    00471400                        ; |Arg1 = 00471400 ASCII "You have entered an invalid code. Please try again."
00411C37  |>  E8 D3720300   |call    00448F0F                        ; \lc4.00448F0F

//////////////  以上是代码  ////////////////

这个关键跳转太显眼了!那么接下去call 0042789B应该是判断两个字符串是否相
同,而call 00403EB0应该就是算注册码的过程了吧!于是在00411BF3处下断点,
单步步过00411BF4以后,果然出现了真正注册码!而接下来的两个push指令应该
是为call 0042789B准备参数的,它们所推入的果然是真码和假码的指针!不用再
多说了,赶快跟进00403EB0这个过程里去吧。

//////////////  以下是代码  ////////////////

00403EB0  /$  83EC 0C       sub     esp, 0C                          ;  预留局部变量空间(dword*3)
00403EB3  |.  8B4424 10     mov     eax, [esp+10]                    ;  指向机器码字串的指针
00403EB7  |.  6A 08         push    8
00403EB9  |.  40            inc     eax                              ;  掐掉机器码头字符
00403EBA  |.  50            push    eax
00403EBB  |.  8D4C24 08     lea     ecx, [esp+8]                     ;  局部变量1的指针
00403EBF  |.  51            push    ecx
00403EC0  |.  E8 AB1E0200   call    00425D70
00403EC5  |.  8D5424 1C     lea     edx, [esp+1C]
00403EC9  |.  52            push    edx
00403ECA  |.  8D4424 10     lea     eax, [esp+10]
00403ECE  |.  68 88FA4600   push    0046FA88                         ;  ASCII "%08x"
00403ED3  |.  50            push    eax
00403ED4  |.  C64424 20 00  mov     byte ptr [esp+20], 0
00403ED9  |.  E8 65240200   call    00426343
00403EDE  |.  8B4424 28     mov     eax, [esp+28]
00403EE2  |.  35 52AE376F   xor     eax, 6F37AE52                    ;  EAX=机器码后8位对应的16进位字符
00403EE7  |.  8BC8          mov     ecx, eax
00403EE9  |.  C1E1 1B       shl     ecx, 1B
00403EEC  |.  C1E8 05       shr     eax, 5
00403EEF  |.  03C8          add     ecx, eax
00403EF1  |.  51            push    ecx                              ;  ECX=注册码
00403EF2  |.  894C24 2C     mov     [esp+2C], ecx
00403EF6  |.  8B4C24 30     mov     ecx, [esp+30]
00403EFA  |.  68 80FA4600   push    0046FA80                         ;  ASCII "%04x"
00403EFF  |.  51            push    ecx
00403F00  |.  E8 EC230200   call    004262F1
00403F05  |.  33C0          xor     eax, eax
00403F07  |.  83C4 30       add     esp, 30
00403F0A  \.  C3            retn

//////////////  以上是代码  ////////////////

机器码现在是9个字符,去掉首字符后所剩8个字符为:5859a29d。我一开始还在
一句一句地分析指令功能,等到步过00403EDE这句时,眼前忽然一亮:

                     EAX 5859A29D

不会这么简单吧!跟到00403EF1查看ECX的值为79BB7066。从这个子程序返回,到
外面一看,真码就是79bb7066!捏到软柿子了!这么说来,只需要额外编写一个
16进制数值与对应的ASCII字串相互转换的函数,而注册码计算的功能完全由上面
00403EE2到00403EEF这几句所标明了。

  (3)注册函数

void Hextoasc(unsigned long int uValue, char *lpTransformedBuffer)

/* 实现把uValue所对应的16进制数值转化为ASCII字符串。16进制字母采用小写 */
/* 入口参数:uValue――16进制数值
             lpTransformedBuffer――用于存放转化串的缓冲区             */
/* 出口参数:lpTransformedBuffer――ASCII串的指针                      */
/* 注意:对输入不作合法性检测!                                        */

{
   char i = 8, temp;
   lpTransformedBuffer[i]='\0';
   do{
       temp = uValue % 16;
       lpTransformedBuffer[i - 1] = temp + (temp < 10 ? '0': 87);
       uValue = uValue >> 4;
       i = i - 1;
     }while(i != 0);
   
}      

unsigned long int uAsctohex(char *lpString)

/* 实现把lpString对应的字符串转换为16进制数值。 */
/* 注意:对输入不作合法性检测!                 */

{
   unsigned long int result = 0;
   char a, i;
   i = 0;
   while(i < 8 && lpString[i] != '\0'){
           if (lpString[i] > '9')
             a = (lpString[i] & 0x1f) + 9;
           else
             a = lpString[i] - '0';
           result = (result << 4) + a;      
           i = i + 1;
           }
   return result;
   
}

void KeyGen(char *lpFingerPrint, char *lpRegCodeBuffer)

/*  注册码计算程序。                                  */
/*  入口参数:lpFingerPrint――机器码字串         
              lpRegCodeBuffer――存放注册码的缓冲区   */
/*  出口参数:lpRegCodeBuffer――注册码字串           */

{
    unsigned long int m;  
    m = uAsctohex(lpFingerPrint + 1);
    m = m ^ 0x6F37AE52;
    m = (m << 27) + (m >> 5);
    Hextoasc(m, lpRegCodeBuffer);
}

[课程]Android-CTF解题方法汇总!

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 207
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
哈 这个不错 我至少看懂了~~
2006-4-10 23:42
0
雪    币: 50
活跃值: (145)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
3
挺好,顶一个来来
2006-4-10 23:45
0
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
4
代表四楼顶!...
2006-4-11 00:29
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢,学习学习.........
2006-4-11 02:10
0
雪    币: 433
活跃值: (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主似乎生活在世外桃园苦练内功,可敬可佩。
同时也要善于利用现代科技带来的便捷,搜索技巧也不能忽视啊。
http://www.google.com/search?q=+L0phtCrack+v5&hl=zh-CN&ie=GB2312&btnG=Google%CB%D1%CB%F7
http://www.pediy.com/bbshtml/BBS6/pediy6532.htm
2006-4-11 19:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
好帖子。。。。。。。。。。。。。。。。。。
2006-4-12 01:02
0
雪    币: 2506
活跃值: (1000)
能力值: (RANK:990 )
在线值:
发帖
回帖
粉丝
8
楼上的请你注意一下,不要在技术区灌纯水!你到现在为止八个回帖里有7个是一样的,另一个也基本相同。
2006-4-12 01:37
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
9
学习+支持
2006-4-12 08:06
0
雪    币: 517
活跃值: (35)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
感觉注册机写得是不是有些复杂了?

我来一个:

        UpdateData(true);
        char serial[10];
        unsigned long tmp;

        strcpy(serial,m_ser);
        tmp=strtoul(serial+1,0,16);
        tmp^=0x6F37AE52;
        tmp=(tmp<<0x1B)+(tmp>>5);
        m_sn.Format("%08x",tmp);
        UpdateData(false);
2006-4-12 10:02
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这个东东不是柿子吧
应该叫……
棉花糖:)
2006-4-12 10:04
0
游客
登录 | 注册 方可回帖
返回
//