首页
论坛
课程
招聘
[原创]Power Copy 1.92 算法分析及 VC 算法注册机
2010-12-18 22:09 3646

[原创]Power Copy 1.92 算法分析及 VC 算法注册机

2010-12-18 22:09
3646
【破文标题】Power Copy 1.92 算法分析及 VC 算法注册机
【破文作者】zaas[PYG]
【破解工具】OllyICE,PEiD v0.94
【破解平台】WinXP
【软件授权】:共享版
【软件介绍】:对于坏的软盘或光碟中的数据进行强制复制解码,取代Windows中自带拷贝工具。使您真正拥有强大稳定无敌的拷贝工具。
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享
--------------------------------------------------------------
【破解内容】
查找字符串,有:
地址=0040B36E
反汇编=push    0044112C
文本字符串=Software\Youtica\Power Copy
双击跟进,猜想一下。
0040B36E  |.  68 2C114400   push    0044112C                         ;  Software\Youtica\Power Copy
0040B373  |.  E8 E869FFFF   call    00401D60
0040B378  |.  8945 BC       mov     dword ptr [ebp-44], eax
0040B37B  |.  E8 00EBFFFF   call    00409E80                         ;  关键call
0040B380  |.  83C4 0C       add     esp, 0C
0040B383  |.  8845 BB       mov     byte ptr [ebp-45], al            ;  标志位
0040B386  |.  0FB655 BB     movzx   edx, byte ptr [ebp-45]
0040B38A  |.  85D2          test    edx, edx
0040B38C  |.  74 78         je      short 0040B406                   ;  跳向死亡
0040B38E  |.  51            push    ecx
0040B38F  |.  8BCC          mov     ecx, esp
0040B391  |.  8965 D4       mov     dword ptr [ebp-2C], esp
0040B394  |.  68 2C114400   push    0044112C                         ;  Software\Youtica\Power Copy
0040B399  |.  E8 C269FFFF   call    00401D60                         ;  写入注册表
0040B39E  |.  8945 B4       mov     dword ptr [ebp-4C], eax

跟进关键call,核心算法很容易找到。
00409F03  |.  E8 88010000   call    0040A090                         ;  算法call
00409F08  |.  8845 9F       mov     byte ptr [ebp-61], al            ;  标志位出来了

