LibXL 算法分析(附注册机)

转载自:http://www.52pojie.cn/thread-566985-1-1.html

 

【文章标题】: LibXL 算法分析(附注册机
【文章作者】: GCCG
【软件名称】: LibXL
【下载地址】: http://www.libxl.com
【加壳方式】: 无加壳
【编写语言】: Visual C++
【使用工具】: OllyDbg
【操作平台】: windows
【软件介绍】: LibXL is a library that can read and write Excel files. It doesn't require Microsoft Excel and .NET framework, combines an easy to use and powerful features.

 

LibXL 可以原格式读写 Excel ,不需要电脑安装 Office, 具体使用请参照官网的文档:http://www.libxl.com/documentation.html
好久没练手了, 这次分析下算法. 看下 libxl.dll 中的导出函数 xlBookSetKeyA(BookHandle handle, const char* name, const char* key); 
很容易找到关键地方。编写个测试 exe 进入 xlBookSetKey 开始调试。我只简单描述下关键地方.
[Asm]   纯文本查看   复制代码
?
1
2
3
4
5
6
10032640  /$  55            push    ebp                              ;  xlBookSetKey 函数入口
10032641  |.  8BEC          mov     ebp , esp
10032643  |.  6A FF         push    -0x1
10032645  |.  68 CA4D3810   push    10384DCA
1003264A  |.  64:A1 0000000> mov     eax , dword ptr fs :[0]
10032650  |.  50            push    eax

下面 是对用户名,注册码长度判断
[Asm]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
10032687  |.  85DB          test    ebx , ebx                         ;  用户名是否为空?
10032689  |.  0F84 C2040000 je      10032B51
1003268F  |.  85C0          test    eax , eax                         ;  注册码是否为空?
10032691  |.  0F84 BA040000 je      10032B51
10032697  |.  50            push    eax
10032698  |.  8D4D 98       lea     ecx , dword ptr [ ebp -0x68]
1003269B  |.  E8 B02DFDFF   call    10005450                        ;  求注册码长度
100326A0  |.  837D AC 28    cmp     dword ptr [ ebp -0x54], 0x28      ;  注册码长度 是否 为 40 位?
100326A4  |.  C645 FC 01    mov     byte ptr [ ebp -0x4], 0x1
100326A8  |.  C686 44030000> mov     byte ptr [ esi +0x344], 0x0
100326AF  |.  8D4D 98       lea     ecx , dword ptr [ ebp -0x68]
100326B2  |.  0F85 94040000 jnz     10032B4C
100326B8  |.  6A 08         push    0x8


[Asm]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
100327C4  |.  E8 67D0FFFF   call    1002F830                        ;  用户名字符串 翻转
100327C9  |.  56            push    esi
100327CA  |.  E8 01083300   call    10362FD0
100327CF  |.  83C4 14       add     esp , 0x14
100327D2  |.  6A FF         push    -0x1
100327D4  |.  6A 00         push    0x0
100327D6  |.  8D8D 7CFFFFFF lea     ecx , dword ptr [ ebp -0x84]
100327DC  |.  51            push    ecx
100327DD  |.  8B8D ECFEFFFF mov     ecx , dword ptr [ ebp -0x114]
100327E3  |.  81C1 A4090000 add     ecx , 0x9A4
100327E9  |.  E8 A2EBFCFF   call    10001390
100327EE  |.  83EC 1C       sub     esp , 0x1C
100327F1  |.  8D95 7CFFFFFF lea     edx , dword ptr [ ebp -0x84]
100327F7  |.  8BCC          mov     ecx , esp
100327F9  |.  89A5 E8FEFFFF mov     dword ptr [ ebp -0x118], esp
100327FF  |.  52            push    edx
10032800  |.  E8 4BEDFCFF   call    10001550
10032805  |.  8D85 28FFFFFF lea     eax , dword ptr [ ebp -0xD8]
1003280B  |.  50            push    eax
1003280C  |.  E8 2F750300   call    10069D40                        ;  翻转后的用户名, 求 MD5 值
10032811  |.  83C4 20       add     esp , 0x20


下面一段代码 取出32位注册码的第1,3,5,7,9,11,13,15,17,19,21,23,25位,并将取出的字符连接成字符串

[Asm]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
100328E0  |> /83FE 20       / cmp     esi , 0x20
100328E3  |. |73 43         | jnb     short 10032928
100328E5  |. |83FE 1A       | cmp     esi , 0x1A
100328E8  |. |73 1B         | jnb     short 10032905
100328EA  |. |56            | push    esi
100328EB  |. |8D8D F0FEFFFF | lea     ecx , dword ptr [ ebp -0x110]
100328F1  |. |E8 6A730300   | call    10069C60
100328F6  |. |0FB600        | movzx   eax , byte ptr [ eax ]
100328F9  |. |50            | push    eax                             ; /Arg1
100328FA  |. |8D8D 0CFFFFFF | lea     ecx , dword ptr [ ebp -0xF4]      ; |
10032900  |. |E8 6BD5FFFF   | call    1002FE70                       ; \libxl.1002FE70
10032905  |> |8D4E 01       | lea     ecx , dword ptr [ esi +0x1]
10032908  |. |51            | push    ecx
10032909  |. |8D8D F0FEFFFF | lea     ecx , dword ptr [ ebp -0x110]
1003290F  |. |E8 4C730300   | call    10069C60
10032914  |. |0FB610        | movzx   edx , byte ptr [ eax ]
10032917  |. |52            | push    edx                             ; /Arg1
10032918  |. |8D8D 44FFFFFF | lea     ecx , dword ptr [ ebp -0xBC]      ; |
1003291E  |. |E8 4DD5FFFF   | call    1002FE70                       ; \libxl.1002FE70
10032923  |. |83C6 02       | add     esi , 0x2
10032926  |.^\EB B8         \ jmp     short 100328E0


对上一步取出的字符串 求 MD5,并截取 前 16 位,比较 md5 值的 前 16 位 是否是 3f8bfcaff330c39f
[Asm]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1003298E  |.  8038 33       cmp     byte ptr [ eax ], 0x33            ;  3
10032991  |.  0F85 41010000 jnz     10032AD8
10032997  |.  6A 01         push    0x1
10032999  |.  8D4D D0       lea     ecx , dword ptr [ ebp -0x30]
1003299C  |.  E8 BF720300   call    10069C60
100329A1  |.  8038 66       cmp     byte ptr [ eax ], 0x66            ;  f
100329A4  |.  0F85 2E010000 jnz     10032AD8
100329AA  |.  6A 02         push    0x2
100329AC  |.  8D4D D0       lea     ecx , dword ptr [ ebp -0x30]
100329AF  |.  E8 AC720300   call    10069C60
100329B4  |.  8038 38       cmp     byte ptr [ eax ], 0x38            ;  8
100329B7  |.  0F85 1B010000 jnz     10032AD8
100329BD  |.  6A 03         push    0x3
100329BF  |.  8D4D D0       lea     ecx , dword ptr [ ebp -0x30]
100329C2  |.  E8 99720300   call    10069C60
100329C7  |.  8038 62       cmp     byte ptr [ eax ], 0x62            ;  b
100329CA  |.  0F85 08010000 jnz     10032AD8
100329D0  |.  6A 04         push    0x4
100329D2  |.  8D4D D0       lea     ecx , dword ptr [ ebp -0x30]
100329D5  |.  E8 86720300   call    10069C60
100329DA  |.  8038 66       cmp     byte ptr [ eax ], 0x66            ;  f
...............................
...............................


以下代码, 可知注册码第 27, 29, 31 位满足关系
[Asm]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
1002EE13 |. 0FBE71 1C movsx esi , byte ptr [ ecx +0x1C]
1002EE17 |. 81C6 79070000 add esi , 0x779
1002EE1D |. 83F8 1E cmp eax , 0x1E
1002EE20 |. 73 09 jnb short 1002EE2B
1002EE22 |. E8 6B3C3300 call 10362A92
1002EE27 |. 8B4424 24 mov eax , dword ptr [ esp +0x24]
1002EE2B |> 8B4C24 14 mov ecx , dword ptr [ esp +0x14]
1002EE2F |. 396C24 28 cmp dword ptr [ esp +0x28], ebp
1002EE33 |. 73 04 jnb short 1002EE39
1002EE35 |. 8D4C24 14 lea ecx , dword ptr [ esp +0x14]
1002EE39 |> 57 push edi
1002EE3A |. 0FBE79 1E movsx edi , byte ptr [ ecx +0x1E]
1002EE3E |. 83EF 69 sub edi , 0x69
1002EE41 |. 83F8 1A cmp eax , 0x1A
1002EE44 |. 73 05 jnb short 1002EE4B
1002EE46 |. E8 473C3300 call 10362A92
1002EE4B |> 8B4424 18 mov eax , dword ptr [ esp +0x18]
1002EE4F |. 396C24 2C cmp dword ptr [ esp +0x2C], ebp
1002EE53 |. 73 04 jnb short 1002EE59
1002EE55 |. 8D4424 18 lea eax , dword ptr [ esp +0x18]
1002EE59 |> 0FBE50 1A movsx edx , byte ptr [ eax +0x1A]
1002EE5D |. 8D8C37 87F8FF> lea ecx , dword ptr [ edi + esi -0x779]
1002EE64 |. 3BD1 cmp edx , ecx
1002EE66 |. 75 28 jnz short 1002EE90
1002EE68 |. 81FE DD070000 cmp esi , 0x7DD
1002EE6E |. 7E 0F jle short 1002EE7F
1002EE70 |. 81FE DF070000 cmp esi , 0x7DF
1002EE76 |. 7C 18 jl short 1002EE90
1002EE78 |. 75 0D jnz short 1002EE87
1002EE7A |. 83FF 03 cmp edi , 0x3
1002EE7D |. EB 06 jmp short 1002EE85
1002EE7F |> 81FE DC070000 cmp esi , 0x7DC


由上面可得知 注册码第27, 29, 31 位 满足以下关系
[Asm]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
第29个字符串 d  0x64 + 0x779 = 0x7DD   -> ESI
 
第31个字符串 o  0x6F-0x69  = 0x6       -> EDI
 
第27个字符串 j  0x6A                  
 
 
ESI + EDI - 0x779 = 0x6A
 
if  ESI <= 0x7DD then
      if ESI < 0x7DC then
            [ ebx +0x9F8]= 0x1   失败
      else
           [ ebx +0x99C]= 0  成功
     end if
else
      if ESI < 0x7DF then
           [ ebx +0x9F8]= 0x1  失败
     else
          if ESI != 0x7DF then
             [ ebx +0x99C]= 0  成功
          else
               if EDI < 0x3 then
                   [ ebx +0x9F8]= 0x1  失败
              else
                   [ ebx +0x99C]= 0 成功
              end if
          end if   
      end if
end if


算法总结:
1. 注册码格式:windows-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(windows- 后面 32 位) 

2. 32位注册码的第1,3,5,7,9,11,13,15,17,19,21,23,25位是固定值, 分别是  22200ce06b66a

3. 32位注册码的第2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,30, 32位是:用户名字符串,经过翻转, 求出 MD5 值, 然后 取 前 16 位

4. 32位注册码的第27, 29, 31 位满足以下关系:

    (1)   ASC(29位)+ASC(31位)-0x69 = ASC(27位字母)

    (2)  ASC(29位) >= 0x63  并且  ASC(29位) 不能等于 0x65,  而且 当 ASC(29位) = 0x66 时,ASC(31位) >=0x6C


以下是注册机源码的关键部分(使用 PowerBASIC 语言 
[Visual Basic]   纯文本查看   复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
function GetRegCode(byval hWnd as dword, byref edtstr as asciiz) as STRING
         local i as LONG
         local oMD5 as iMD5
         Dim bReg(32) as BYTE
         local sName as asciiz * 260
         local szMd5 as ASCIIZ * 40
         local szChar as ASCIZ * 10
         dim p as byte ptr
         dim pRegCode as ASCIIZ ptr
         if CheckIsDBCS(edtstr) = 1 THEN
                 MessageBox hWnd, "用户名不能包含中文。" , "提示!" , %MB_OK or %MB_ICONEXCLAMATION
         END IF
         
         for i = len(edtstr) to 1 step -1
                 sName = sName & Mid$(edtstr, i, 1)
         NEXT
         oMD5 = class "MD5"
         szMd5 = LCASE$(oMD5.calc(sName))
         ARRAY ASSIGN bReg() = &H32,&H00,&H32,&H00,&H32,&H00,&H30,&H00,&H30,&H00,&H63,&H00,&H65,&H00,&H30,&H00,&H36,&H00,&H62,&H00,&H36,&H00,&H36,&H00,&H61,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
         p = varptr(szMd5)
         for i = 1 to 31
                 bReg(i) = @p
                 p=p+1
                 i=i+1
         NEXT
         szChar = GetThreeChar()
         p = varptr(szChar)
         bReg(26) = @p
         p = p+1
         bReg(28) = @p
         p = p+1
         bReg(30) = @p
         
         pRegCode = varptr(bReg(0))
         
         function = "windows-" & @pRegCode
END FUNCTION
 
function GetThreeChar() as STRING
         local char27 as ASCIIZ * 2
         local char29 as ASCIIZ * 2
         local char31 as ASCIIZ * 2
         
         char29 = Get29()
         char31 = Get31(char29)
         char27 = chr$(ASC(char29) + ASC(char31) - 105)
 
         function = char27 & char29 & char31
END FUNCTION
 
function Get29() as string
         local char29 as ASCIIZ * 2
         randomize
         char29 = chr$(int(rnd*24 + 99))
         if asc(char29) = 101 THEN  ' e
                 Get29()
         END IF
 
         function = char29
END FUNCTION
 
function Get31(byref char as asciiz) as STRING
         local char31 as ASCIIZ * 2
         randomize
         char31 = chr$(int(rnd*26 + 202- ASC(char)))
         if ASC(char) <> 102 THEN
                 if ASC(char31) >= 97 and ASC(char31) < 123 THEN
                         function = char31
                 else
                         Get31(char)
                 END IF
         else
                 if ASC(char31) >= 108 and ASC(char31) < 123 THEN
                         function = char31
                 else
                         Get31(char)
                 END IF
         END IF
END FUNCTION


--------------------------------------------------------------------------------
【版权声明】: 本文原创于吾爱破解论坛, 转载请注明作者并保持文章的完整, 谢谢!

附一张注册机截图:(帖子附件包含注册机,以及注册机的 PowerBASIC 源码 )
(提示:杀软可能会误报, 不信者可以自己编译。)

 

注册机+源码:
 Keygen for LibXL.rar (124 KB, 下载次数: 167) 
用法:
见30楼:http://www.52pojie.cn/forum.php?mod=redirect&goto=findpost&ptid=566985&pid=14784663

 

点评

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值