-
-
[原创]Power Copy 1.92 算法分析及 VC 算法注册机
-
2010-12-18 22:09 4733
-
【破文标题】Power Copy 1.92 算法分析及 VC 算法注册机
【破文作者】zaas[PYG]
【破解工具】OllyICE,PEiD v0.94
【破解平台】WinXP
【软件授权】:共享版
【软件介绍】:对于坏的软盘或光碟中的数据进行强制复制解码,取代Windows中自带拷贝工具。使您真正拥有强大稳定无敌的拷贝工具。
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享
--------------------------------------------------------------
【破解内容】
查找字符串,有:
地址=0040B36E
反汇编=push 0044112C
文本字符串=Software\Youtica\Power Copy
双击跟进,猜想一下。
跟进关键call,核心算法很容易找到。
跟进 call 0040A090,大致一看,就像是算法,下断跟跟。程序settimer了,频繁断下,不怕。
修改mov dl, byte ptr [ebp-D]为 mov dl,1即可完美爆破。
我们的目标是分析算法,依次贴出。
验证假码call:
验证假码的call很长,只是逐位比较,不全贴了。作用:检测假码格式及假码字符是否在密码表中。
算法一和算法二类似,有兴趣的自己跟一下,不再贴了:
注释很清楚了,那么,再看下算法A:
可知SumA是怎么来的。
算法三和算法四类似,自己跟吧:
软件的注册算法比较复杂,而且最后采用了浮点运算。用语言描述不易,我用数学方式描述下吧;
注册码去掉“-”为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,有兴趣的自己发现下。)
【破文作者】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; } } }【版权声明】破文是学习的手记,兴趣是成功的源泉;本破文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
赞赏
他的文章
看原图