菜鸟学破解:1.Feiq等级设置
公司内部聊天软件用的是Feiq,像QQ那样也有太阳月亮星星等级,不过是用授权码方式进行设置。
用OD打开运行Feiq,在汇编窗口右键选择“查找”“所有模块中的名字”,找出MessageBoxA打上断点。
打开Feiq的等级设置窗口,随便填个授权码,按确定跑到MessageBoxA的断点处,可见执行这个函数后会弹出“授权码不正确”的窗口;返回上一个函数,会发现这里分别有两个地方调用MessageBoxA,稍往前观察可得"00463503   .  74 25         je      short 0046352A"这里的决定调用哪个MessageBoxA;猜想这里就是判断授权码对错的分支,把je改成jne后再运行等级设置,断点后弹出“授权码正确”的窗口。
因此,把Feiq.exe中那个地方的je改成jne,以后运行这个exe就可以随意进行等级设置了。

=========================================================
00463480   .  6A FF         push    -1
00463482   .  68 D8505800   push    005850D8                         ;  SE 处理程序安装
00463487   .  64:A1 0000000>mov     eax, dword ptr fs:[0]
0046348D   .  50            push    eax
0046348E   .  64:8925 00000>mov     dword ptr fs:[0], esp
00463495   .  83EC 08       sub     esp, 8
00463498   .  53            push    ebx
00463499   .  56            push    esi
0046349A   .  57            push    edi
0046349B   .  8BF9          mov     edi, ecx
0046349D   .  6A 01         push    1
0046349F   .  E8 C27E1000   call    0056B366
004634A4   .  8B47 68       mov     eax, dword ptr [edi+68]
004634A7   .  8D57 60       lea     edx, dword ptr [edi+60]
004634AA   .  50            push    eax
004634AB   .  51            push    ecx
004634AC   .  8BCC          mov     ecx, esp
004634AE   .  896424 18     mov     dword ptr [esp+18], esp
004634B2   .  52            push    edx
004634B3   .  E8 C94F1000   call    00568481
004634B8   .  8D4424 14     lea     eax, dword ptr [esp+14]
004634BC   .  50            push    eax
;;;;;;;;;;;;;;;;;;;;;;;;传入机器标识码,算出授权码;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
004634BD   .  E8 0E040300   call    004938D0

004634C2   .  83C4 0C       add     esp, 0C
004634C5   .  8B77 64       mov     esi, dword ptr [edi+64]
004634C8   .  8B4424 0C     mov     eax, dword ptr [esp+C]
004634CC   .  C74424 1C 000>mov     dword ptr [esp+1C], 0
004634D4   >  8A10          mov     dl, byte ptr [eax]
004634D6   .  8A1E          mov     bl, byte ptr [esi]
004634D8   .  8ACA          mov     cl, dl
;;;;;;;;;;;;;;;;;;;;;;;;比较输入的字符串和授权码;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
004634DA   .  3AD3          cmp     dl, bl
004634DC   .  75 1E         jnz     short 004634FC
004634DE   .  84C9          test    cl, cl
004634E0   .  74 16         je      short 004634F8
004634E2   .  8A50 01       mov     dl, byte ptr [eax+1]
004634E5   .  8A5E 01       mov     bl, byte ptr [esi+1]
004634E8   .  8ACA          mov     cl, dl
004634EA   .  3AD3          cmp     dl, bl
004634EC   .  75 0E         jnz     short 004634FC
004634EE   .  83C0 02       add     eax, 2
004634F1   .  83C6 02       add     esi, 2
004634F4   .  84C9          test    cl, cl
004634F6   .^ 75 DC         jnz     short 004634D4

004634F8   >  33C0          xor     eax, eax
004634FA   .  EB 05         jmp     short 00463501
004634FC   >  1BC0          sbb     eax, eax
004634FE   .  83D8 FF       sbb     eax, -1
00463501      85C0          test    eax, eax
;;;;;;;;;;;;;;;;;;;;;;;;跳转至“授权码正确”对话框;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00463503   .  74 25         je      short 0046352A

00463505   .  68 D8E75F00   push    005FE7D8
0046350A   .  8D4C24 10     lea     ecx, dword ptr [esp+10]
0046350E   .  E8 82531000   call    00568895
00463513   .  8B47 5C       mov     eax, dword ptr [edi+5C]
00463516   .  6A 40         push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00463518   .  68 90755E00   push    005E7590                         ; |Title = "提示"
0046351D   .  50            push    eax                              ; |Text
0046351E   .  8B47 1C       mov     eax, dword ptr [edi+1C]          ; |
00463521   .  50            push    eax                              ; |hOwner
;;;;;;;;;;;;;;;;;;;;;;;;“授权码不正确”对话框;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00463522   .  FF15 10775900 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA

00463528   .  EB 1D         jmp     short 00463547
0046352A   >  8B4F 1C       mov     ecx, dword ptr [edi+1C]
0046352D   .  6A 40         push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0046352F   .  68 74C65E00   push    005EC674                         ; |Title = "成?,A6,""
00463534   .  68 64C65E00   push    005EC664                         ; |Text = "授?,A8,"码正?,B7,"?,A1,""
00463539   .  51            push    ecx                              ; |hOwner
;;;;;;;;;;;;;;;;;;;;;;;;“授权码正确”对话框;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0046353A   .  FF15 10775900 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA

00463540   .  8BCF          mov     ecx, edi
00463542   .  E8 384E1000   call    0056837F
00463547   >  8D4C24 0C     lea     ecx, dword ptr [esp+C]
0046354B   .  C74424 1C FFF>mov     dword ptr [esp+1C], -1
00463553   .  E8 B4511000   call    0056870C
00463558   .  8B4C24 14     mov     ecx, dword ptr [esp+14]
0046355C   .  5F            pop     edi
0046355D   .  5E            pop     esi
0046355E   .  64:890D 00000>mov     dword ptr fs:[0], ecx
00463565   .  5B            pop     ebx
00463566   .  83C4 14       add     esp, 14
00463569   .  C3            retn
=========================================================

除了直接改跳转的方法,还可以直接找出它的授权码。在“决定性一跳”之前有个比较变量的地方,观察发现是把输入的授权码和一个字符串进行比较,这样不改exe,直接手工输入该字符串,也可以任意设置等级了。
然而,如果换了机器,这个字符串就无效了。可以想到授权码的生成和机器信息(如计算机标识码之类)有关,因此可以更进一步寻找授权码生成的方法,做成算号器。由于本人水平和时间有限,这部分没有完成。

菜鸟学破解:2.文件解密

公司最近启用加密策略,对某些项目文件进行自动加解密,这样文件就算带回家也打不开了。

随便新建了几个小文件,观察加密后的二进制,加密文件由大致三部分组成:密文、0填充区和附加信息。其中密文和原文长度一致,附加信息对于每个文件都是一样的。
初步猜测,加密应该是某种字符映射Hash算法,估计可以穷举暴力解密。
于是分别生成内容全部是0x00,0x01……0xFF的文件,对比自动加密后生成的文件,发现加密算法以4个bit为单位。一共有16种(f0:{0->0,1->1...},f1:{0->1,1->0...}...fF:{0->F,1->E...})映射,根据原文字节的位置选一种映射得到密文,对应可以表示为:(f8 f7) (fD f1) (f1 f2) (f7 fD) ...
至于对应某个位置应该选哪一种映射,从这里难以看出规律,而且找不到有循环周期;然而,如果只要有一个原文全是0x00的Nbyte的加密后文件,就可以此为参考很方便地得到每个位置的映射,从而可以解密小于Nbyte的加密文件。

