- UID
- 52135
注册时间2008-5-3
阅读权限20
最后登录1970-1-1
以武会友
该用户从未签到
|
【破文标题】[一起学算法]Power Video Converter V1.6.6.11(视频转换)算法分析+KeyGen
【破文作者】lzover[PYG]
【破解工具】PEiD,OD
【破解平台】DB.XP SP2
【软件名称】Power Video Converter
【软件大小】2622KB
【原版下载】http://www.onlinedown.net/soft/29607.htm
【保护方式】注册码
【软件简介】Power Video Converter可以在AVi, MPEG1, MPEG2, VCD, SVCD, DVD, WMV, ASF, DAT, VOB文件格式之间进行转换,同时具有很快的转换速度和友好的使用界面。
【破解声明】我是小菜菜,只为学习,高人见谅了!
————————————————————————————————————————————————————————————
用PEID查壳,无壳,是Microsoft Visual C++ 6.0的程序,试注册一下,有错误的提示:Invalid username or registration code(错误的用户名或注册码),OK先用C32查一下字符串,找到了错误提示在这个地址:00421BDB,直接OD载入史册程序F9运行起来,找到错误提示地址处的段首下断,然后随便注册一下,断下来了,看到以下代码:
00421B7A . 57 push edi
00421B7B . 8D4C24 0C lea ecx, dword ptr [esp+C]
00421B7F . E8 2A580000 call <jmp.&MFC42.#540>
00421B84 . 6A 01 push 1
00421B86 . 8BCE mov ecx, esi
00421B88 . C74424 1C 000>mov dword ptr [esp+1C], 0
00421B90 . E8 515C0000 call <jmp.&MFC42.#6334>
00421B95 . E8 D45B0000 call <jmp.&MFC42.#1168>
00421B9A . 8B48 04 mov ecx, dword ptr [eax+4]
00421B9D . E8 C85C0000 call <jmp.&MFC42.#1669>
00421BA2 . 68 E8030000 push 3E8 ; /Timeout = 1000. ms
00421BA7 . FF15 ECD04200 call dword ptr [<&KERNEL32.Sleep>] ; \Sleep //这有个缓冲
00421BAD . E8 BC5B0000 call <jmp.&MFC42.#1168>
00421BB2 . 8B48 04 mov ecx, dword ptr [eax+4]
00421BB5 . E8 A45C0000 call <jmp.&MFC42.#2652>
00421BBA . 8B46 64 mov eax, dword ptr [esi+64] ; 假码进EAX
00421BBD . 8B4E 60 mov ecx, dword ptr [esi+60] ; 用户名进ECX
00421BC0 . 8D5E 64 lea ebx, dword ptr [esi+64]
00421BC3 . 8D7E 60 lea edi, dword ptr [esi+60]
00421BC6 . 50 push eax
00421BC7 . 51 push ecx
00421BC8 . E8 73FEFFFF call 00421A40 ; 算法+比较CALL F7进入
00421BCD . 83C4 08 add esp, 8
00421BD0 . 85C0 test eax, eax
00421BD2 . 75 15 jnz short 00421BE9 ; 不跳就错
00421BD4 . 6A 40 push 40
00421BD6 . 68 14894300 push 00438914 ; ASCII "Sorry"
00421BDB . 68 E8884300 push 004388E8 ; ASCII "Invalid username or registration code "
00421BE0 . 8BCE mov ecx, esi
00421BE2 . E8 5F5C0000 call <jmp.&MFC42.#4224>
00421BE7 . EB 3E jmp short 00421C27
00421BE9 > 8B07 mov eax, dword ptr [edi]
00421BEB . 8D4C24 0C lea ecx, dword ptr [esp+C]
00421BEF . 50 push eax
00421BF0 . 68 CC884300 push 004388CC ; ASCII "License To:%s "
00421BF5 . 51 push ecx
00421BF6 . E8 515C0000 call <jmp.&MFC42.#2818>
00421BFB . 8B5424 18 mov edx, dword ptr [esp+18]
00421BFF . 83C4 0C add esp, 0C
00421C02 . 8BCE mov ecx, esi
00421C04 . 6A 40 push 40
00421C06 . 68 C0884300 push 004388C0 ; ASCII "Thank you"
00421C0B . 52 push edx
00421C0C . E8 355C0000 call <jmp.&MFC42.#4224>
00421C11 . 57 push edi
00421C12 . B9 0C8D4300 mov ecx, 00438D0C
00421C17 . E8 5E580000 call <jmp.&MFC42.#858>
00421C1C . 53 push ebx
00421C1D . B9 108D4300 mov ecx, 00438D10
00421C22 . E8 53580000 call <jmp.&MFC42.#858>
00421C27 > 8BCE mov ecx, esi
00421C29 . E8 765B0000 call <jmp.&MFC42.#4853>
00421C2E . 8D4C24 0C lea ecx, dword ptr [esp+C]
00421C32 . C74424 18 FFF>mov dword ptr [esp+18], -1
00421C3A . E8 63570000 call <jmp.&MFC42.#800>
00421C3F . 8B4C24 10 mov ecx, dword ptr [esp+10]
00421C43 . 5F pop edi
00421C44 . 5E pop esi
00421C45 . 5B pop ebx
00421C46 . 64:890D 00000>mov dword ptr fs:[0], ecx
00421C4D . 83C4 10 add esp, 10
00421C50 . C3 retn
==================================================================================
OK.下面进入00421BC8 call 00421A40,看到以下代码:
00421A40 /$ 8B5424 04 mov edx, dword ptr [esp+4]
00421A44 |. 56 push esi
00421A45 |. 57 push edi
00421A46 |. BF F08B4300 mov edi, 00438BF0
00421A4B |. 8BF2 mov esi, edx
00421A4D |. B9 01000000 mov ecx, 1
00421A52 |. 33C0 xor eax, eax
00421A54 |. F3:A6 repe cmps byte ptr es:[edi], byte ptr [esi] ; 用户第一个字不为空
00421A56 |. 74 2B je short 00421A83 ; 跳了就死
00421A58 |. 8B4424 10 mov eax, dword ptr [esp+10]
00421A5C |. 53 push ebx
00421A5D |. BF F08B4300 mov edi, 00438BF0
00421A62 |. 8BF0 mov esi, eax
00421A64 |. B9 01000000 mov ecx, 1
00421A69 |. 33DB xor ebx, ebx
00421A6B |. F3:A6 repe cmps byte ptr es:[edi], byte ptr [esi] ; 注册码第一位不为0
00421A6D |. 5B pop ebx
00421A6E |. 74 13 je short 00421A83 ; 跳了就死
00421A70 |. 50 push eax
00421A71 |. 52 push edx
00421A72 |. E8 99FDFFFF call 00421810 ; 算法CALL F7进入
00421A77 |. 83C4 08 add esp, 8
00421A7A |. F7D8 neg eax
00421A7C |. 1BC0 sbb eax, eax
00421A7E |. 5F pop edi
00421A7F |. F7D8 neg eax
00421A81 |. 5E pop esi
00421A82 |. C3 retn
00421A83 |> 5F pop edi
00421A84 |. 33C0 xor eax, eax
00421A86 |. 5E pop esi
00421A87 \. C3 retn
=================================================================================================
继续进入00421A72 call 00421810,这里是关键了,算法部分和比较都是这个CALL,好的,进入以后看到下面的代码:
0042182E |. 56 push esi
0042182F |. 57 push edi
00421830 |. 50 push eax
00421831 |. 8D4C24 18 lea ecx, dword ptr [esp+18]
00421835 |. E8 325E0000 call <jmp.&MFC42.#537>
0042183A |. 8D4C24 14 lea ecx, dword ptr [esp+14]
0042183E |. C74424 2C 000>mov dword ptr [esp+2C], 0
00421846 |. E8 11620000 call <jmp.&MFC42.#6282>
0042184B |. 8D4C24 14 lea ecx, dword ptr [esp+14]
0042184F |. E8 02620000 call <jmp.&MFC42.#6283>
00421854 |. 6A 20 push 20
00421856 |. 8D4C24 18 lea ecx, dword ptr [esp+18]
0042185A |. E8 D1600000 call <jmp.&MFC42.#2915>
0042185F |. 8B4C24 38 mov ecx, dword ptr [esp+38]
00421863 |. 8BD8 mov ebx, eax
00421865 |. 51 push ecx
00421866 |. 8D4C24 14 lea ecx, dword ptr [esp+14]
0042186A |. E8 FD5D0000 call <jmp.&MFC42.#537>
0042186F |. 8D4C24 10 lea ecx, dword ptr [esp+10]
00421873 |. C64424 2C 01 mov byte ptr [esp+2C], 1
00421878 |. E8 DF610000 call <jmp.&MFC42.#6282>
0042187D |. 8D4C24 10 lea ecx, dword ptr [esp+10]
00421881 |. E8 D0610000 call <jmp.&MFC42.#6283>
00421886 |. 6A 20 push 20
00421888 |. 8D4C24 14 lea ecx, dword ptr [esp+14]
0042188C |. E8 9F600000 call <jmp.&MFC42.#2915>
00421891 |. 8BD0 mov edx, eax
00421893 |. 83CE FF or esi, FFFFFFFF
00421896 |. 8BFA mov edi, edx
00421898 |. 8BCE mov ecx, esi
0042189A |. 33C0 xor eax, eax
0042189C |. 895424 20 mov dword ptr [esp+20], edx
004218A0 |. F2:AE repne scas byte ptr es:[edi]
004218A2 |. F7D1 not ecx
004218A4 |. 49 dec ecx ; 得出注册码位为 B
004218A5 |. 8BFB mov edi, ebx
004218A7 |. 8BE9 mov ebp, ecx
004218A9 |. 8BCE mov ecx, esi
004218AB |. F2:AE repne scas byte ptr es:[edi]
004218AD |. F7D1 not ecx
004218AF |. 49 dec ecx ; 得出用户名为数为 A
004218B0 |. 3BCD cmp ecx, ebp
004218B2 |. 0F87 54010000 ja 00421A0C ; A>B 大于就OVER
004218B8 |. 8BFB mov edi, ebx
004218BA |. 8BCE mov ecx, esi
004218BC |. F2:AE repne scas byte ptr es:[edi]
004218BE |. F7D1 not ecx
004218C0 |. 49 dec ecx
004218C1 |. 0F84 45010000 je 00421A0C
004218C7 |. 8BFA mov edi, edx
004218C9 |. 8BCE mov ecx, esi
004218CB |. F2:AE repne scas byte ptr es:[edi]
004218CD |. F7D1 not ecx
004218CF |. 49 dec ecx
004218D0 |. 0F84 36010000 je 00421A0C
004218D6 |. 894424 38 mov dword ptr [esp+38], eax
004218DA |> 8B5424 38 /mov edx, dword ptr [esp+38]
004218DE |. 8D4C24 34 |lea ecx, dword ptr [esp+34]
004218E2 |. 8A82 A8884300 |mov al, byte ptr [edx+4388A8] ; V
004218E8 |. 884424 18 |mov byte ptr [esp+18], al
004218EC |. E8 BD5A0000 |call <jmp.&MFC42.#540>
004218F1 |. 8BFB |mov edi, ebx
004218F3 |. 83C9 FF |or ecx, FFFFFFFF
004218F6 |. 33C0 |xor eax, eax
004218F8 |. 33ED |xor ebp, ebp
004218FA |. F2:AE |repne scas byte ptr es:[edi]
004218FC |. F7D1 |not ecx
004218FE |. 49 |dec ecx
004218FF |. C64424 2C 02 |mov byte ptr [esp+2C], 2
00421904 |. 74 4B |je short 00421951
00421906 |> 8A042B |/mov al, byte ptr [ebx+ebp] ; 逐位取NAME
00421909 |. 33F6 ||xor esi, esi ; 清0 ESI
0042190B |> 3A0475 408843>||/cmp al, byte ptr [esi*2+438840] ; ESI每次循环+2,直到相等
00421912 |. 74 08 |||je short 0042191C
00421914 |. 46 |||inc esi ; ESI+1
00421915 |. 83FE 34 |||cmp esi, 34 ; 循环52次,没有相等的就OVER
00421918 |.^ 7C F1 ||\jl short 0042190B ; 循环判断用户名
0042191A |. EB 11 ||jmp short 0042192D
0042191C |> 8A0C75 418843>||mov cl, byte ptr [esi*2+438841] ; 上面的地址指针+1
00421923 |. 51 ||push ecx
00421924 |. 8D4C24 38 ||lea ecx, dword ptr [esp+38]
00421928 |. E8 1B5D0000 ||call <jmp.&MFC42.#940> ; 得到的值存入内存
0042192D |> 83FE 34 ||cmp esi, 34
00421930 |. 75 0E ||jnz short 00421940
00421932 |. 8B5424 18 ||mov edx, dword ptr [esp+18]
00421936 |. 8D4C24 34 ||lea ecx, dword ptr [esp+34]
0042193A |. 52 ||push edx
0042193B |. E8 085D0000 ||call <jmp.&MFC42.#940>
00421940 |> 8BFB ||mov edi, ebx
00421942 |. 83C9 FF ||or ecx, FFFFFFFF
00421945 |. 33C0 ||xor eax, eax
00421947 |. 45 ||inc ebp
00421948 |. F2:AE ||repne scas byte ptr es:[edi]
0042194A |. F7D1 ||not ecx
0042194C |. 49 ||dec ecx
0042194D |. 3BE9 ||cmp ebp, ecx
0042194F |.^ 72 B5 |\jb short 00421906
00421951 |> 8B4424 34 |mov eax, dword ptr [esp+34] ; 取出循环得到的值,进EAX
00421955 |. 8B48 F8 |mov ecx, dword ptr [eax-8] ; 用户名位数进ECX
00421958 |. 83F9 10 |cmp ecx, 10 ; 用户名大于等于16位就OVER
0042195B |. 7D 3A |jge short 00421997
0042195D |. 8BC1 |mov eax, ecx
0042195F |. B9 10000000 |mov ecx, 10
00421964 |. 2BC8 |sub ecx, eax
00421966 |. 8D5424 1C |lea edx, dword ptr [esp+1C]
0042196A |. 51 |push ecx
0042196B |. 52 |push edx
0042196C |. B9 C48E4300 |mov ecx, 00438EC4 ; ASCII "8o8"
00421971 |. E8 D45A0000 |call <jmp.&MFC42.#4129> ; 取出固定字符串:ESqNCdaYoDcieku
00421976 |. 50 |push eax
00421977 |. 8D4C24 38 |lea ecx, dword ptr [esp+38]
0042197B |. C64424 30 03 |mov byte ptr [esp+30], 3
00421980 |. E8 BD5C0000 |call <jmp.&MFC42.#939> ; 计算应该取出固定字串位数:16-用户名长度
00421985 |. 8D4C24 1C |lea ecx, dword ptr [esp+1C]
00421989 |. C64424 2C 02 |mov byte ptr [esp+2C], 2
0042198E |. E8 0F5A0000 |call <jmp.&MFC42.#800> ; 拼接得出真码
00421993 |. 8B4424 34 |mov eax, dword ptr [esp+34] ; 真码进EAX
00421997 |> 8B4C24 20 |mov ecx, dword ptr [esp+20] ; 假码进ECX
0042199B |. 51 |push ecx ; /s2
0042199C |. 50 |push eax ; |s1
0042199D |. FF15 B4D64200 |call dword ptr [<&MSVCRT._mbscmp>] ; \_mbscmp
004219A3 |. 83C4 08 |add esp, 8
004219A6 |. 8D4C24 34 |lea ecx, dword ptr [esp+34]
004219AA |. 85C0 |test eax, eax
004219AC |. C64424 2C 01 |mov byte ptr [esp+2C], 1
004219B1 |. 74 1B |je short 004219CE ; 注册码正确跳向成功,74变75可爆破
004219B3 |. 33F6 |xor esi, esi
004219B5 |. E8 E8590000 |call <jmp.&MFC42.#800>
004219BA |. 8B4424 38 |mov eax, dword ptr [esp+38]
004219BE |. 40 |inc eax
004219BF |. 83F8 03 |cmp eax, 3
004219C2 |. 894424 38 |mov dword ptr [esp+38], eax
004219C6 |.^ 0F8C 0EFFFFFF \jl 004218DA ; 循环比较三次,不知道作者是何用意
004219CC |. EB 0A jmp short 004219D8
004219CE |> BE 01000000 mov esi, 1
004219D3 |. E8 CA590000 call <jmp.&MFC42.#800>
004219D8 |> 8D4C24 10 lea ecx, dword ptr [esp+10]
004219DC |. C64424 2C 00 mov byte ptr [esp+2C], 0
004219E1 |. E8 BC590000 call <jmp.&MFC42.#800>
004219E6 |. 8D4C24 14 lea ecx, dword ptr [esp+14]
004219EA |. C74424 2C FFF>mov dword ptr [esp+2C], -1
004219F2 |. E8 AB590000 call <jmp.&MFC42.#800>
004219F7 |. 8BC6 mov eax, esi
004219F9 |. 5F pop edi
004219FA |. 5E pop esi
004219FB |. 5D pop ebp
004219FC |. 5B pop ebx
004219FD |. 8B4C24 14 mov ecx, dword ptr [esp+14]
00421A01 |. 64:890D 00000>mov dword ptr fs:[0], ecx
00421A08 |. 83C4 20 add esp, 20
00421A0B |. C3 retn
00421A0C |> 8D4C24 10 lea ecx, dword ptr [esp+10]
00421A10 |. C64424 2C 00 mov byte ptr [esp+2C], 0
00421A15 |. E8 88590000 call <jmp.&MFC42.#800>
00421A1A |. 8D4C24 14 lea ecx, dword ptr [esp+14]
00421A1E |. 897424 2C mov dword ptr [esp+2C], esi
00421A22 |. E8 7B590000 call <jmp.&MFC42.#800>
00421A27 |. 8B4C24 24 mov ecx, dword ptr [esp+24]
00421A2B |. 5F pop edi
00421A2C |. 5E pop esi
00421A2D |. 5D pop ebp
00421A2E |. 33C0 xor eax, eax
00421A30 |. 5B pop ebx
00421A31 |. 64:890D 00000>mov dword ptr fs:[0], ecx
00421A38 |. 83C4 20 add esp, 20
00421A3B \. C3 retn
——————————————————————————————————————————————————————————
在这一段可以得出真码了,而且还是明码比较的,嘿嘿。现在我们只是研究其算法,明码就忽略了,当作没看到,呵呵。这个算法的关键在这个循环:
0042190B |> 3A0475 408843>||/cmp al, byte ptr [esi*2+438840] ; ESI每次循环+2,直到相等
00421912 |. 74 08 |||je short 0042191C
00421914 |. 46 |||inc esi ; ESI+1
00421915 |. 83FE 34 |||cmp esi, 34 ; 循环52次,没有相等的就OVER
00421918 |.^ 7C F1 ||\jl short 0042190B ; 循环判断用户名
0042191A |. EB 11 ||jmp short 0042192D
0042191C |> 8A0C75 418843>||mov cl, byte ptr [esi*2+438841] ; 上面的地址指针+1
我们看看内存中地址[esi*2+438840]的值是什么东西,这个循环是怎么实现算法的,OK,在注释窗口右键选:数据窗口中跟随地址,看到下图:
嘿嘿,明白了吧:取用户名的每一个字符,然后与地址[esi*2+438840]处的字符比较,不等就继续循环,直到相等则跳向0042191C处,[esi*2+438841]中的值进CL,这个指针是上一个指针+1,就是说如果用户名中的字符和[esi*2+438840]中的值则取此指针的下一指针的字符存进CL。每次循环ESI+1而在地址处是ESI*2+438840,也就是每此循环隔一字符进行比较。如:用户名为abcdABCD 则可以取出一组字符串为:GmlSPoKg 这样讲应该能明白了吧,呵呵。
好了,这个循环是得出与用户名相对应的字符串,但是还没完呢,得出来的字符串还得和与组固定的字符串进行拼接才会得出真码,在00421971处取出固定字符串:ESqNCdaYoDcieku,然后根据用户名的长度来取此字符串的多少个字(16-len(Name)个),最后拼接出来的注册码为16位.
好了,分析到这里也应该可以得出结论了,如有不懂请看以下VB注册机代码,有注释:
————————————————————————————————————————————
Private Sub Command1_Click()
Dim Name, K2 As String
Dim NS As Integer
Name = CStr(Text1.Text) '用户名
NS = Len(Text1.Text) '用户名长度
If NS < 1 Or NS > 16 Then
MsgBox "请输入1至16位英文字母!", , "友情提示"
End
End If
For i = 1 To NS
X = Val(Asc(Mid(Name, i, 1)))
If X < 65 Or (90 < X And X < 97) Or X > 122 Then '判断是否为字母
MsgBox "请输入英文字母!", , "友情提示"
End
ElseIf X > 90 Then
Y = X - 96 '以字符的ASC定位 //a的ASCII码是97
K1 = Mid("GmlSmkEcxstYbkDtafwljDIPZX", Y, 1)
Else
Y = X - 64 '以字符ASC定位 //A的ASCII码是65
K1 = Mid("PoKgymtarqNQUuGJLnbCFHowEp", Y, 1)
End If
K2 = K2 + K1 '得出与用户名对应的字符串
Next i
f = 16 - NS '决定去出固定字符串的多少个字
Text2.Text = K2 + Mid( "ESqNCdaYoDcieku", 1, f ) '拼接得出KEY
End Sub
————————————————————————————————————————————————————
[ 本帖最后由 lzover 于 2008-6-20 02:16 编辑 ] |
|