跟进 call    0040A090,大致一看,就像是算法,下断跟跟。程序settimer了,频繁断下,不怕。
0040A090  /$  55            push    ebp
0040A091  |.  8BEC          mov     ebp, esp
0040A093  |.  6A FF         push    -1
0040A095  |.  68 88D34300   push    0043D388
0040A09A  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
0040A0A0  |.  50            push    eax
0040A0A1  |.  83EC 7C       sub     esp, 7C
0040A0A4  |.  56            push    esi
0040A0A5  |.  A1 ECBC4400   mov     eax, dword ptr [44BCEC]
0040A0AA  |.  33C5          xor     eax, ebp
0040A0AC  |.  50            push    eax
0040A0AD  |.  8D45 F4       lea     eax, dword ptr [ebp-C]
0040A0B0  |.  64:A3 0000000>mov     dword ptr fs:[0], eax
0040A0B6  |.  894D A0       mov     dword ptr [ebp-60], ecx          ;  密码表
0040A0B9  |.  C745 FC 00000>mov     dword ptr [ebp-4], 0
0040A0C0  |.  C645 F3 00    mov     byte ptr [ebp-D], 0
0040A0C4  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A0C7  |.  E8 14BBFFFF   call    00405BE0                         ;  转大写
0040A0CC  |.  51            push    ecx
0040A0CD  |.  8BCC          mov     ecx, esp
0040A0CF  |.  8965 B8       mov     dword ptr [ebp-48], esp
0040A0D2  |.  8D45 08       lea     eax, dword ptr [ebp+8]
0040A0D5  |.  50            push    eax
0040A0D6  |.  E8 357CFFFF   call    00401D10
0040A0DB  |.  8945 9C       mov     dword ptr [ebp-64], eax
0040A0DE  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]
0040A0E1  |.  E8 9A020000   call    0040A380                         ;  验证假码call
0040A0E6  |.  8845 9B       mov     byte ptr [ebp-65], al            ;  标志位
0040A0E9  |.  0FB64D 9B     movzx   ecx, byte ptr [ebp-65]
0040A0ED  |.  85C9          test    ecx, ecx
0040A0EF  |.  0F84 1B020000 je      0040A310                         ;  有一个不在就死翘翘。
0040A0F5  |.  6A 08         push    8                                ;  假码第9位
0040A0F7  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A0FA  |.  E8 F1A2FFFF   call    004043F0                         ;  取得
0040A0FF  |.  0FB7D0        movzx   edx, ax
0040A102  |.  52            push    edx
0040A103  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]
0040A106  |.  E8 55050000   call    0040A660                         ;  在密码表中的位置
0040A10B  |.  8945 DC       mov     dword ptr [ebp-24], eax          ;  保存为S
0040A10E  |.  6A 07         push    7
0040A110  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A113  |.  E8 D8A2FFFF   call    004043F0                         ;  假码第8位
0040A118  |.  0FB7C0        movzx   eax, ax
0040A11B  |.  50            push    eax
0040A11C  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]
0040A11F  |.  E8 3C050000   call    0040A660                         ;  在密码表中的位置
0040A124  |.  99            cdq
0040A125  |.  B9 05000000   mov     ecx, 5
0040A12A  |.  F7F9          idiv    ecx                              ;  %5
0040A12C  |.  8955 E8       mov     dword ptr [ebp-18], edx          ;  保存余数a
0040A12F  |.  6A 09         push    9                                ;  假码第10位
0040A131  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A134  |.  E8 B7A2FFFF   call    004043F0
0040A139  |.  0FB7D0        movzx   edx, ax
0040A13C  |.  52            push    edx
0040A13D  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]
0040A140  |.  E8 1B050000   call    0040A660                         ;  在密码表中的位置
0040A145  |.  99            cdq
0040A146  |.  B9 05000000   mov     ecx, 5
0040A14B  |.  F7F9          idiv    ecx                              ;  %5
0040A14D  |.  8955 D8       mov     dword ptr [ebp-28], edx          ;  保存余数b
0040A150  |.  8D4D E0       lea     ecx, dword ptr [ebp-20]
0040A153  |.  E8 987BFFFF   call    00401CF0
0040A158  |.  C645 FC 01    mov     byte ptr [ebp-4], 1
0040A15C  |.  C745 D0 00000>mov     dword ptr [ebp-30], 0
0040A163  |.  EB 09         jmp     short 0040A16E
0040A165  |>  8B55 D0       /mov     edx, dword ptr [ebp-30]
0040A168  |.  83C2 01       |add     edx, 1
0040A16B  |.  8955 D0       |mov     dword ptr [ebp-30], edx
0040A16E  |>  837D D0 07     cmp     dword ptr [ebp-30], 7
0040A172  |.  7D 3A         |jge     short 0040A1AE
0040A174  |.  8B45 E8       |mov     eax, dword ptr [ebp-18]
0040A177  |.  3B45 D0       |cmp     eax, dword ptr [ebp-30]
0040A17A  |.  75 12         |jnz     short 0040A18E
0040A17C  |.  8B4D D0       |mov     ecx, dword ptr [ebp-30]
0040A17F  |.  51            |push    ecx
0040A180  |.  8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A183  |.  E8 68A2FFFF   |call    004043F0
0040A188  |.  66:8945 EC    |mov     word ptr [ebp-14], ax
0040A18C  |.  EB 1E         |jmp     short 0040A1AC
0040A18E  |>  837D D0 05    |cmp     dword ptr [ebp-30], 5
0040A192  |.  74 18         |je      short 0040A1AC
0040A194  |.  8B55 D0       |mov     edx, dword ptr [ebp-30]
0040A197  |.  52            |push    edx
0040A198  |.  8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A19B  |.  E8 50A2FFFF   |call    004043F0
0040A1A0  |.  0FB7C0        |movzx   eax, ax
0040A1A3  |.  50            |push    eax
0040A1A4  |.  8D4D E0       |lea     ecx, dword ptr [ebp-20]
0040A1A7  |.  E8 94010000   |call    0040A340
0040A1AC  |>^ EB B7         \jmp     short 0040A165                  ;  这段去掉假码前6位中位置为余数a的那位,保存为新字符串StrA
0040A1AE  |>  8D4D D4       lea     ecx, dword ptr [ebp-2C]
0040A1B1  |.  E8 3A7BFFFF   call    00401CF0
0040A1B6  |.  C645 FC 02    mov     byte ptr [ebp-4], 2
0040A1BA  |.  C745 CC 00000>mov     dword ptr [ebp-34], 0
0040A1C1  |.  EB 09         jmp     short 0040A1CC
0040A1C3  |>  8B4D CC       /mov     ecx, dword ptr [ebp-34]
0040A1C6  |.  83C1 01       |add     ecx, 1
0040A1C9  |.  894D CC       |mov     dword ptr [ebp-34], ecx
0040A1CC  |>  837D CC 07     cmp     dword ptr [ebp-34], 7
0040A1D0  |.  7D 45         |jge     short 0040A217
0040A1D2  |.  BA 10000000   |mov     edx, 10
0040A1D7  |.  2B55 CC       |sub     edx, dword ptr [ebp-34]
0040A1DA  |.  8955 C8       |mov     dword ptr [ebp-38], edx
0040A1DD  |.  8B45 D8       |mov     eax, dword ptr [ebp-28]
0040A1E0  |.  3B45 CC       |cmp     eax, dword ptr [ebp-34]
0040A1E3  |.  75 12         |jnz     short 0040A1F7
0040A1E5  |.  8B4D C8       |mov     ecx, dword ptr [ebp-38]
0040A1E8  |.  51            |push    ecx
0040A1E9  |.  8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A1EC  |.  E8 FFA1FFFF   |call    004043F0
0040A1F1  |.  66:8945 E4    |mov     word ptr [ebp-1C], ax
0040A1F5  |.  EB 1E         |jmp     short 0040A215
0040A1F7  |>  837D CC 05    |cmp     dword ptr [ebp-34], 5
0040A1FB  |.  74 18         |je      short 0040A215
0040A1FD  |.  8B55 C8       |mov     edx, dword ptr [ebp-38]
0040A200  |.  52            |push    edx
0040A201  |.  8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A204  |.  E8 E7A1FFFF   |call    004043F0
0040A209  |.  0FB7C0        |movzx   eax, ax
0040A20C  |.  50            |push    eax
0040A20D  |.  8D4D D4       |lea     ecx, dword ptr [ebp-2C]
0040A210  |.  E8 2B010000   |call    0040A340
0040A215  |>^ EB AC         \jmp     short 0040A1C3                  ;  这段去掉假码末6位中位置为余数b的那位,倒序保存为新字符串StrB
0040A217  |>  0FB775 EC     movzx   esi, word ptr [ebp-14]
0040A21B  |.  0FB74D 0C     movzx   ecx, word ptr [ebp+C]
0040A21F  |.  51            push    ecx
0040A220  |.  51            push    ecx
0040A221  |.  8BCC          mov     ecx, esp
0040A223  |.  8965 B4       mov     dword ptr [ebp-4C], esp
0040A226  |.  8D55 E0       lea     edx, dword ptr [ebp-20]
0040A229  |.  52            push    edx
0040A22A  |.  E8 E17AFFFF   call    00401D10
0040A22F  |.  8945 94       mov     dword ptr [ebp-6C], eax          ;  StrA
0040A232  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]          ;  密码表
0040A235  |.  E8 56050000   call    0040A790                         ;  算法一
0040A23A  |.  66:8945 92    mov     word ptr [ebp-6E], ax            ;  返回值
0040A23E  |.  0FB745 92     movzx   eax, word ptr [ebp-6E]
0040A242  |.  3BF0          cmp     esi, eax                         ;  和余数a去掉的那一位的ascii比较
0040A244  |.  0F85 AE000000 jnz     0040A2F8                         ;  跳则死
0040A24A  |.  0FB775 E4     movzx   esi, word ptr [ebp-1C]
0040A24E  |.  0FB74D 10     movzx   ecx, word ptr [ebp+10]
0040A252  |.  51            push    ecx
0040A253  |.  51            push    ecx
0040A254  |.  8BCC          mov     ecx, esp
0040A256  |.  8965 B0       mov     dword ptr [ebp-50], esp
0040A259  |.  8D55 D4       lea     edx, dword ptr [ebp-2C]
0040A25C  |.  52            push    edx
0040A25D  |.  E8 AE7AFFFF   call    00401D10
0040A262  |.  8945 8C       mov     dword ptr [ebp-74], eax          ;  StrB
0040A265  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]          ;  密码表
0040A268  |.  E8 23050000   call    0040A790                         ;  算法二
0040A26D  |.  66:8945 8A    mov     word ptr [ebp-76], ax            ;  返回值
0040A271  |.  0FB745 8A     movzx   eax, word ptr [ebp-76]
0040A275  |.  3BF0          cmp     esi, eax                         ;  和余数a去掉的那一位的ascii比较
0040A277  |.  75 7F         jnz     short 0040A2F8                   ;  跳则死
0040A279  |.  6A 05         push    5
0040A27B  |.  83EC 08       sub     esp, 8
0040A27E  |.  DD05 68114400 fld     qword ptr [441168]               ;  24
0040A284  |.  DD1C24        fstp    qword ptr [esp]
0040A287  |.  E8 D4000000   call    0040A360                         ;  24的5次方
0040A28C  |.  83C4 0C       add     esp, 0C
0040A28F  |.  E8 8C4E0200   call    0042F120                         ;  =798000
0040A294  |.  8945 C0       mov     dword ptr [ebp-40], eax
0040A297  |.  51            push    ecx
0040A298  |.  8BCC          mov     ecx, esp
0040A29A  |.  8965 AC       mov     dword ptr [ebp-54], esp
0040A29D  |.  8D55 E0       lea     edx, dword ptr [ebp-20]
0040A2A0  |.  52            push    edx
0040A2A1  |.  E8 6A7AFFFF   call    00401D10
0040A2A6  |.  8945 84       mov     dword ptr [ebp-7C], eax
0040A2A9  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]
0040A2AC  |.  E8 FF030000   call    0040A6B0                         ;  算法三
0040A2B1  |.  8945 80       mov     dword ptr [ebp-80], eax          ;  结果A
0040A2B4  |.  8B45 80       mov     eax, dword ptr [ebp-80]
0040A2B7  |.  8945 C4       mov     dword ptr [ebp-3C], eax
0040A2BA  |.  51            push    ecx
0040A2BB  |.  8BCC          mov     ecx, esp
0040A2BD  |.  8965 A8       mov     dword ptr [ebp-58], esp
0040A2C0  |.  8D55 D4       lea     edx, dword ptr [ebp-2C]
0040A2C3  |.  52            push    edx
0040A2C4  |.  E8 477AFFFF   call    00401D10
0040A2C9  |.  8985 7CFFFFFF mov     dword ptr [ebp-84], eax
0040A2CF  |.  8B4D A0       mov     ecx, dword ptr [ebp-60]
0040A2D2  |.  E8 D9030000   call    0040A6B0                         ;  算法四
0040A2D7  |.  8985 78FFFFFF mov     dword ptr [ebp-88], eax          ;  结果B
0040A2DD  |.  8B85 78FFFFFF mov     eax, dword ptr [ebp-88]
0040A2E3  |.  8945 BC       mov     dword ptr [ebp-44], eax
0040A2E6  |.  8B4D C4       mov     ecx, dword ptr [ebp-3C]
0040A2E9  |.  034D DC       add     ecx, dword ptr [ebp-24]          ;  结果A+结果B+S
0040A2EC  |.  034D BC       add     ecx, dword ptr [ebp-44]
0040A2EF  |.  394D C0       cmp     dword ptr [ebp-40], ecx          ;  和0x798000比较
0040A2F2  |.  75 04         jnz     short 0040A2F8                   ;  不等则死
0040A2F4  |.  C645 F3 01    mov     byte ptr [ebp-D], 1              ;  设置标志位[ebp-D]
0040A2F8  |>  C645 FC 01    mov     byte ptr [ebp-4], 1
0040A2FC  |.  8D4D D4       lea     ecx, dword ptr [ebp-2C]
0040A2FF  |.  E8 AC84FFFF   call    004027B0
0040A304  |.  C645 FC 00    mov     byte ptr [ebp-4], 0
0040A308  |.  8D4D E0       lea     ecx, dword ptr [ebp-20]
0040A30B  |.  E8 A084FFFF   call    004027B0
0040A310  |>  8A55 F3       mov     dl, byte ptr [ebp-D]             ;  取出标志位[ebp-D],爆破点
0040A313  |.  8855 A7       mov     byte ptr [ebp-59], dl            ;  另存
0040A316  |.  C745 FC FFFFF>mov     dword ptr [ebp-4], -1
0040A31D  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A320  |.  E8 8B84FFFF   call    004027B0
0040A325  |.  8A45 A7       mov     al, byte ptr [ebp-59]
0040A328  |.  8B4D F4       mov     ecx, dword ptr [ebp-C]
0040A32B  |.  64:890D 00000>mov     dword ptr fs:[0], ecx
0040A332  |.  59            pop     ecx
0040A333  |.  5E            pop     esi
0040A334  |.  8BE5          mov     esp, ebp
0040A336  |.  5D            pop     ebp
0040A337  \.  C2 0C00       retn    0C
这里是一个大循环。如果输入的注册码不正确的话会在这个call里打转。最终设置有标志位。
修改mov     dl, byte ptr [ebp-D]为 mov dl,1即可完美爆破。
我们的目标是分析算法,依次贴出。
验证假码call:
0040A3B6  |.  E8 15A0FFFF   call    004043D0                         ;  假码长度
0040A3BB  |.  83F8 11       cmp     eax, 11                          ;  假码位数是不是0x11位
0040A3BE  |.  74 09         je      short 0040A3C9                   ;  不是,死
0040A3C0  |.  C645 F3 00    mov     byte ptr [ebp-D], 0
0040A3C4  |.  E9 1B020000   jmp     0040A5E4
0040A3C9  |>  6A 00         push    0
0040A3CB  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A3CE  |.  E8 1DA0FFFF   call    004043F0                         ;  取假码之一位
0040A3D3  |.  0FB7C0        movzx   eax, ax
0040A3D6  |.  50            push    eax
0040A3D7  |.  8B4D EC       mov     ecx, dword ptr [ebp-14]
0040A3DA  |.  E8 31020000   call    0040A610                         ;  循环检测是否在密码表中
0040A3DF  |.  0FB6C8        movzx   ecx, al
0040A3E2  |.  85C9          test    ecx, ecx
0040A3E4  |.  75 04         jnz     short 0040A3EA
...............
0040A473  |.  E8 789FFFFF   call    004043F0                         ;  假码第6位
0040A478  |.  0FB7C8        movzx   ecx, ax
0040A47B  |.  83F9 2D       cmp     ecx, 2D                          ;  是不是“-”
0040A47E  |.  74 04         je      short 0040A484                   ;  不是,死
...............