=======原文:密文=====================================
00 00 00 ……:  87 D1 12 7D 4C 73 0D 4C 86 69 9A 66 08 ED EF DF ……  
01 01 01 ……:  86 D0 13 7C 4D 72 0C 4D 87 68 9B 67 09 EC EE DE ……  
02 02 02 ……:  85 D3 10 7F 4E 71 0F 4E 84 6B 98 64 0A EF ED DD ……  
03 03 03 ……:  84 D2 11 7E 4F 70 0E 4F 85 6A 99 65 0B EE EC DC ……  
04 04 04 ……:  83 D5 16 79 48 77 09 48 82 6D 9E 62 0C E9 EB DB ……  
05 05 05 ……:  82 D4 17 78 49 76 08 49 83 6C 9F 63 0D E8 EA DA ……  
06 06 06 ……:  81 D7 14 7B 4A 75 0B 4A 80 6F 9C 60 0E EB E9 D9 ……  
07 07 07 ……:  80 D6 15 7A 4B 74 0A 4B 81 6E 9D 61 0F EA E8 D8 ……  
08 08 08 ……:  8F D9 1A 75 44 7B 05 44 8E 61 92 6E 00 E5 E7 D7 ……  
09 09 09 ……:  8E D8 1B 74 45 7A 04 45 8F 60 93 6F 01 E4 E6 D6 ……  
0A 0A 0A ……:  8D DB 18 77 46 79 07 46 8C 63 90 6C 02 E7 E5 D5 ……  
0B 0B 0B ……:  8C DA 19 76 47 78 06 47 8D 62 91 6D 03 E6 E4 D4 ……  
0C 0C 0C ……:  8B DD 1E 71 40 7F 01 40 8A 65 96 6A 04 E1 E3 D3 ……  
0D 0D 0D ……:  8A DC 1F 70 41 7E 00 41 8B 64 97 6B 05 E0 E2 D2 ……  
0E 0E 0E ……:  89 DF 1C 73 42 7D 03 42 88 67 94 68 06 E3 E1 D1 ……  
0F 0F 0F ……:  88 DE 1D 72 43 7C 02 43 89 66 95 69 07 E2 E0 D0 …… 
 ……
====================================================

除了暴力,当然还有其他的办法。例如可以翻出进程里面调用的加解密模块,分析跟踪一下,还能找到选择映射的算法,这就一劳永逸,多大的文件都可以方便解密了。当然,本人还菜,只是有个想法,还没做出来。

这是我初学破解的小“成果”,和大家分享一下,也希望可以申请到邀请码

  • 标 题:答复
  • 作 者:jass
  • 时 间:2009-08-26 21:08:10

前言:原文再续书接上一回(很高兴拿到邀请码了,顺便掘坟),上回说到注册机--
================================================================

菜鸟学破解:1.Feiq等级设置(续): 找出Feiq授权码生成的算法

我的方法比较原始:跟踪函数,通过搜索内存找出授权码字符串是在哪个call之后才出现的;转向跟踪那个call的子函数,重复之前的方法不断层层进入,找到生成授权码的最深层子函数。
在feiq中,由于等级设置窗口有计算机标识码字符串,我猜想授权码是通过它来生成的,理想情况下,那个最深层子函数就是对计算机标识码字符串直接作一些例如加减乘除与或异或移位等运算,然后生成授权码。可惜,事实没有那么简单,授权码的计算并非“一步”完成。
因此,我的主要思路是:回溯,授权码可能由中间量A生成,通过分析算法找出A,而A可能由中间量B和C生成,B可能由中间量D、E等和一些已知量(例如计算机标识码,程序里的常量等)生成,这样一步一步追根溯源,逆流而上,最终找出所有已知量,综合当中由已知量生成未知量的算法就得到生成授权码的算法。


用OD载入Feiq,进入之前爆破所在的函数00463480,找到之前分析确认是传入计算机标识码生成授权码的函数004938D0,通过边搜索内存边步进,在call 00568C0E之后出现了授权码,如果忽略大小写,在call 00493B60之后会出现大小写混杂的“授权码”。用IDA分析,00568C0E正是CStrng::MackUpper。

