lzover 发表于 2008-6-18 00:14:25

[一起学算法二]Power Video Converter V1.6.6.11(视频转换)算法分析+KeyGen

【破文标题】[一起学算法]Power Video Converter V1.6.6.11(视频转换)算法分析+KeyGen
【破文作者】lzover
【破解工具】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
00421B7F   .E8 2A580000   call    <jmp.&MFC42.#540>
00421B84   .6A 01         push    1
00421B86   .8BCE          mov   ecx, esi
00421B88   .C74424 1C 000>mov   dword ptr , 0
00421B90   .E8 515C0000   call    <jmp.&MFC42.#6334>
00421B95   .E8 D45B0000   call    <jmp.&MFC42.#1168>
00421B9A   .8B48 04       mov   ecx, dword ptr
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
00421BB5   .E8 A45C0000   call    <jmp.&MFC42.#2652>
00421BBA   .8B46 64       mov   eax, dword ptr           ;假码进EAX
00421BBD   .8B4E 60       mov   ecx, dword ptr           ;用户名进ECX
00421BC0   .8D5E 64       lea   ebx, dword ptr
00421BC3   .8D7E 60       lea   edi, dword ptr
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
00421BEB   .8D4C24 0C   lea   ecx, dword ptr
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
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
00421C32   .C74424 18 FFF>mov   dword ptr , -1
00421C3A   .E8 63570000   call    <jmp.&MFC42.#800>
00421C3F   .8B4C24 10   mov   ecx, dword ptr
00421C43   .5F            pop   edi
00421C44   .5E            pop   esi
00421C45   .5B            pop   ebx
00421C46   .64:890D 00000>mov   dword ptr fs:, ecx
00421C4D   .83C4 10       add   esp, 10
00421C50   .C3            retn
==================================================================================

OK.下面进入00421BC8   call 00421A40,看到以下代码:

00421A40/$8B5424 04   mov   edx, dword ptr
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:, byte ptr    ;用户第一个字不为空
00421A56|.74 2B         je      short 00421A83                           ;跳了就死
00421A58|.8B4424 10   mov   eax, dword ptr
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:, byte ptr    ;注册码第一位不为0
00421A6D|.5B            pop   ebx
00421A6E|.74 13         je      short 00421A83                           ;跳了就死
00421A70|.50            push    eax
00421A71|.52            push    edx
00421A72|.E8 99FDFFFF   call    00421810                                 ;算法CALLF7进入
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    call00421810,这里是关键了,算法部分和比较都是这个CALL,好的,进入以后看到下面的代码:
0042182E|.56            push    esi
0042182F|.57            push    edi
00421830|.50            push    eax
00421831|.8D4C24 18   lea   ecx, dword ptr
00421835|.E8 325E0000   call    <jmp.&MFC42.#537>
0042183A|.8D4C24 14   lea   ecx, dword ptr
0042183E|.C74424 2C 000>mov   dword ptr , 0
00421846|.E8 11620000   call    <jmp.&MFC42.#6282>
0042184B|.8D4C24 14   lea   ecx, dword ptr
0042184F|.E8 02620000   call    <jmp.&MFC42.#6283>
00421854|.6A 20         push    20
00421856|.8D4C24 18   lea   ecx, dword ptr
0042185A|.E8 D1600000   call    <jmp.&MFC42.#2915>
0042185F|.8B4C24 38   mov   ecx, dword ptr
00421863|.8BD8          mov   ebx, eax
00421865|.51            push    ecx
00421866|.8D4C24 14   lea   ecx, dword ptr
0042186A|.E8 FD5D0000   call    <jmp.&MFC42.#537>
0042186F|.8D4C24 10   lea   ecx, dword ptr
00421873|.C64424 2C 01mov   byte ptr , 1
00421878|.E8 DF610000   call    <jmp.&MFC42.#6282>
0042187D|.8D4C24 10   lea   ecx, dword ptr
00421881|.E8 D0610000   call    <jmp.&MFC42.#6283>
00421886|.6A 20         push    20
00421888|.8D4C24 14   lea   ecx, dword ptr
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 , edx
004218A0|.F2:AE         repne   scas byte ptr es:
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:
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:
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:
004218CD|.F7D1          not   ecx
004218CF|.49            dec   ecx
004218D0|.0F84 36010000 je      00421A0C
004218D6|.894424 38   mov   dword ptr , eax
004218DA|>8B5424 38   /mov   edx, dword ptr
004218DE|.8D4C24 34   |lea   ecx, dword ptr
004218E2|.8A82 A8884300 |mov   al, byte ptr       ;V
004218E8|.884424 18   |mov   byte ptr , 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:
004218FC|.F7D1          |not   ecx
004218FE|.49            |dec   ecx
004218FF|.C64424 2C 02|mov   byte ptr , 2
00421904|.74 4B         |je      short 00421951
00421906|>8A042B      |/mov   al, byte ptr           ;逐位取NAME
00421909|.33F6          ||xor   esi, esi                        ;清0ESI
0042190B|>3A0475 408843>||/cmp   al, byte ptr     ;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    ;上面的地址指针+1
00421923|.51            ||push    ecx
00421924|.8D4C24 38   ||lea   ecx, dword ptr
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
00421936|.8D4C24 34   ||lea   ecx, dword ptr
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:
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           ;取出循环得到的值,进EAX
00421955|.8B48 F8       |mov   ecx, dword ptr          ;用户名位数进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
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
0042197B|.C64424 30 03|mov   byte ptr , 3
00421980|.E8 BD5C0000   |call    <jmp.&MFC42.#939>                ;计算应该取出固定字串位数:16-用户名长度
00421985|.8D4C24 1C   |lea   ecx, dword ptr
00421989|.C64424 2C 02|mov   byte ptr , 2
0042198E|.E8 0F5A0000   |call    <jmp.&MFC42.#800>                ;拼接得出真码
00421993|.8B4424 34   |mov   eax, dword ptr           ;真码进EAX
00421997|>8B4C24 20   |mov   ecx, dword ptr           ;假码进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
004219AA|.85C0          |test    eax, eax
004219AC|.C64424 2C 01|mov   byte ptr , 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
004219BE|.40            |inc   eax
004219BF|.83F8 03       |cmp   eax, 3
004219C2|.894424 38   |mov   dword ptr , 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
004219DC|.C64424 2C 00mov   byte ptr , 0
004219E1|.E8 BC590000   call    <jmp.&MFC42.#800>
004219E6|.8D4C24 14   lea   ecx, dword ptr
004219EA|.C74424 2C FFF>mov   dword ptr , -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
00421A01|.64:890D 00000>mov   dword ptr fs:, ecx
00421A08|.83C4 20       add   esp, 20
00421A0B|.C3            retn
00421A0C|>8D4C24 10   lea   ecx, dword ptr
00421A10|.C64424 2C 00mov   byte ptr , 0
00421A15|.E8 88590000   call    <jmp.&MFC42.#800>
00421A1A|.8D4C24 14   lea   ecx, dword ptr
00421A1E|.897424 2C   mov   dword ptr , esi
00421A22|.E8 7B590000   call    <jmp.&MFC42.#800>
00421A27|.8B4C24 24   mov   ecx, dword ptr
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:, ecx
00421A38|.83C4 20       add   esp, 20
00421A3B\.C3            retn
——————————————————————————————————————————————————————————
在这一段可以得出真码了,而且还是明码比较的,嘿嘿。现在我们只是研究其算法,明码就忽略了,当作没看到,呵呵。这个算法的关键在这个循环:
0042190B|>3A0475 408843>||/cmp   al, byte ptr     ;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    ;上面的地址指针+1

    我们看看内存中地址的值是什么东西,这个循环是怎么实现算法的,OK,在注释窗口右键选:数据窗口中跟随地址,看到下图:

    嘿嘿,明白了吧:取用户名的每一个字符,然后与地址处的字符比较,不等就继续循环,直到相等则跳向0042191C处,中的值进CL,这个指针是上一个指针+1,就是说如果用户名中的字符和中的值则取此指针的下一指针的字符存进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) OrX > 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 编辑 ]

crystalsnail 发表于 2008-6-18 00:17:55

不错,学习了,半夜了还在奋斗/:good

tianxj 发表于 2008-6-18 06:31:36

算法还不是很完整
页: [1]
查看完整版本: [一起学算法二]Power Video Converter V1.6.6.11(视频转换)算法分析+KeyGen