验证假码的call很长,只是逐位比较,不全贴了。作用:检测假码格式及假码字符是否在密码表中。
算法一和算法二类似,有兴趣的自己跟一下,不再贴了:
0040A790  /$  55            push    ebp
0040A791  |.  8BEC          mov     ebp, esp
0040A793  |.  6A FF         push    -1
0040A795  |.  68 18D44300   push    0043D418
0040A79A  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
0040A7A0  |.  50            push    eax
0040A7A1  |.  83EC 28       sub     esp, 28
0040A7A4  |.  A1 ECBC4400   mov     eax, dword ptr [44BCEC]
0040A7A9  |.  33C5          xor     eax, ebp
0040A7AB  |.  50            push    eax
0040A7AC  |.  8D45 F4       lea     eax, dword ptr [ebp-C]
0040A7AF  |.  64:A3 0000000>mov     dword ptr fs:[0], eax
0040A7B5  |.  894D D4       mov     dword ptr [ebp-2C], ecx          ;  密码表
0040A7B8  |.  C745 FC 00000>mov     dword ptr [ebp-4], 0
0040A7BF  |.  8B45 D4       mov     eax, dword ptr [ebp-2C]
0040A7C2  |.  66:8B08       mov     cx, word ptr [eax]
0040A7C5  |.  66:894D EC    mov     word ptr [ebp-14], cx
0040A7C9  |.  51            push    ecx
0040A7CA  |.  8BCC          mov     ecx, esp
0040A7CC  |.  8965 DC       mov     dword ptr [ebp-24], esp
0040A7CF  |.  8D55 08       lea     edx, dword ptr [ebp+8]           ;  StrA
0040A7D2  |.  52            push    edx
0040A7D3  |.  E8 3875FFFF   call    00401D10
0040A7D8  |.  8945 D0       mov     dword ptr [ebp-30], eax
0040A7DB  |.  8B4D D4       mov     ecx, dword ptr [ebp-2C]
0040A7DE  |.  E8 8D000000   call    0040A870                         ;  算法A
0040A7E3  |.  8945 CC       mov     dword ptr [ebp-34], eax          ;  得出一个数值SumA
0040A7E6  |.  8B45 CC       mov     eax, dword ptr [ebp-34]
0040A7E9  |.  8945 F0       mov     dword ptr [ebp-10], eax
0040A7EC  |.  C745 E8 00000>mov     dword ptr [ebp-18], 0
0040A7F3  |.  EB 09         jmp     short 0040A7FE
0040A7F5  |>  8B4D E8       /mov     ecx, dword ptr [ebp-18]
0040A7F8  |.  83C1 01       |add     ecx, 1                          ;  计数器
0040A7FB  |.  894D E8       |mov     dword ptr [ebp-18], ecx
0040A7FE  |>  837D E8 18     cmp     dword ptr [ebp-18], 18
0040A802  |.  7D 39         |jge     short 0040A83D
0040A804  |.  8B55 F0       |mov     edx, dword ptr [ebp-10]         ;  密码表
0040A807  |.  0355 E8       |add     edx, dword ptr [ebp-18]
0040A80A  |.  8955 E0       |mov     dword ptr [ebp-20], edx
0040A80D  |.  8B45 E0       |mov     eax, dword ptr [ebp-20]
0040A810  |.  99            |cdq
0040A811  |.  B9 18000000   |mov     ecx, 18
0040A816  |.  F7F9          |idiv    ecx                             ;  除以0x18求余
0040A818  |.  8955 E4       |mov     dword ptr [ebp-1C], edx         ;  保存余数
0040A81B  |.  8B55 E4       |mov     edx, dword ptr [ebp-1C]
0040A81E  |.  8B45 D4       |mov     eax, dword ptr [ebp-2C]
0040A821  |.  0FB70C50      |movzx   ecx, word ptr [eax+edx*2]       ;  余数作为密码表中的的位置,取出该位置字符
0040A825  |.  0FB755 0C     |movzx   edx, word ptr [ebp+C]           ;  和密码表首字符比较
0040A829  |.  3BCA          |cmp     ecx, edx                        ;  计数器即该字符和密码表中首字符的距离
0040A82B  |.  75 0E         |jnz     short 0040A83B
0040A82D  |.  8B45 E8       |mov     eax, dword ptr [ebp-18]         ;  密码表
0040A830  |.  8B4D D4       |mov     ecx, dword ptr [ebp-2C]         ;  以距离为序号取得密码表中字符
0040A833  |.  66:8B1441     |mov     dx, word ptr [ecx+eax*2]
0040A837  |.  66:8955 EC    |mov     word ptr [ebp-14], dx
0040A83B  |>^ EB B8         \jmp     short 0040A7F5
0040A83D  |>  66:8B45 EC    mov     ax, word ptr [ebp-14]
0040A841  |.  66:8945 DA    mov     word ptr [ebp-26], ax
0040A845  |.  C745 FC FFFFF>mov     dword ptr [ebp-4], -1
0040A84C  |.  8D4D 08       lea     ecx, dword ptr [ebp+8]
0040A84F  |.  E8 5C7FFFFF   call    004027B0
0040A854  |.  66:8B45 DA    mov     ax, word ptr [ebp-26]
0040A858  |.  8B4D F4       mov     ecx, dword ptr [ebp-C]
0040A85B  |.  64:890D 00000>mov     dword ptr fs:[0], ecx
0040A862  |.  59            pop     ecx
0040A863  |.  8BE5          mov     esp, ebp
0040A865  |.  5D            pop     ebp
0040A866  \.  C2 0800       retn    8