代码:
//函数004938D0(GenLv1_MacID_RegCode)
004938D0  /$  6A FF         push    -1
004938D2  |.  68 299E5800   push    00589E29                         ;  SE 处理程序安装
004938D7  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0049391E  |.  8D4424 24     lea     eax, dword ptr [esp+24]
00493922  |.  50            push    eax
00493923  |.  E8 38020000   call    00493B60                         ;  JASS: 生成字串JOLG...
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493954  |.  55            push    ebp
00493955  |.  8BD1          mov     edx, ecx
00493957  |.  8BF7          mov     esi, edi
00493959  |.  8BFB          mov     edi, ebx
0049395B  |.  53            push    ebx
0049395C  |.  C1E9 02       shr     ecx, 2
0049395F  |.  F3:A5         rep     movs dword ptr es:[edi], dword p>
00493961  |.  8BCA          mov     ecx, edx
00493963  |.  83E1 03       and     ecx, 3
00493966  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr>
00493968  |.  8D4C24 30     lea     ecx, dword ptr [esp+30]
0049396C  |.  E8 1F11F7FF   call    00404A90                         ;  JASS: 生成4055c0用到的参考数组S
00493971  |.  8B8424 440800>mov     eax, dword ptr [esp+844]
00493978  |.  C68424 380800>mov     byte ptr [esp+838], 3
00493980  |.  8B68 F8       mov     ebp, dword ptr [eax-8]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493A01  |.  6A 22         push    22
00493A03  |.  8D8424 3C0400>lea     eax, dword ptr [esp+43C]
00493A0A  |.  55            push    ebp
00493A0B  |.  8D4C24 40     lea     ecx, dword ptr [esp+40]
00493A0F  |.  50            push    eax
00493A10  |.  51            push    ecx
00493A11  |.  8D4C24 40     lea     ecx, dword ptr [esp+40]
00493A15  |.  E8 A61BF7FF   call    004055C0                         ;  JASS: 传入机器标识码,生成产生数字串"xxx"的二进制串的函数
00493A1A  |.  8B15 889F5F00 mov     edx, dword ptr [5F9F88]          ;  飞秋FeiQ.005F9F9C
00493A20  |.  8BF8          mov     edi, eax
00493A22  |.  895424 18     mov     dword ptr [esp+18], edx
00493A26  |.  33F6          xor     esi, esi
00493A28  |.  C68424 380800>mov     byte ptr [esp+838], 4
00493A30  |.  85FF          test    edi, edi
00493A32  |.  7E 51         jle     short 00493A85
00493A34  |>  A1 889F5F00   /mov     eax, dword ptr [5F9F88]
00493A39  |.  894424 10     |mov     dword ptr [esp+10], eax
00493A3D  |.  33C9          |xor     ecx, ecx
00493A3F  |.  8D5424 10     |lea     edx, dword ptr [esp+10]
00493A43  |.  8A8C34 300400>|mov     cl, byte ptr [esp+esi+430]
00493A4A  |.  C68424 380800>|mov     byte ptr [esp+838], 5
00493A52  |.  51            |push    ecx
00493A53  |.  68 88FD5E00   |push    005EFD88                        ;  ASCII "%u"
00493A58  |.  52            |push    edx
00493A59  |.  E8 56040D00   |call    00563EB4                        ;  JASS: 类似sprintf函数
00493A5E  |.  83C4 0C       |add     esp, 0C
00493A61  |.  8D4424 10     |lea     eax, dword ptr [esp+10]
00493A65  |.  8D4C24 18     |lea     ecx, dword ptr [esp+18]
00493A69  |.  50            |push    eax
00493A6A  |.  E8 B5500D00   |call    00568B24                        ;  JASS: 类似CString::operator+=
00493A6F  |.  8D4C24 10     |lea     ecx, dword ptr [esp+10]
00493A73  |.  C68424 380800>|mov     byte ptr [esp+838], 4
00493A7B  |.  E8 8C4C0D00   |call    0056870C
00493A80  |.  46            |inc     esi
00493A81  |.  3BF7          |cmp     esi, edi
00493A83  |.^ 7C AF         \jl      short 00493A34
00493A85  |>  8B8C24 480800>mov     ecx, dword ptr [esp+848]         ;  JASS:数字串"xxx"已生成
00493A8C  |.  8D5424 18     lea     edx, dword ptr [esp+18]
00493A90  |.  51            push    ecx
00493A91  |.  51            push    ecx
00493A92  |.  8BCC          mov     ecx, esp
00493A94  |.  896424 18     mov     dword ptr [esp+18], esp
00493A98  |.  52            push    edx
00493A99  |.  E8 E3490D00   call    00568481
00493A9E  |.  8D4424 1C     lea     eax, dword ptr [esp+1C]
00493AA2  |.  50            push    eax
00493AA3  |.  E8 B8000000   call    00493B60                         ;  JASS:生成lmto.....
00493AA8  |.  53            push    ebx
00493AA9  |.  C68424 480800>mov     byte ptr [esp+848], 6
00493AB1  |.  E8 76400D00   call    00567B2C
00493AB6  |.  8B4C24 30     mov     ecx, dword ptr [esp+30]
00493ABA  |.  51            push    ecx
00493ABB  |.  E8 6C400D00   call    00567B2C
00493AC0  |.  83C4 14       add     esp, 14
00493AC3  |.  8D4C24 14     lea     ecx, dword ptr [esp+14]
00493AC7  |.  E8 42510D00   call    00568C0E                         ;  JASS:CString::MakeUpper 生成LMTO.....
00493ACC  |.  8BB424 400800>mov     esi, dword ptr [esp+840]
00493AD3  |.  8D5424 14     lea     edx, dword ptr [esp+14]
00493AD7  |.  52            push    edx
00493AD8  |.  8BCE          mov     ecx, esi
00493ADA  |.  E8 A2490D00   call    00568481
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493B59  \.  C3            retn
 

