【破文标题】ADSL拨号计时器v5.28算法分析
【软件名称】ADSL拨号计时器v5.28
【软件地址】http://www.uncleme.com/showarticle.php?id=85
【破文作者】KiLlL[DFCG][FCG]
【破解时间】2005-09-16 17:00
【破解声明】仅为技术交流之用!刚加入FCG,高兴~
【破解过程】
看到一篇文章
http://www.it33.com.cn/soft/kftq/200578113841.html
“具体怎么使用,那要看你自己的意愿了和需要了。反正我是这样做的,我的软件ADSL拨号计时器只在很早版 本上出过注册机,后来的v3.70出过破解补丁——其实只是破掉了启动时提示注册的对话框,实质上根本没破解 。用了上述的着法以后,到现在的v5.28版本,再没有过什么破解补丁或注册机。如果现在的v5.28版本谁能破 解,将立即公布程序源码。”
说的很是有趣,于是下载看看,由于程序现在最新版7.02已经免费,所以看看也无妨了,结果出乎意料。
程序有壳,aspack,脱后dede查看:
00489004 /. 55 push ebp ; dede可知这个是注册按钮的事件
00489005 |. 8BEC mov ebp,esp
00489007 |. 6A 00 push 0
00489009 |. 6A 00 push 0
0048900B |. 53 push ebx
0048900C |. 8BD8 mov ebx,eax
0048900E |. 33C0 xor eax,eax
00489010 |. 55 push ebp
00489011 |. 68 A5904800 push unpacked.004890A5
00489016 |. 64:FF30 push dword ptr fs:[eax]
00489019 |. 64:8920 mov dword ptr fs:[eax],esp
0048901C |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
0048901F |. 8B83 FC02000>mov eax,dword ptr ds:[ebx+2FC]
00489025 |. E8 EA92FBFF call unpacked.00442314 ; 读取假码
0048902A |. 837D FC 00 cmp dword ptr ss:[ebp-4],0 ; 假码是否为空?
0048902E |. 74 57 je short unpacked.00489087
00489030 |. 8BC3 mov eax,ebx
00489032 |. E8 59FEFFFF call unpacked.00488E90 ; 对假码进行运算
00489037 |. 84C0 test al,al ; 关键跳转
00489039 |. 74 36 je short unpacked.00489071 ; 注册失败就跳走
0048903B |. A1 100D4900 mov eax,dword ptr ds:[490D10]
00489040 |. E8 E712F8FF call unpacked.0040A32C
00489045 |. D805 B490480>fadd dword ptr ds:[4890B4]
0048904B |. 83C4 F4 add esp,-0C
跟进关键算法看看:
00488E90 /$ 55 push ebp ; 关键算法
00488E91 |. 8BEC mov ebp,esp
00488E93 |. B9 05000000 mov ecx,5
00488E98 |> 6A 00 /push 0
00488E9A |. 6A 00 |push 0
00488E9C |. 49 |dec ecx
00488E9D |.^ 75 F9 \jnz short unpacked.00488E98
00488E9F |. 51 push ecx
00488EA0 |. 53 push ebx
00488EA1 |. 56 push esi
00488EA2 |. 8945 FC mov dword ptr ss:[ebp-4],eax
00488EA5 |. 33C0 xor eax,eax
00488EA7 |. 55 push ebp
00488EA8 |. 68 E08F4800 push unpacked.00488FE0
00488EAD |. 64:FF30 push dword ptr fs:[eax]
00488EB0 |. 64:8920 mov dword ptr fs:[eax],esp
00488EB3 |. 33F6 xor esi,esi
00488EB5 |. 8D55 F8 lea edx,dword ptr ss:[ebp-8]
00488EB8 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00488EBB |. E8 D0FAFFFF call unpacked.00488990
00488EC0 |. 8B45 F8 mov eax,dword ptr ss:[ebp-8] ; 硬件号 "7FD9534C"
00488EC3 |. E8 5CBAF7FF call unpacked.00404924 ; 获得长度
00488EC8 |. 8BD8 mov ebx,eax ; 8
00488ECA |. 85DB test ebx,ebx
00488ECC |. 7E 58 jle short unpacked.00488F26
00488ECE |. C745 F4 0100>mov dword ptr ss:[ebp-C],1
00488ED5 |> 8D45 F0 /lea eax,dword ptr ss:[ebp-10] ; 以长度作为循环终止值
00488ED8 |. 50 |push eax
00488ED9 |. B9 01000000 |mov ecx,1
00488EDE |. 8B55 F4 |mov edx,dword ptr ss:[ebp-C]
00488EE1 |. 8B45 F8 |mov eax,dword ptr ss:[ebp-8]
00488EE4 |. E8 93BCF7FF |call unpacked.00404B7C ; mid(code,i,1)
00488EE9 |. 8B45 F0 |mov eax,dword ptr ss:[ebp-10]
00488EEC |. E8 2BBCF7FF |call unpacked.00404B1C
00488EF1 |. 8A00 |mov al,byte ptr ds:[eax] ; 取得ascii
00488EF3 |. 25 FF000000 |and eax,0FF
00488EF8 |. 03F0 |add esi,eax ; 加到esi
00488EFA |. 8D55 E8 |lea edx,dword ptr ss:[ebp-18]
00488EFD |. 69C6 4132000>|imul eax,esi,3241 ; eax=esi*3241
00488F03 |. E8 24FDF7FF |call unpacked.00408C2C ; 转成十进制
00488F08 |. 8B45 E8 |mov eax,dword ptr ss:[ebp-18] ; 7->707575
00488F0B |. 8D55 EC |lea edx,dword ptr ss:[ebp-14]
00488F0E |. E8 C5260000 |call unpacked.0048B5D8 ; 较复杂的编码
00488F13 |. 8B55 EC |mov edx,dword ptr ss:[ebp-14] ; 707575 -》"2060320645206502065020645")
00488F16 |. B8 100D4900 |mov eax,unpacked.00490D10
00488F1B |. E8 A0B7F7FF |call unpacked.004046C0
00488F20 |. FF45 F4 |inc dword ptr ss:[ebp-C]
00488F23 |. 4B |dec ebx
00488F24 |.^ 75 AF \jnz short unpacked.00488ED5
00488F26 |> 8D55 DC lea edx,dword ptr ss:[ebp-24]
00488F29 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00488F2C |. 8B80 FC02000>mov eax,dword ptr ds:[eax+2FC]
00488F32 |. E8 DD93FBFF call unpacked.00442314
这里面对硬件号进行了处理,分成两个步骤,首先,逐位取出ascii,加到esi,把esi*3241的结果转成十进制 ,得到临时码。再对其进行编码。
For i = 1 To Len(machineID)
eax = Asc(Mid$(machineID, i, 1)) '取出ascii
esi = esi + eax '相加
eax = esi * &H3241 '乘以3241
temp = temp & CStr(encode(eax)) '对结果编码
Next
编码过程有点复杂,请看:
0048B5D8 /$ 55 push ebp ; 把数字编码过程
0048B5D9 |. 8BEC mov ebp,esp
0048B5DB |. 81C4 DCFEFFF>add esp,-124
0048B5E1 |. 53 push ebx
0048B5E2 |. 56 push esi
0048B5E3 |. 57 push edi
0048B5E4 |. 33C9 xor ecx,ecx
0048B5E6 |. 898D E4FEFFF>mov dword ptr ss:[ebp-11C],ecx
0048B5EC |. 898D ECFEFFF>mov dword ptr ss:[ebp-114],ecx
0048B5F2 |. 898D E8FEFFF>mov dword ptr ss:[ebp-118],ecx
0048B5F8 |. 898D F0FEFFF>mov dword ptr ss:[ebp-110],ecx
0048B5FE |. 8BF2 mov esi,edx
0048B600 |. 8945 FC mov dword ptr ss:[ebp-4],eax
0048B603 |. 8B45 FC mov eax,dword ptr ss:[ebp-4] ; 需要编码的数字,以第一个为例: 707575
0048B606 |. E8 0195F7FF call unpacked.00404B0C
0048B60B |. 8DBD F4FEFFF>lea edi,dword ptr ss:[ebp-10C] ; 707575
0048B611 |. 33C0 xor eax,eax
0048B613 |. 55 push ebp
0048B614 |. 68 5BB74800 push unpacked.0048B75B
0048B619 |. 64:FF30 push dword ptr fs:[eax]
0048B61C |. 64:8920 mov dword ptr fs:[eax],esp
0048B61F |. 8BC7 mov eax,edi
0048B621 |. 8B55 FC mov edx,dword ptr ss:[ebp-4]
0048B624 |. B9 FF000000 mov ecx,0FF ; 707575
0048B629 |. E8 D292F7FF call unpacked.00404900 ; 取得位数
0048B62E |. 8A07 mov al,byte ptr ds:[edi] ; 6
0048B630 |. 33D2 xor edx,edx ; 707575
0048B632 |. 8AD0 mov dl,al
0048B634 |. 42 inc edx
0048B635 |. 8955 F8 mov dword ptr ss:[ebp-8],edx
0048B638 |. 8B55 F8 mov edx,dword ptr ss:[ebp-8]
0048B63B |. 81E2 0100008>and edx,80000001
0048B641 |. 79 05 jns short unpacked.0048B648
0048B643 |. 4A dec edx
0048B644 |. 83CA FE or edx,FFFFFFFE
0048B647 |. 42 inc edx
0048B648 |> 85D2 test edx,edx
0048B64A |. 74 03 je short unpacked.0048B64F
0048B64C |. FF45 F8 inc dword ptr ss:[ebp-8]
0048B64F |> 837D F8 0A cmp dword ptr ss:[ebp-8],0A ; 跟10比较
0048B653 |. 7D 07 jge short unpacked.0048B65C
0048B655 |. C745 F8 0A00>mov dword ptr ss:[ebp-8],0A
0048B65C |> 33DB xor ebx,ebx
0048B65E |. 8AD8 mov bl,al
0048B660 |. 85DB test ebx,ebx
0048B662 |. 75 67 jnz short unpacked.0048B6CB
0048B664 |. E8 9BB6F7FF call <jmp.&kernel32.GetTickCoun>; [GetTickCount
0048B669 |. 33D2 xor edx,edx
0048B66B |. 52 push edx ; /Arg2 => 00000000
0048B66C |. 50 push eax ; |Arg1
0048B66D |. 8D85 F0FEFFF>lea eax,dword ptr ss:[ebp-110] ; |
0048B673 |. E8 E4D5F7FF call unpacked.00408C5C ; \unpacked.00408C5C
0048B678 |. 8B95 F0FEFFF>mov edx,dword ptr ss:[ebp-110]
0048B67E |. 8BC7 mov eax,edi
0048B680 |. B9 FF000000 mov ecx,0FF
0048B685 |. E8 7692F7FF call unpacked.00404900
0048B68A |. EB 44 jmp short unpacked.0048B6D0
0048B68C |> 8D85 ECFEFFF>/lea eax,dword ptr ss:[ebp-114]
0048B692 |. 8BD7 |mov edx,edi ; 707575
0048B694 |. E8 2F92F7FF |call unpacked.004048C8
0048B699 |. 8D85 ECFEFFF>|lea eax,dword ptr ss:[ebp-114]
0048B69F |. 50 |push eax
0048B6A0 |. 8D85 E8FEFFF>|lea eax,dword ptr ss:[ebp-118]
0048B6A6 |. 8BD7 |mov edx,edi ; 707575
0048B6A8 |. E8 1B92F7FF |call unpacked.004048C8
0048B6AD |. 8B95 E8FEFFF>|mov edx,dword ptr ss:[ebp-118]
0048B6B3 |. 58 |pop eax
0048B6B4 |. E8 7392F7FF |call unpacked.0040492C
0048B6B9 |. 8B95 ECFEFFF>|mov edx,dword ptr ss:[ebp-114] ; 扩展成"707575707575"
0048B6BF |. 8BC7 |mov eax,edi
0048B6C1 |. B9 FF000000 |mov ecx,0FF
0048B6C6 |. E8 3592F7FF |call unpacked.00404900
0048B6CB |> 803F 0A cmp byte ptr ds:[edi],0A
0048B6CE |.^ 72 BC \jb short unpacked.0048B68C
0048B6D0 |> 8BC7 mov eax,edi
0048B6D2 |. 8BD3 mov edx,ebx
0048B6D4 |. E8 0B74F7FF call unpacked.00402AE4
0048B6D9 |. 8BC6 mov eax,esi
0048B6DB |. E8 8C8FF7FF call unpacked.0040466C
0048B6E0 |. 8B5D F8 mov ebx,dword ptr ss:[ebp-8]
0048B6E3 |. D1FB sar ebx,1
0048B6E5 |. 79 03 jns short unpacked.0048B6EA
0048B6E7 |. 83D3 00 adc ebx,0
0048B6EA |> 85DB test ebx,ebx
0048B6EC |. 7E 47 jle short unpacked.0048B735 ; edi存放的就是位数+扩展后的字符串 ascii码为0637303735...
0048B6EE |> 0FB707 /movzx eax,word ptr ds:[edi] ; 取ascii,第一个为3706
0048B6F1 |. 05 75190000 |add eax,1975 ; +1975
0048B6F6 |. 8945 F4 |mov dword ptr ss:[ebp-C],eax ; 507b
0048B6F9 |. 83C7 02 |add edi,2
0048B6FC |. 8D85 E4FEFFF>|lea eax,dword ptr ss:[ebp-11C]
0048B702 |. 50 |push eax ; /Arg1
0048B703 |. 8B45 F4 |mov eax,dword ptr ss:[ebp-C] ; |
0048B706 |. 8985 DCFEFFF>|mov dword ptr ss:[ebp-124],eax ; |
0048B70C |. C685 E0FEFFF>|mov byte ptr ss:[ebp-120],0 ; |
0048B713 |. 8D95 DCFEFFF>|lea edx,dword ptr ss:[ebp-124] ; |
0048B719 |. 33C9 |xor ecx,ecx ; |
0048B71B |. B8 74B74800 |mov eax,unpacked.0048B774 ; |ASCII "%5.5d"
0048B720 |. E8 5BE1F7FF |call unpacked.00409880 ; \unpacked.00409880
0048B725 |. 8B95 E4FEFFF>|mov edx,dword ptr ss:[ebp-11C] ; 转成10进制: "20603"
0048B72B |. 8BC6 |mov eax,esi
0048B72D |. E8 FA91F7FF |call unpacked.0040492C
0048B732 |. 4B |dec ebx
0048B733 |.^ 75 B9 \jnz short unpacked.0048B6EE ; 取出前5位
0048B735 |> 33C0 xor eax,eax
0048B737 |. 5A pop edx
0048B738 |. 59 pop ecx
编码的方法是先扩展字符串,然后在前面加上位数,比如刚才的硬件第一位7临时码是707575,扩展成为 “707575707575”,在最前面加上长度6,成了chr(6) & "707575707575",然后根据ascii码每四位加上1975后 转换成10进制数字。
Function encode(eax)
result = Chr$(Len(eax)) & eax & eax '扩展
For i = 1 To 10 Step 2
eax = Hex$(Asc(Mid$(result, i + 1, 1))) & Right$("0" & Hex$(Asc(Mid$(result, i, 1))), 2) '取出两位的ascii
eax = CInt("&H" & eax) + &H1975 '转换成数字并加1975
encode = encode & eax
Next
End Function
最终,707575转换成为:2060320645206502065020645。现在回到验证注册码程序。作者这里虽然每位都编码, 但是最后只用到了机器码最后一位的编码,也就是“C”->"2034820901191142013718859"
当然,这个编码跟前面几位也是有关系的,用到了他们的ascii和。
本来到这里就不错了,可惜作者下面的代码让你笑:
00488F37 |. 8B45 DC mov eax,dword ptr ss:[ebp-24] ; 假码
00488F3A |. E8 ED13F8FF call unpacked.0040A32C
00488F3F |. D825 F08F480>fsub dword ptr ds:[488FF0] ; -1728
00488F45 |. 83C4 F4 add esp,-0C
00488F48 |. DB3C24 fstp tbyte ptr ss:[esp] ; |
00488F4B |. 9B wait ; |
00488F4C |. 8D45 E0 lea eax,dword ptr ss:[ebp-20] ; |
00488F4F |. E8 5013F8FF call unpacked.0040A2A4 ; \unpacked.0040A2A4
00488F54 |. 8B45 E0 mov eax,dword ptr ss:[ebp-20] ; "12343950"
00488F57 |. 8D55 E4 lea edx,dword ptr ss:[ebp-1C]
00488F5A |. E8 79260000 call unpacked.0048B5D8 ; 较复杂的编码
00488F5F |. 8B45 E4 mov eax,dword ptr ss:[ebp-1C] ; "1906919623196252014219109"
00488F62 |. 8B15 100D490>mov edx,dword ptr ds:[490D10] ; 最后一次的编码结果
00488F68 |. E8 FBBAF7FF call unpacked.00404A68 ; 比较是否一样
00488F6D |. 75 37 jnz short unpacked.00488FA6 ; 不一样就跳走,注册失败
作者直接拿假码减去1728,然后编码,然后比较两次编码是否一致,这个也太简单了吧。上面的编码白跟踪了 。最终的算法是:
注册码=机器码-1728
++++++++++++++++++++++++++++++++++
这里我分析错了,由于作者没有对输入的数字进行转换,所以你无法输入十六进制数字。所以可能只有对编码求逆了。
但是可以利用下面的漏洞直接写入注册表。就是把那串数字直接写入注册表。
2005-9-17 18:00
++++++++++++++++++++++++++++++++++
真的没有想到亚,更没有想到的是如果在00488F6D 爆破的话,存入注册表的竟然是正确的注册码:
2.03482090119114E24 ("2034820901191142013718859"转成数字)
注册成功后,注册表里增加:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Netzc]
"Card"="7FD9534C"
"Code"="2.03482090119114E24"
删除成了没有注册。
【破解心得】作者估计太自信,可以说这个算法本来还有一点点麻烦,但是在错误思想的指导下要想搞定太容 易了。而作者用到的反破解除了加个弱壳以外,如果注册表中的注册码不正确,程序启动后会自动退出。
+++++++++++++++++++++++++++++++++++++++++
最新增加:
除了可以直接写入注册表注册以外,终于搞定了逆运算:就是知道编码如何求编码前的字串:
Function decode2(eax)
Dim temp, tmp1, tmp2
For i = 1 To 25 Step 5
temp = CLng(Mid$(eax, i, 5)) - &H1975
For j = Asc("9") To Asc("0") Step -1
tmp1 = j * 16 * 16
tmp2 = temp - tmp1
If i = 1 And tmp2 > 0 And tmp2 < 16 * 16 Then
decode2 = decode2 & Chr$(tmp2) & Chr$(tmp1)
Exit For
Else
If tmp2 >= Asc("0") And tmp2 < Asc("9") Then
decode2 = decode2 & Chr$(tmp2) & Chr$(tmp1)
Exit For
End If
End If
Next
Next
decode2 = clng(Mid$(decode2, 2, Asc(Mid$(decode2, 1, 1))))+ 1728
End Function
++++++++++++++++++++++++++++++++++++++++
2005-9-18
今天又想了一下,原来我真笨亚,直接取没有编码前的数字就可以了,不需要编码,再反编码。
For i = 1 To Len(machineID)
eax = Asc(Mid$(machineID, i, 1)) '取出ascii
esi = esi + eax '相加
Next
eax = esi * &H3241 '乘以3241
eax = eax + 1728
sn = eax
++++++++++++++++++++++++++++++++++++++++
2005-9-18 17:00
跟踪了下机器码的生成:
00488974 /$ 53 push ebx
00488975 |. 57 push edi
00488976 |. 89C7 mov edi,eax
00488978 |. B8 01000000 mov eax,1
0048897D |. 0FA2 cpuid
0048897F |. AB stos dword ptr es:[edi] '保存eax
00488980 |. 89D8 mov eax,ebx
00488982 |. AB stos dword ptr es:[edi] '保存ebx
00488983 |. 89C8 mov eax,ecx
00488985 |. AB stos dword ptr es:[edi] '保存ecx
00488986 |. 89D0 mov eax,edx
00488988 |. AB stos dword ptr es:[edi] '保存edx
00488989 |. 89D0 mov eax,edx
0048898B |. AB stos dword ptr es:[edi] '保存edx
0048898C |. 5F pop edi
0048898D |. 5B pop ebx
0048898E \. C3 retn
EAX 00000F27
ECX 00004400
EDX BFEBFBFF
EBX 00010809
004889AB |. E8 C4FFFFFF call unpacked.00488974
004889B0 |. 8B0424 mov eax,dword ptr ss:[esp] ; eax:f27
004889B3 |. 83C0 08 add eax,8 ; +8
004889B6 |. 8B5424 04 mov edx,dword ptr ss:[esp+4] ; ebx 10809
004889BA |. 83C2 07 add edx,7 ; +7
004889BD |. 03C2 add eax,edx ; f27+10810
004889BF |. 8B5424 08 mov edx,dword ptr ss:[esp+8] ; ecx 4400
004889C3 |. 83C2 06 add edx,6 ; 4400+6
004889C6 |. 03C2 add eax,edx ; 1173f+4406
004889C8 |. 8B5424 0C mov edx,dword ptr ss:[esp+C] ; edx BFEBFBFF
004889CC |. 83C2 05 add edx,5 ; +5
004889CF |. 03C2 add eax,edx ; BFEBFC04 + 15B45
004889D1 |. 8B5424 10 mov edx,dword ptr ss:[esp+10] ; EDX BFEBFBFF
004889D5 |. 83C2 04 add edx,4 ; +4
004889D8 |. 03C2 add eax,edx ; BFEBFC03+ BFED5749
004889DA |. 8BCB mov ecx,ebx ; 12fbc4
最后结果: "7FD9534C"