注释很清楚了,那么,再看下算法A:
0040A8AF  |> /8B45 EC       /mov     eax, dword ptr [ebp-14]
0040A8B2  |. |83C0 01       |add     eax, 1
0040A8B5  |. |8945 EC       |mov     dword ptr [ebp-14], eax
0040A8B8  |> |8D4D 08        lea     ecx, dword ptr [ebp+8]
0040A8BB  |. |E8 109BFFFF   |call    004043D0                        ;  StrA的长度
0040A8C0  |. |3945 EC       |cmp     dword ptr [ebp-14], eax
0040A8C3  |. |7D 20         |jge     short 0040A8E5
0040A8C5  |. |8B4D EC       |mov     ecx, dword ptr [ebp-14]
0040A8C8  |. |51            |push    ecx
0040A8C9  |. |8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A8CC  |. |E8 1F9BFFFF   |call    004043F0                        ;  取StrA的字符
0040A8D1  |. |0FB7D0        |movzx   edx, ax
0040A8D4  |. |52            |push    edx
0040A8D5  |. |8B4D E4       |mov     ecx, dword ptr [ebp-1C]
0040A8D8  |. |E8 83FDFFFF   |call    0040A660                        ;  求字符在密码表中的位置
0040A8DD  |. |0345 F0       |add     eax, dword ptr [ebp-10]         ;  累加得到SumA
0040A8E0  |. |8945 F0       |mov     dword ptr [ebp-10], eax
0040A8E3  |.^\EB CA         \jmp     short 0040A8AF