进入函数00493B60,会看到有5个循环。第一个循环里充满令人发昏的浮点运算;第二、三、四个循环很相似,而且分别循环5次;第五个循环里有和数字、大小写字母比较的判断。跟踪分析得,一串很长的数字ASCII码串经过第一循环得到了三个32位数,第二、三、四循环分别用这三个数生成了一个15byte的数组,这个数组经过第五循环的变换得到了15个字符的大小写混杂的“授权码”。
代码:
//函数00493B60(GenLv2_NumStr_RegCodeCI)
00493B60  /$  6A FF         push    -1
00493B62  |.  68 679E5800   push    00589E67                         ;  SE 处理程序安装
00493B67  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493BDF  |.  8B7C24 58     mov     edi, dword ptr [esp+58]
00493BE3  |>  8B4424 54     /mov     eax, dword ptr [esp+54]         ;  JASS: 由字串"xxxx"生成一整数
00493BE7  |.  0FAFD5        |imul    edx, ebp
00493BEA  |.  DB4424 18     |fild    dword ptr [esp+18]
00493BEE  |.  DD5C24 18     |fstp    qword ptr [esp+18]
00493BF2  |.  8A5C30 FF     |mov     bl, byte ptr [eax+esi-1]
00493BF6  |.  0FAF5424 10   |imul    edx, dword ptr [esp+10]
00493BFB  |.  0FBECB        |movsx   ecx, bl
00493BFE  |.  0FAFD7        |imul    edx, edi
00493C01  |.  894C24 58     |mov     dword ptr [esp+58], ecx
00493C05  |.  DB4424 58     |fild    dword ptr [esp+58]
00493C09  |.  0FBEC3        |movsx   eax, bl
00493C0C  |.  D9FA          |fsqrt
00493C0E  |.  0FAFC6        |imul    eax, esi
00493C11  |.  DC4C24 18     |fmul    qword ptr [esp+18]
00493C15  |.  DC05 B89A5900 |fadd    qword ptr [599AB8]
00493C1B  |.  0FAFC6        |imul    eax, esi
00493C1E  |.  894424 58     |mov     dword ptr [esp+58], eax
00493C22  |.  DB4424 58     |fild    dword ptr [esp+58]
00493C26  |.  895424 58     |mov     dword ptr [esp+58], edx
00493C2A  |.  DEC9          |fmulp   st(1), st
00493C2C  |.  DB4424 58     |fild    dword ptr [esp+58]
00493C30  |.  DEC1          |faddp   st(1), st
00493C32  |.  E8 75CD0B00   |call    005509AC                        ;  JASS: _ftol浮点转长整数:arg ST0--return eax
00493C37  |.  99            |cdq
00493C38  |.  B9 A0860100   |mov     ecx, 186A0
00493C3D  |.  F7F9          |idiv    ecx
00493C3F  |.  895424 10     |mov     dword ptr [esp+10], edx         ;  JASS-DEBUG: edx - IterValA
00493C43  |.  DB4424 10     |fild    dword ptr [esp+10]
00493C47  |.  0FBED3        |movsx   edx, bl
00493C4A  |.  DD5C24 28     |fstp    qword ptr [esp+28]
00493C4E  |.  895424 58     |mov     dword ptr [esp+58], edx
00493C52  |.  DB4424 58     |fild    dword ptr [esp+58]
00493C56  |.  DD05 F8BA5900 |fld     qword ptr [59BAF8]
00493C5C  |.  E8 3FE20B00   |call    00551EA0                        ;  JASS: _CIpow
00493C61  |.  DC4C24 18     |fmul    qword ptr [esp+18]
00493C65  |.  E8 42CD0B00   |call    005509AC
00493C6A  |.  DD4424 28     |fld     qword ptr [esp+28]
00493C6E  |.  D9FE          |fsin
00493C70  |.  8BD8          |mov     ebx, eax
00493C72  |.  E8 35CD0B00   |call    005509AC
00493C77  |.  DD4424 28     |fld     qword ptr [esp+28]
00493C7B  |.  03D8          |add     ebx, eax
00493C7D  |.  8BC6          |mov     eax, esi
00493C7F  |.  0FAFC5        |imul    eax, ebp
00493C82  |.  D9FA          |fsqrt
00493C84  |.  B9 A0860100   |mov     ecx, 186A0
00493C89  |.  0FAFC7        |imul    eax, edi
00493C8C  |.  03C3          |add     eax, ebx
00493C8E  |.  99            |cdq
00493C8F  |.  F7F9          |idiv    ecx
00493C91  |.  8BEA          |mov     ebp, edx                        ;  JASS-DEBUG: ebp - IterValB
00493C93  |.  E8 14CD0B00   |call    005509AC
00493C98  |.  8BD5          |mov     edx, ebp
00493C9A  |.  8B4C24 10     |mov     ecx, dword ptr [esp+10]
00493C9E  |.  0FAFD5        |imul    edx, ebp
00493CA1  |.  03D1          |add     edx, ecx
00493CA3  |.  B9 A0860100   |mov     ecx, 186A0
00493CA8  |.  0FAFD6        |imul    edx, esi
00493CAB  |.  0FAFD6        |imul    edx, esi
00493CAE  |.  0FAFD7        |imul    edx, edi
00493CB1  |.  03C2          |add     eax, edx
00493CB3  |.  99            |cdq
00493CB4  |.  F7F9          |idiv    ecx                             ;  JASS-DEBUG: edx - IterValC (除法之后)
00493CB6  |.  8B4424 20     |mov     eax, dword ptr [esp+20]
00493CBA  |.  46            |inc     esi
00493CBB  |.  3BF0          |cmp     esi, eax
00493CBD  |.  897424 18     |mov     dword ptr [esp+18], esi
00493CC1  |.^ 0F8E 1CFFFFFF \jle     00493BE3
00493CC7  |.  8B5C24 10     mov     ebx, dword ptr [esp+10]          ;  JASS: 生成的整数:dword ptr [esp+10],ebp,edx
00493CCB  |>  33C0          xor     eax, eax
00493CCD  |>  8BC8          /mov     ecx, eax
00493CCF  |.  0FAFC8        |imul    ecx, eax
00493CD2  |.  0FAFC8        |imul    ecx, eax
00493CD5  |.  8D4C19 1F     |lea     ecx, dword ptr [ecx+ebx+1F]
00493CD9  |.  81E1 7F000080 |and     ecx, 8000007F
00493CDF  |.  79 05         |jns     short 00493CE6
00493CE1  |.  49            |dec     ecx
00493CE2  |.  83C9 80       |or      ecx, FFFFFF80
00493CE5  |.  41            |inc     ecx
00493CE6  |>  884C04 30     |mov     byte ptr [esp+eax+30], cl
00493CEA  |.  40            |inc     eax
00493CEB  |.  83F8 05       |cmp     eax, 5
00493CEE  |.^ 7C DD         \jl      short 00493CCD
00493CF0  |.  B8 05000000   mov     eax, 5
00493CF5  |>  8BC8          /mov     ecx, eax
00493CF7  |.  0FAFC8        |imul    ecx, eax
00493CFA  |.  0FAFC8        |imul    ecx, eax
00493CFD  |.  8D4C29 1F     |lea     ecx, dword ptr [ecx+ebp+1F]
00493D01  |.  81E1 7F000080 |and     ecx, 8000007F
00493D07  |.  79 05         |jns     short 00493D0E
00493D09  |.  49            |dec     ecx
00493D0A  |.  83C9 80       |or      ecx, FFFFFF80
00493D0D  |.  41            |inc     ecx
00493D0E  |>  884C04 30     |mov     byte ptr [esp+eax+30], cl
00493D12  |.  40            |inc     eax
00493D13  |.  83F8 0A       |cmp     eax, 0A
00493D16  |.^ 7C DD         \jl      short 00493CF5
00493D18  |.  B8 0A000000   mov     eax, 0A
00493D1D  |>  8BC8          /mov     ecx, eax
00493D1F  |.  0FAFC8        |imul    ecx, eax
00493D22  |.  0FAFC8        |imul    ecx, eax
00493D25  |.  8D4C11 1F     |lea     ecx, dword ptr [ecx+edx+1F]
00493D29  |.  81E1 7F000080 |and     ecx, 8000007F
00493D2F  |.  79 05         |jns     short 00493D36
00493D31  |.  49            |dec     ecx
00493D32  |.  83C9 80       |or      ecx, FFFFFF80
00493D35  |.  41            |inc     ecx
00493D36  |>  884C04 30     |mov     byte ptr [esp+eax+30], cl
00493D3A  |.  40            |inc     eax
00493D3B  |.  83F8 0F       |cmp     eax, 0F
00493D3E  |.^ 7C DD         \jl      short 00493D1D
00493D40  |.  33D2          xor     edx, edx
00493D42  |.  C64424 3F 00  mov     byte ptr [esp+3F], 0
00493D47  |.  33C9          xor     ecx, ecx
00493D49  |>  8A4414 30     /mov     al, byte ptr [esp+edx+30]
00493D4D  |.  3C 30         |cmp     al, 30
00493D4F  |.  7C 04         |jl      short 00493D55
00493D51  |.  3C 39         |cmp     al, 39
00493D53  |.  7E 29         |jle     short 00493D7E
00493D55  |>  3C 41         |cmp     al, 41
00493D57  |.  7C 04         |jl      short 00493D5D
00493D59  |.  3C 5A         |cmp     al, 5A
00493D5B  |.  7E 21         |jle     short 00493D7E
00493D5D  |>  3C 61         |cmp     al, 61
00493D5F  |.  7C 04         |jl      short 00493D65
00493D61  |.  3C 7A         |cmp     al, 7A
00493D63  |.  7E 19         |jle     short 00493D7E
00493D65  |>  0FBEC0        |movsx   eax, al
00493D68  |.  8D4408 1F     |lea     eax, dword ptr [eax+ecx+1F]
00493D6C  |.  25 7F000080   |and     eax, 8000007F
00493D71  |.  79 05         |jns     short 00493D78
00493D73  |.  48            |dec     eax
00493D74  |.  83C8 80       |or      eax, FFFFFF80
00493D77  |.  40            |inc     eax
00493D78  |>  884414 30     |mov     byte ptr [esp+edx+30], al
00493D7C  |.^ EB CB         |jmp     short 00493D49
00493D7E  |>  83C1 07       |add     ecx, 7
00493D81  |.  42            |inc     edx
00493D82  |.  83F9 69       |cmp     ecx, 69
00493D85  |.^ 7C C2         \jl      short 00493D49
00493D87  |.  8D4C24 30     lea     ecx, dword ptr [esp+30]
00493D8B  |.  8D5424 14     lea     edx, dword ptr [esp+14]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493DE6  \.  C3            retn
 

返回跟踪函数004938D0(GenLv1_MacID_RegCode),同样通过搜索内存,找到很长的数字串是在中间一个循环之后(00493A85)生成的,这个循环里有sprintf和CString::+=的调用;跟踪发现此循环的作用是把一个24byte的数组的每个byte的十进制表示连接在一起,生成长数字串。
搜索那个24byte的数组,是在call 004055C0后生成的。进入分析这个函数004055C0,此函数调用前push的其中一个参数正是已知的计算机标识码。函数里有个大循环,循环里有一处函数调用。经过跟踪,在执行循环之前,15byte的计算机标识码加结束符\0共16byte被扩展成24byte的数组。循环每次对8个byte进行处理,结果覆盖该24byte数组并对下8byte处理有所影响。
代码:
//函数004055C0(GenLv2_MacID_24ByteArray)
004055C0  /$  51            push    ecx
004055C1  |.  53            push    ebx
004055C2  |.  8B5C24 14     mov     ebx, dword ptr [esp+14]
004055C6  |.  55            push    ebp
004055C7  |.  56            push    esi
004055C8  |.  8B7424 14     mov     esi, dword ptr [esp+14]
004055CC  |.  57            push    edi
004055CD  |.  8B7C24 1C     mov     edi, dword ptr [esp+1C]
004055D1  |.  8BC1          mov     eax, ecx
004055D3  |.  3BF7          cmp     esi, edi
004055D5  |.  894424 10     mov     dword ptr [esp+10], eax
004055D9  |.  74 10         je      short 004055EB
004055DB  |.  8BCB          mov     ecx, ebx
004055DD  |.  8BD1          mov     edx, ecx
004055DF  |.  C1E9 02       shr     ecx, 2
004055E2  |.  F3:A5         rep     movs dword ptr es:[edi], dword p>
004055E4  |.  8BCA          mov     ecx, edx
004055E6  |.  83E1 03       and     ecx, 3
004055E9  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr>
004055EB  |>  8B4C24 24     mov     ecx, dword ptr [esp+24]
004055EF  |.  51            push    ecx
004055F0  |.  53            push    ebx
004055F1  |.  8BC8          mov     ecx, eax
004055F3  |.  E8 A8FFFFFF   call    004055A0
004055F8  |.  8BE8          mov     ebp, eax
004055FA  |.  8A4424 24     mov     al, byte ptr [esp+24]
004055FE  |.  A8 20         test    al, 20
00405600  |.  74 06         je      short 00405608
00405602  |.  8BC5          mov     eax, ebp
00405604  |.  2BC3          sub     eax, ebx
00405606  |.  EB 02         jmp     short 0040560A
00405608  |>  33C0          xor     eax, eax
0040560A  |>  8B7424 1C     mov     esi, dword ptr [esp+1C]
0040560E  |.  8BCD          mov     ecx, ebp
00405610  |.  2BCB          sub     ecx, ebx
00405612  |.  8D3C1E        lea     edi, dword ptr [esi+ebx]
00405615  |.  8AD8          mov     bl, al
00405617  |.  8AFB          mov     bh, bl
00405619  |.  8BD1          mov     edx, ecx
0040561B  |.  8BC3          mov     eax, ebx
0040561D  |.  C1E0 10       shl     eax, 10
00405620  |.  66:8BC3       mov     ax, bx
00405623  |.  C1E9 02       shr     ecx, 2
00405626  |.  F3:AB         rep     stos dword ptr es:[edi]
00405628  |.  8BCA          mov     ecx, edx
0040562A  |.  83E1 03       and     ecx, 3
0040562D  |.  F3:AA         rep     stos byte ptr es:[edi]
0040562F  |.  33C0          xor     eax, eax
00405631  |.  85ED          test    ebp, ebp
00405633  |.  0F86 D8000000 jbe     00405711
00405639  |.  8B4424 24     mov     eax, dword ptr [esp+24]
0040563D  |.  83C5 07       add     ebp, 7
00405640  |.  83E0 02       and     eax, 2
00405643  |.  83C6 06       add     esi, 6
00405646  |.  C1ED 03       shr     ebp, 3
00405649  |.  894424 1C     mov     dword ptr [esp+1C], eax
0040564D  |.  8D0CED 000000>lea     ecx, dword ptr [ebp*8]
00405654  |.  894C24 18     mov     dword ptr [esp+18], ecx
00405658  |.  EB 04         jmp     short 0040565E
0040565A  |>  8B4424 1C     /mov     eax, dword ptr [esp+1C]
0040565E  |>  85C0           test    eax, eax
00405660  |.  74 18         |je      short 0040567A
00405662  |.  8B5424 28     |mov     edx, dword ptr [esp+28]
00405666  |.  8B7E FA       |mov     edi, dword ptr [esi-6]
00405669  |.  8B4424 2C     |mov     eax, dword ptr [esp+2C]
0040566D  |.  33FA          |xor     edi, edx
0040566F  |.  897E FA       |mov     dword ptr [esi-6], edi
00405672  |.  8B4E FE       |mov     ecx, dword ptr [esi-2]
00405675  |.  33C8          |xor     ecx, eax
00405677  |.  894E FE       |mov     dword ptr [esi-2], ecx
0040567A  |>  8B46 FA       |mov     eax, dword ptr [esi-6]
0040567D  |.  8D7E FA       |lea     edi, dword ptr [esi-6]
00405680  |.  894424 24     |mov     dword ptr [esp+24], eax         ;  JASS: 32bit交换高低位
00405684  |.  8D5E FE       |lea     ebx, dword ptr [esi-2]
00405687  |.  8A4C24 26     |mov     cl, byte ptr [esp+26]
0040568B  |.  8A5424 27     |mov     dl, byte ptr [esp+27]
0040568F  |.  8846 FD       |mov     byte ptr [esi-3], al
00405692  |.  8866 FC       |mov     byte ptr [esi-4], ah
00405695  |.  884E FB       |mov     byte ptr [esi-5], cl
00405698  |.  8817          |mov     byte ptr [edi], dl
0040569A  |.  8B03          |mov     eax, dword ptr [ebx]
0040569C  |.  53            |push    ebx
0040569D  |.  894424 28     |mov     dword ptr [esp+28], eax
004056A1  |.  8846 01       |mov     byte ptr [esi+1], al
004056A4  |.  8A4C24 2B     |mov     cl, byte ptr [esp+2B]
004056A8  |.  8A4424 2A     |mov     al, byte ptr [esp+2A]
004056AC  |.  880B          |mov     byte ptr [ebx], cl
004056AE  |.  8B4C24 14     |mov     ecx, dword ptr [esp+14]
004056B2  |.  57            |push    edi
004056B3  |.  8826          |mov     byte ptr [esi], ah
004056B5  |.  8846 FF       |mov     byte ptr [esi-1], al
004056B8  |.  E8 33F4FFFF   |call    00404AF0                        ;  JASS:把8字节“字符串”转换成二进制串
004056BD  |.  8B07          |mov     eax, dword ptr [edi]
004056BF  |.  894424 24     |mov     dword ptr [esp+24], eax
004056C3  |.  8846 FD       |mov     byte ptr [esi-3], al
004056C6  |.  8A5424 26     |mov     dl, byte ptr [esp+26]
004056CA  |.  8A4424 27     |mov     al, byte ptr [esp+27]
004056CE  |.  8866 FC       |mov     byte ptr [esi-4], ah
004056D1  |.  8856 FB       |mov     byte ptr [esi-5], dl
004056D4  |.  8807          |mov     byte ptr [edi], al
004056D6  |.  8B03          |mov     eax, dword ptr [ebx]
004056D8  |.  894424 24     |mov     dword ptr [esp+24], eax
004056DC  |.  8846 01       |mov     byte ptr [esi+1], al
004056DF  |.  8A4C24 26     |mov     cl, byte ptr [esp+26]
004056E3  |.  8A5424 27     |mov     dl, byte ptr [esp+27]
004056E7  |.  8826          |mov     byte ptr [esi], ah
004056E9  |.  8B4424 1C     |mov     eax, dword ptr [esp+1C]
004056ED  |.  85C0          |test    eax, eax
004056EF  |.  884E FF       |mov     byte ptr [esi-1], cl
004056F2  |.  8813          |mov     byte ptr [ebx], dl
004056F4  |.  74 0D         |je      short 00405703
004056F6  |.  8B07          |mov     eax, dword ptr [edi]
004056F8  |.  8B4F 04       |mov     ecx, dword ptr [edi+4]
004056FB  |.  894424 28     |mov     dword ptr [esp+28], eax
004056FF  |.  894C24 2C     |mov     dword ptr [esp+2C], ecx
00405703  |>  83C6 08       |add     esi, 8
00405706  |.  4D            |dec     ebp
00405707  |.^ 0F85 4DFFFFFF \jnz     0040565A
0040570D  |.  8B4424 18     mov     eax, dword ptr [esp+18]
00405711  |>  5F            pop     edi
00405712  |.  5E            pop     esi
00405713  |.  5D            pop     ebp
00405714  |.  5B            pop     ebx
00405715  |.  59            pop     ecx
00405716  \.  C2 1800       retn    18
 