可知SumA是怎么来的。
算法三和算法四类似,自己跟吧:
0040A6EF  |> /8B45 EC       /mov     eax, dword ptr [ebp-14]
0040A6F2  |. |83C0 01       |add     eax, 1
0040A6F5  |. |8945 EC       |mov     dword ptr [ebp-14], eax
0040A6F8  |> |8D4D 08        lea     ecx, dword ptr [ebp+8]          ;  StrA
0040A6FB  |. |E8 D09CFFFF   |call    004043D0                        ;  长度
0040A700  |. |3945 EC       |cmp     dword ptr [ebp-14], eax
0040A703  |. |7D 5B         |jge     short 0040A760
0040A705  |. |8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A708  |. |E8 C39CFFFF   |call    004043D0
0040A70D  |. |83E8 01       |sub     eax, 1
0040A710  |. |2B45 EC       |sub     eax, dword ptr [ebp-14]
0040A713  |. |8945 E8       |mov     dword ptr [ebp-18], eax
0040A716  |. |8B4D E8       |mov     ecx, dword ptr [ebp-18]
0040A719  |. |51            |push    ecx
0040A71A  |. |83EC 08       |sub     esp, 8
0040A71D  |. |DD05 68114400 |fld     qword ptr [441168]              ;  24
0040A723  |. |DD1C24        |fstp    qword ptr [esp]
0040A726  |. |E8 35FCFFFF   |call    0040A360                        ;  依次乘方
0040A72B  |. |83C4 0C       |add     esp, 0C
0040A72E  |. |E8 ED490200   |call    0042F120
0040A733  |. |8945 E4       |mov     dword ptr [ebp-1C], eax
0040A736  |. |8B55 EC       |mov     edx, dword ptr [ebp-14]
0040A739  |. |52            |push    edx
0040A73A  |. |8D4D 08       |lea     ecx, dword ptr [ebp+8]
0040A73D  |. |E8 AE9CFFFF   |call    004043F0                        ;  取StrA字符
0040A742  |. |0FB7C0        |movzx   eax, ax
0040A745  |. |50            |push    eax
0040A746  |. |8B4D D8       |mov     ecx, dword ptr [ebp-28]
0040A749  |. |E8 12FFFFFF   |call    0040A660                        ;  在密码表的位置
0040A74E  |. |8945 E0       |mov     dword ptr [ebp-20], eax
0040A751  |. |8B4D E0       |mov     ecx, dword ptr [ebp-20]
0040A754  |. |0FAF4D E4     |imul    ecx, dword ptr [ebp-1C]         ;  相乘
0040A758  |. |034D F0       |add     ecx, dword ptr [ebp-10]         ;  依次累加得到结果A
0040A75B  |. |894D F0       |mov     dword ptr [ebp-10], ecx
0040A75E  |.^\EB 8F         \jmp     short 0040A6EF