循环中间的函数00404A4F很长但很有规律,里面没有更深层的函数调用,有很多异或运算。主要的运算就是分别对那8个byte的前4byte和后4byte进行异或迭代,其中还用到了一些“常量”数组加入异或运算。
代码:
//函数00404A4F(GenLv3_8ByteTrans)
00404AF0  /$  83EC 10       sub     esp, 10
00404AF3  |.  53            push    ebx
00404AF4  |.  55            push    ebp
00404AF5  |.  56            push    esi
00404AF6  |.  8B31          mov     esi, dword ptr [ecx]
00404AF8  |.  57            push    edi
00404AF9  |.  8B7C24 24     mov     edi, dword ptr [esp+24]          ;  JASS-DEBUG:ESP[24]0012CA7C
00404AFD  |.  8B2E          mov     ebp, dword ptr [esi]             ;  JASS-DEBUG:S[0]2A9BB267
00404AFF  |.  8B41 04       mov     eax, dword ptr [ecx+4]           ;  JASS-DEBUG:a
00404B02  |.  8B17          mov     edx, dword ptr [edi]             ;  JASS-DEBUG:[]32483758--首4字母
00404B04  |.  33D5          xor     edx, ebp                         ;  JASS-DEBUG:edx=(首4字母)^S[0]
00404B06  |.  895424 10     mov     dword ptr [esp+10], edx          ;  JASS-DEBUG:T[0]_1--下面用到的4个“行”指标
00404B0A  |.  8B5C24 13     mov     ebx, dword ptr [esp+13]          ;  JASS-DEBUG:b=T[0]_1:32
00404B0E  |.  8B4C24 12     mov     ecx, dword ptr [esp+12]          ;  JASS-DEBUG:c=T[0]_1:24
00404B12  |.  81E3 FF000000 and     ebx, 0FF
00404B18  |.  81E1 FF000000 and     ecx, 0FF
00404B1E  |.  8B2C98        mov     ebp, dword ptr [eax+ebx*4]       ;  JASS-DEBUG:A[a+b*4]
00404B21  |.  8B5C24 11     mov     ebx, dword ptr [esp+11]          ;  JASS-DEBUG:f=T[0]_1:16
00404B25  |.  8B8C88 000400>mov     ecx, dword ptr [eax+ecx*4+400]   ;  JASS-DEBUG:B[a+c*4]
00404B2C  |.  81E3 FF000000 and     ebx, 0FF
00404B32  |.  03CD          add     ecx, ebp
00404B34  |.  8BAC98 000800>mov     ebp, dword ptr [eax+ebx*4+800]   ;  JASS-DEBUG:C[a+f*4]
00404B3B  |.  8BDA          mov     ebx, edx
00404B3D  |.  81E3 FF000000 and     ebx, 0FF                         ;  JASS-DEBUG:i=T[0]_1:8
00404B43  |.  33CD          xor     ecx, ebp
00404B45  |.  8BAC98 000C00>mov     ebp, dword ptr [eax+ebx*4+C00]   ;  JASS-DEBUG:D[a+i*4]
00404B4C  |.  8B5E 04       mov     ebx, dword ptr [esi+4]           ;  JASS-DEBUG:S[1]A5125437
00404B4F  |.  03CD          add     ecx, ebp
00404B51  |.  33CB          xor     ecx, ebx                         ;  JASS-DEBUG: ecx = ((A+B)^C+D)^S
00404B53  |.  8B5C24 28     mov     ebx, dword ptr [esp+28]          ;  JASS-DEBUG:ESP[28]
00404B57  |.  330B          xor     ecx, dword ptr [ebx]             ;  JASS-DEBUG:[]4652564C--次4字母
00404B59  |.  894C24 18     mov     dword ptr [esp+18], ecx          ;  JASS-DEBUG:T[1]_1=(次4字母)^ecx(ABCDS_1)
00404B5D  |.  8B5C24 1A     mov     ebx, dword ptr [esp+1A]
00404B61  |.  8B6C24 1B     mov     ebp, dword ptr [esp+1B]
00404B65  |.  81E3 FF000000 and     ebx, 0FF
00404B6B  |.  81E5 FF000000 and     ebp, 0FF
00404B71  |.  8B9C98 000400>mov     ebx, dword ptr [eax+ebx*4+400]   ;  JASS-DEBUG:B[]
00404B78  |.  031CA8        add     ebx, dword ptr [eax+ebp*4]       ;  JASS-DEBUG:A[]
00404B7B  |.  8B6C24 19     mov     ebp, dword ptr [esp+19]
00404B7F  |.  81E5 FF000000 and     ebp, 0FF
00404B85  |.  339CA8 000800>xor     ebx, dword ptr [eax+ebp*4+800]   ;  JASS-DEBUG:C[]
00404B8C  |.  8BE9          mov     ebp, ecx
00404B8E  |.  81E5 FF000000 and     ebp, 0FF
00404B94  |.  039CA8 000C00>add     ebx, dword ptr [eax+ebp*4+C00]   ;  JASS-DEBUG:D[]
00404B9B  |.  8B6E 08       mov     ebp, dword ptr [esi+8]           ;  JASS-DEBUG:S[2]41772F25
00404B9E  |.  33DD          xor     ebx, ebp                         ;  JASS-DEBUG: ebx = ((A+B)^C+D)^S
00404BA0  |.  33D3          xor     edx, ebx                         ;  JASS-DEBUG: edx = (首4字母)^S[0]^ebx
00404BA2  |.  895424 10     mov     dword ptr [esp+10], edx          ;  JASS-DEBUG:T[0]_2=T[0]_1^ABCDS_2
00404BA6  |.  8B5C24 12     mov     ebx, dword ptr [esp+12]
00404BAA  |.  8B6C24 13     mov     ebp, dword ptr [esp+13]
00404BAE  |.  81E3 FF000000 and     ebx, 0FF
00404BB4  |.  81E5 FF000000 and     ebp, 0FF
00404BBA  |.  8B9C98 000400>mov     ebx, dword ptr [eax+ebx*4+400]
00404BC1  |.  031CA8        add     ebx, dword ptr [eax+ebp*4]
00404BC4  |.  8B6C24 11     mov     ebp, dword ptr [esp+11]
00404BC8  |.  81E5 FF000000 and     ebp, 0FF
00404BCE  |.  339CA8 000800>xor     ebx, dword ptr [eax+ebp*4+800]
00404BD5  |.  8BEA          mov     ebp, edx
00404BD7  |.  81E5 FF000000 and     ebp, 0FF
00404BDD  |.  039CA8 000C00>add     ebx, dword ptr [eax+ebp*4+C00]
00404BE4  |.  8B6E 0C       mov     ebp, dword ptr [esi+C]
00404BE7  |.  33DD          xor     ebx, ebp
00404BE9  |.  33CB          xor     ecx, ebx
00404BEB  |.  894C24 18     mov     dword ptr [esp+18], ecx          ;  JASS-DEBUG:T[1]_2=T[1]_1^ABCDS_3
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00404F57  |.  894C24 18     mov     dword ptr [esp+18], ecx          ;  JASS-DEBUG:  15
00404F5B  |.  8B5C24 1A     mov     ebx, dword ptr [esp+1A]
00404F5F  |.  8B6C24 1B     mov     ebp, dword ptr [esp+1B]
00404F63  |.  81E3 FF000000 and     ebx, 0FF
00404F69  |.  81E5 FF000000 and     ebp, 0FF
00404F6F  |.  8B9C98 000400>mov     ebx, dword ptr [eax+ebx*4+400]
00404F76  |.  031CA8        add     ebx, dword ptr [eax+ebp*4]
00404F79  |.  8B6C24 19     mov     ebp, dword ptr [esp+19]
00404F7D  |.  81E5 FF000000 and     ebp, 0FF
00404F83  |.  339CA8 000800>xor     ebx, dword ptr [eax+ebp*4+800]
00404F8A  |.  8BE9          mov     ebp, ecx
00404F8C  |.  81E5 FF000000 and     ebp, 0FF
00404F92  |.  039CA8 000C00>add     ebx, dword ptr [eax+ebp*4+C00]
00404F99  |.  8B46 40       mov     eax, dword ptr [esi+40]          ;  JASS-DEBUG:S[16]
00404F9C  |.  33D8          xor     ebx, eax                         ;  JASS-DEBUG:ABCDS_16
00404F9E  |.  8B46 44       mov     eax, dword ptr [esi+44]          ;  JASS-DEBUG:S[17]
00404FA1  |.  33D3          xor     edx, ebx                         ;  JASS-DEBUG:edx = T[0]_8^ABCDS_16
00404FA3  |.  33C8          xor     ecx, eax                         ;  JASS-DEBUG:ecx = T[1]_8^S[17]
00404FA5  |.  8B4424 28     mov     eax, dword ptr [esp+28]
00404FA9  |.  8910          mov     dword ptr [eax], edx
00404FAB  |.  890F          mov     dword ptr [edi], ecx
00404FAD  |.  5F            pop     edi
00404FAE  |.  5E            pop     esi
00404FAF  |.  5D            pop     ebp
00404FB0  |.  5B            pop     ebx
00404FB1  |.  83C4 10       add     esp, 10
00404FB4  \.  C2 0800       retn    8
 