软件的注册算法比较复杂,而且最后采用了浮点运算。用语言描述不易,我用数学方式描述下吧;
注册码去掉“-”为15位,设为str:0123456789ABCDE;
str[6]和str[8]除以5求余分别得到前后6位中的一位,设为char_a和char_b
前后6位分别去掉char_a和char_b得到StrA和StrB
软件要成功注册要满足的条件:
1。StrA在密码表中的位置和经过运算得出的值等于char_a;
2。StrB在密码表中的位置和经过运算得出的值等于char_b;
3。StrA和StrB中字符在密码表中的位置经浮点运算的和加上str[7]的位置=0x798000,用数学公式表示为:
a*18H^4+b*18H^3+c*18H^2+d*18H^1+e*18H^0+x*18H^4+y*18H^3+z*18H^2+u*18H^1+v*18H^0=18H^5(+-)18H
条件1,2比较容易,条件三初看起来没有头绪,但实际分析一下,以上公式可以化简为:
(a+x)*51000+(b+y)*3600+(c+z)*240+(d+u)*18+(e+v)=798000
再次化简就很容易理解了,条件三等价于:
a+x=17
b+y=17
c+7=17
d+u=17
e+v=17
注册成功后注册码保存在:[HKEY_LOCAL_MACHINE\SOFTWARE\Youtica\Power Copy]