到这里,我可以总结出授权码大概的生成过程:

计算机标识码 
=> 
24byte扩展的计算机标识码 => 24byte数组       
=> 
数字ASCII码串 => 3个32位整数 => 15byte数组 => 大小写混杂的授权码 
=>                        
授权码  
        

似乎大功告成,只需把相应函数的算法整理出来,组合一下就可得授权码生成器。但如果换了另一台机子去尝试,会发现授权码是错的。原因是函数00404A4F用到的“常量”数组并非常量,是动态生成的。继续往前探索,终于发现这些数组是在call 00404A90之后生成的。函数00404A90首先动态分配了两块内存,然后调用00405490。
在函数00405490中,那两块内存的初始值分别来源于两个固定地址的内存(程序的数据段);之后有3个循环,从循环次数可以判断前两个是生成0x48byte的数组(简记为S),后一个生成0x1000byte的数组(简记为A)。第一个循环由一个15byte的中间字符串和S的初始值生成新的S值,第二第三个循环都调用了之前提到的00404A4F(GenLv3_8ByteTrans),相当于对自身数组作迭代更新。
代码:
//函数00405490(GenLv2_15MedStr_SA)
00405490  /$  83EC 08       sub     esp, 8
00405493  |.  33C0          xor     eax, eax
00405495  |.  53            push    ebx
00405496  |.  55            push    ebp
00405497  |.  56            push    esi
00405498  |.  57            push    edi
00405499  |.  8BF1          mov     esi, ecx
0040549B  |>  8B0E          /mov     ecx, dword ptr [esi]
0040549D  |.  8B90 20655E00 |mov     edx, dword ptr [eax+5E6520]
004054A3  |.  891408        |mov     dword ptr [eax+ecx], edx        ;  JASS-DEBUG: 复制内存
004054A6  |.  83C0 04       |add     eax, 4
004054A9  |.  83F8 48       |cmp     eax, 48
004054AC  |.^ 7C ED         \jl      short 0040549B
004054AE  |.  33C0          xor     eax, eax
004054B0  |>  B9 00010000   /mov     ecx, 100
004054B5  |>  8B56 04       |/mov     edx, dword ptr [esi+4]
004054B8  |.  8BB8 68655E00 ||mov     edi, dword ptr [eax+5E6568]
004054BE  |.  893C10        ||mov     dword ptr [eax+edx], edi       ;  JASS-DEBUG: 复制内存
004054C1  |.  83C0 04       ||add     eax, 4
004054C4  |.  49            ||dec     ecx
004054C5  |.^ 75 EE         |\jnz     short 004054B5
004054C7  |.  3D 00100000   |cmp     eax, 1000
004054CC  |.^ 7C E2         \jl      short 004054B0
004054CE  |.  8B7C24 20     mov     edi, dword ptr [esp+20]
004054D2  |.  8B5C24 1C     mov     ebx, dword ptr [esp+1C]
004054D6  |.  33C9          xor     ecx, ecx
004054D8  |.  33ED          xor     ebp, ebp
004054DA  |>  8BC1          /mov     eax, ecx
004054DC  |.  99            |cdq
004054DD  |.  F7FF          |idiv    edi
004054DF  |.  41            |inc     ecx
004054E0  |.  8A041A        |mov     al, byte ptr [edx+ebx]
004054E3  |.  884424 23     |mov     byte ptr [esp+23], al
004054E7  |.  8BC1          |mov     eax, ecx
004054E9  |.  99            |cdq
004054EA  |.  F7FF          |idiv    edi
004054EC  |.  41            |inc     ecx
004054ED  |.  8BC1          |mov     eax, ecx
004054EF  |.  8A141A        |mov     dl, byte ptr [edx+ebx]
004054F2  |.  885424 22     |mov     byte ptr [esp+22], dl
004054F6  |.  99            |cdq
004054F7  |.  F7FF          |idiv    edi
004054F9  |.  41            |inc     ecx
004054FA  |.  8A041A        |mov     al, byte ptr [edx+ebx]
004054FD  |.  884424 21     |mov     byte ptr [esp+21], al
00405501  |.  8BC1          |mov     eax, ecx
00405503  |.  99            |cdq
00405504  |.  F7FF          |idiv    edi
00405506  |.  8B06          |mov     eax, dword ptr [esi]
00405508  |.  41            |inc     ecx
00405509  |.  03C5          |add     eax, ebp
0040550B  |.  83C5 04       |add     ebp, 4
0040550E  |.  8A141A        |mov     dl, byte ptr [edx+ebx]
00405511  |.  885424 20     |mov     byte ptr [esp+20], dl
00405515  |.  8B5424 20     |mov     edx, dword ptr [esp+20]
00405519  |.  3110          |xor     dword ptr [eax], edx
0040551B  |.  83FD 48       |cmp     ebp, 48
0040551E  |.^ 7C BA         \jl      short 004054DA
00405520  |.  33FF          xor     edi, edi
00405522  |.  897C24 14     mov     dword ptr [esp+14], edi
00405526  |.  897C24 10     mov     dword ptr [esp+10], edi
0040552A  |>  8D4424 14     /lea     eax, dword ptr [esp+14]
0040552E  |.  8D4C24 10     |lea     ecx, dword ptr [esp+10]
00405532  |.  50            |push    eax
00405533  |.  51            |push    ecx
00405534  |.  8BCE          |mov     ecx, esi
00405536  |.  E8 B5F5FFFF   |call    00404AF0
0040553B  |.  8B16          |mov     edx, dword ptr [esi]
0040553D  |.  8B4424 10     |mov     eax, dword ptr [esp+10]
00405541  |.  890417        |mov     dword ptr [edi+edx], eax
00405544  |.  8B0E          |mov     ecx, dword ptr [esi]
00405546  |.  8B5424 14     |mov     edx, dword ptr [esp+14]
0040554A  |.  89540F 04     |mov     dword ptr [edi+ecx+4], edx
0040554E  |.  83C7 08       |add     edi, 8
00405551  |.  83FF 48       |cmp     edi, 48
00405554  |.^ 7C D4         \jl      short 0040552A
00405556  |.  BF 04000000   mov     edi, 4
0040555B  |>  BB 80000000   /mov     ebx, 80
00405560  |>  8D4424 14     |/lea     eax, dword ptr [esp+14]
00405564  |.  8D4C24 10     ||lea     ecx, dword ptr [esp+10]
00405568  |.  50            ||push    eax
00405569  |.  51            ||push    ecx
0040556A  |.  8BCE          ||mov     ecx, esi
0040556C  |.  E8 7FF5FFFF   ||call    00404AF0
00405571  |.  8B56 04       ||mov     edx, dword ptr [esi+4]
00405574  |.  8B4424 10     ||mov     eax, dword ptr [esp+10]
00405578  |.  894417 FC     ||mov     dword ptr [edi+edx-4], eax
0040557C  |.  8B4E 04       ||mov     ecx, dword ptr [esi+4]
0040557F  |.  8B5424 14     ||mov     edx, dword ptr [esp+14]
00405583  |.  89140F        ||mov     dword ptr [edi+ecx], edx
00405586  |.  83C7 08       ||add     edi, 8
00405589  |.  4B            ||dec     ebx
0040558A  |.^ 75 D4         |\jnz     short 00405560
0040558C  |.  81FF 04100000 |cmp     edi, 1004
00405592  |.^ 7C C7         \jl      short 0040555B
00405594  |.  5F            pop     edi
00405595  |.  5E            pop     esi
00405596  |.  5D            pop     ebp
00405597  |.  5B            pop     ebx
00405598  |.  83C4 08       add     esp, 8
0040559B  \.  C2 0800       retn    8
 