C算法注册机代码如下:(好像还有一个小小bug,有兴趣的自己发现下。)
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void main()
{
	char ref_str[]="BCDFGHJKMPQRTVWXY2346789";
	int position[16]={0};
	int rnd_a,rnd_b;	
	int i,k,m;
	printf("----------------------\n");
	printf("Power Copy 1.92 keygen\n");
	printf("code by zaas ,20101216\n");
	printf("----------------------\n");
	while(1)
	{
		char code[]="111111111111111";
		int result_a=0,result_b=0;
		srand((unsigned) time(0));
		rnd_a=rand()%24;
		code[6]=ref_str[rnd_a];						//第7位
		rnd_b=rand()%24;
		code[8]=ref_str[rnd_b];						//第9位
		for (i=0;i<4;i++)							//1-5,11-15位在密码表中的坐标
		{
			*(position+i)=rand()%22;
			*(position+14-i)=23-*(position+i);
			result_a += *(position+i);
			result_b += *(position+14-i);
		}
		position[4]=rand()%8;
		result_a +=position[4];
		position[10]=rand()%8;
		result_b +=position[10];
		position[7]=24-position[4]-position[10];	//9,5,11位的坐标之和等于24
		code[7]=ref_str[position[7]];				//第8位
		i=rnd_a%5;
		k=14-rnd_b%5;
		result_a=24-result_a%24;					//前插入位的坐标
		result_b=23-result_b%24;					//后插入位的坐标
		code[i]=ref_str[result_a];					//前插入位
		code[k]=ref_str[result_b];					//后插入位
		k=0;
		for (m=0;m<5;m++)							//前6位的排序
		{
			if (code[m] !=0x31)	k=1;
			*(code+m+k)=ref_str[*(position+m)];	
		}
		k=0;
		for (m=14;m>9;m--)							//后6位的排序,逆序
		{
			if (code[m] !=0x31)	k=1;
			*(code+m-k)=ref_str[*(position+m)];	
		}
		for (i=0;i<15;i++)							//输出
		{
			if (!(i%5) && i) printf("-");
			printf("%c",*(code+i));
		}
		printf("\n");
		printf("----------------------\n");
		printf("Want another one?[Y/N]\n");
		char redo;
		scanf("%c",&redo);
		getchar();
		printf("----------------------\n");
		if (redo !='y' && redo != 'Y') 
		{
			printf("Bye~good luck.........\n");
			break;
		}
	}
}
【版权声明】破文是学习的手记,兴趣是成功的源泉;本破文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!

《0day安全 软件漏洞分析技术(第二版)》第三次再版印刷预售开始!

收藏
点赞0
打赏
分享
最新回复 (1)
雪    币: 225
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wxhanshan 活跃值 2011-1-22 21:18
2
0
不错的学习教材 谢谢!
游客
登录 | 注册 方可回帖
返回