继续往前找那个15byte的中间字符串的来源。在call 00493B60之后这个字符串出现了。函数00493B60(GenLv2_NumStr_RegCodeCI)正是之前分析过的由数字ASCII码串生成大小写混杂的授权码的函数,这回的输入字符串正是计算机标识符,输出是
15byte的中间字符串。

因此,函数00404A4F(GenLv3_8ByteTrans)(*)所用到的“常量”数组是由计算机标识符和真正的常量数组生成。为了验证这是否常量数组,可以在不同的机器上观察该地址的内存是否一致。

下一步可以整理算法。我选择把算法用c/c++重写,下面是一些重要的计算过程:

//由计算机标识码生成24byte数组,其中用到数组A、S
int Algo_004055C0(unsigned char * _src, int _src_len,  int _res_len);
//由24byte数组生成数字ASCII码串
string Algo_00493A3F(const unsigned char * _src, int _size);
//由数字ASCII码串生成大小写混杂的授权码
//由计算机标识码生成15byte中间字符串
int Algo_00493B60(string & _str);
//由15byte中间字符串和内存中的常量数组生成数组A、S
int Algo_00405490(const unsigned char * _src, unsigned int * _dst, int _dst_len);
//由扩展的计算机标识码生成24byte数组的中间步骤
//数组A、S迭代更新的中间步骤
int Algo_00404AF0(unsigned int & _higher, unsigned int & _lower);


程序在6台机器及2台虚拟机上测试,其中有1台机器授权码不对,可能有些细节我还分析得不对-_-b

后记:
  注册机做出来后,我上网搜索了一下别人对Feiq授权码的破解,只找到有人做过内存注册机,没找到有人分析它的生成算法,有点失望,不过我不懂内存注册机,正好可以学习研究下,有空也做个锻炼下。

心得体会:
  1.跟踪分析时注释很重要,就像是在迷宫中作记号。希望大牛们可以分享下注释的技巧等等。
  2.通过不断搜索内存来找到生成目标的函数。当然,我觉得应该还有更好方法,又或者是写个脚本之类,好减少重复劳动,还请大家指点了。
  3.分析函数时可以先忽略计算的细节,先找出输入和输出。
  4.用C等重写算法时,最好不要“一气呵成”,按照汇编的函数组织层次和逻辑结构分成几个层次几个函数,这样可以方便调试测试。此外,听说可以直接把汇编代码拷出来用,不用花力气分析算法,不知道具体咋操作,是在OD弄还是在IDA弄比较方便?
  5.初学者分析下算法还是有好处的,我觉得我对汇编的恐惧感又减少了。
  6.现在的工具很好很强大,要好好熟悉,充分利用。

附源码
上传的附件 FeiqRankReg.rar