且行且远 » Blog Archive » Midi To Mp3破解手记
且行且远
分类: 逆向手札 由 ssfighter 于 2006年2月20日 发表

呵呵,开学了,弄了个简单的软件破解一下。
从看雪论坛上看到了一篇破解手记,于是自己试着破解一下,软件下载地址:
http://www3.skycn.com/soft/25150.html

看雪上破文的地址:http://bbs.pediy.com/showthread.php?s=&threadid=21496

先用PeiD0.94侦壳,Microsoft Visual C++ 6.0,基本判定无壳。
用FlyOdbg载入,搜索-所有参考的文本字符串中找“Registration has succeeded”,来到这里

00407A44 > \6A 00 push 0 ; /Arg3 = 00000000
00407A46 . 6A 00 push 0 ; |Arg2 = 00000000
00407A48 . 68 38AD4300 push midi2mp3.0043AD38 ; |Arg1 = 0043AD38 ASCII “Registration has succeeded!”
00407A4D . E8 D2060200 call midi2mp3.00428124 ; \midi2mp3.00428124
00407A52 . 8B7424 38 mov esi,dword ptr ss:[esp+38]

往前翻来到这个模块的开始部分

00407890 . 83EC 2C sub esp,2C
00407893 . 53 push ebx
00407894 . 55 push ebp
00407895 . 56 push esi
00407896 . 57 push edi
00407897 . 8BD9 mov ebx,ecx
00407899 . 6A 01 push 1
0040789B . 895C24 3C mov dword ptr ss:[esp+3C],ebx
0040789F . E8 8DD10100 call midi2mp3.00424A31
004078A4 . 8BB3 64010000 mov esi,dword ptr ds:[ebx+164] ; 用户名
004078AA . 8B7E F8 mov edi,dword ptr ds:[esi-8] ; 用户名位数
004078AD . 83FF 02 cmp edi,2 ; 用户名长度要大于2
004078B0 . 7D 16 jge short midi2mp3.004078C8
004078B2 . 6A 00 push 0 ; /Arg3 = 00000000
004078B4 . 6A 00 push 0 ; |Arg2 = 00000000
004078B6 . 68 7CAD4300 push midi2mp3.0043AD7C ; |Arg1 = 0043AD7C ASCII “Please input correct User Name!”
004078BB . E8 64080200 call midi2mp3.00428124 ; \midi2mp3.00428124
004078C0 . 5F pop edi
004078C1 . 5E pop esi
004078C2 . 5D pop ebp
004078C3 . 5B pop ebx
004078C4 . 83C4 2C add esp,2C
004078C7 . C3 retn
004078C8 > 8B8B 68010000 mov ecx,dword ptr ds:[ebx+168] ; 取注册码
004078CE . 8379 F8 08 cmp dword ptr ds:[ecx-8],8 ; 注册码位数
004078D2 . 7D 16 jge short midi2mp3.004078EA ; 注册码位数要大于等于8
004078D4 . 6A 00 push 0 ; /Arg3 = 00000000
004078D6 . 6A 00 push 0 ; |Arg2 = 00000000
004078D8 . 68 54AD4300 push midi2mp3.0043AD54 ; |Arg1 = 0043AD54 ASCII “Please input correct Registration Code!”
004078DD . E8 42080200 call midi2mp3.00428124 ; \midi2mp3.00428124
004078E2 . 5F pop edi
004078E3 . 5E pop esi
004078E4 . 5D pop ebp
004078E5 . 5B pop ebx
004078E6 . 83C4 2C add esp,2C
004078E9 . C3 retn

由此看出用户名要大于2位,注册码要不小于8位

继续往下看,由4078D8的跳转来到这里:
004078EA > \8A1E mov bl,byte ptr ds:[esi] ; 取用户名第一位
004078EC . BD 0A000000 mov ebp,0A
004078F1 . 8BC3 mov eax,ebx
004078F3 . 25 FF000000 and eax,0FF ; eax=al
004078F8 . 0C 4D or al,4D ; 和4d取或
004078FA . 99 cdq
004078FB . F7FD idiv ebp
004078FD . 8A46 01 mov al,byte ptr ds:[esi+1] ; 取用户名第二位
00407900 . 25 FF000000 and eax,0FF
00407905 . 885424 28 mov byte ptr ss:[esp+28],dl ; **计算得到第一位
00407909 . 0C 44 or al,44
0040790B . 99 cdq
0040790C . F7FD idiv ebp
0040790E . 8BC3 mov eax,ebx
00407910 . 8BDD mov ebx,ebp
00407912 . 25 FF000000 and eax,0FF ; eax=用户名第一位
00407917 . 33ED xor ebp,ebp ; ebp=0
00407919 . 0C 32 or al,32 ; 用户名第一位和32取或
0040791B . 885424 2C mov byte ptr ss:[esp+2C],dl ; **计算得到第二位
0040791F . 99 cdq
00407920 . F7FB idiv ebx
00407922 . 8A46 01 mov al,byte ptr ds:[esi+1] ; 用户名第二位
00407925 . 25 FF000000 and eax,0FF
0040792A . 885424 30 mov byte ptr ss:[esp+30],dl ; **计算得到的第三位
0040792E . 0C 4D or al,4D
00407930 . 99 cdq
00407931 . F7FB idiv ebx
00407933 . 885424 34 mov byte ptr ss:[esp+34],dl ; **计算得到的第四位
00407937 . 33D2 xor edx,edx
00407939 . 85FF test edi,edi ; 用户名位数
0040793B . 7E 0C jle short midi2mp3.00407949
0040793D > 33C0 xor eax,eax
0040793F . 8A0416 mov al,byte ptr ds:[esi+edx]
00407942 . 03E8 add ebp,eax
00407944 . 42 inc edx
00407945 . 3BD7 cmp edx,edi
00407947 .^ 7C F4 jl short midi2mp3.0040793D ; 用户名每位的ascii码取和放入ebp

以上是通过用户名计算真码(也可能是中间代码)的过程。

00407949 > \8A51 01 mov dl,byte ptr ds:[ecx+1] ; 取假码第二位->dl
0040794C . 8A41 02 mov al,byte ptr ds:[ecx+2] ; 取假码第三位->al
0040794F . 8A19 mov bl,byte ptr ds:[ecx] ; 取假码第一位->bl
00407951 . 885424 14 mov byte ptr ss:[esp+14],dl ; 假码第二位
00407955 . 8A51 03 mov dl,byte ptr ds:[ecx+3]
00407958 . 884424 18 mov byte ptr ss:[esp+18],al ; 假码第三位
0040795C . 8A41 04 mov al,byte ptr ds:[ecx+4]
0040795F . 885424 1C mov byte ptr ss:[esp+1C],dl ; 假码第四位
00407963 . 8A51 05 mov dl,byte ptr ds:[ecx+5]
00407966 . 885C24 24 mov byte ptr ss:[esp+24],bl ; 假码第一位
0040796A . 884424 20 mov byte ptr ss:[esp+20],al ; 假码第五位
0040796E . 8A41 06 mov al,byte ptr ds:[ecx+6]
00407971 . 885424 12 mov byte ptr ss:[esp+12],dl ; 假码第六位
00407975 . 8B5424 24 mov edx,dword ptr ss:[esp+24]
00407979 . 8A49 07 mov cl,byte ptr ds:[ecx+7] ; 假码第八位
0040797C . 884424 13 mov byte ptr ss:[esp+13],al ; 假码第七位
00407980 . 8B4424 28 mov eax,dword ptr ss:[esp+28] ; 第一位比较
00407984 . 81E2 FF000000 and edx,0FF
0040798A . 83EA 30 sub edx,30
0040798D . 25 FF000000 and eax,0FF
00407992 . 3BC2 cmp eax,edx
00407994 . 75 6E jnz short midi2mp3.00407A04

这里有一个跳转,可以看到无论跳转与否都有可能到达注册成功的位置,由此可以初步推断出注册码可能有2个。继续往下看程序:

00407996 . 8B5424 14 mov edx,dword ptr ss:[esp+14] ; 第二位比较
0040799A . 8B4424 2C mov eax,dword ptr ss:[esp+2C]
0040799E . 81E2 FF000000 and edx,0FF
004079A4 . 25 FF000000 and eax,0FF
004079A9 . 83EA 30 sub edx,30
004079AC . 3BC2 cmp eax,edx
004079AE . 75 54 jnz short midi2mp3.00407A04
004079B0 . 8B5424 18 mov edx,dword ptr ss:[esp+18] ; 第三位比较
004079B4 . 8B4424 30 mov eax,dword ptr ss:[esp+30]
004079B8 . 81E2 FF000000 and edx,0FF
004079BE . 25 FF000000 and eax,0FF
004079C3 . 83EA 30 sub edx,30
004079C6 . 3BC2 cmp eax,edx
004079C8 . 75 3A jnz short midi2mp3.00407A04
004079CA . 8B5424 1C mov edx,dword ptr ss:[esp+1C] ; 第四位比较
004079CE . 8B4424 34 mov eax,dword ptr ss:[esp+34]
004079D2 . 81E2 FF000000 and edx,0FF
004079D8 . 25 FF000000 and eax,0FF
004079DD . 83EA 30 sub edx,30
004079E0 . 3BC2 cmp eax,edx
004079E2 . 75 20 jnz short midi2mp3.00407A04
004079E4 . 8BC5 mov eax,ebp ; 第五位比较
004079E6 . BE 0A000000 mov esi,0A
004079EB . 99 cdq
004079EC . F7FE idiv esi ; 第五位真码是ebp mod 10
004079EE . 8B4424 20 mov eax,dword ptr ss:[esp+20]
004079F2 . 25 FF000000 and eax,0FF
004079F7 . 83E8 30 sub eax,30
004079FA . 81E2 FF000000 and edx,0FF
00407A00 . 3BD0 cmp edx,eax
00407A02 . 74 40 je short midi2mp3.00407A44

由于在判断过程中esp的值一直都没有改变过,因此也可以往上翻看到比较的位数是第几位。比较的五位都已经在前面计算出来了,当前五位判定均正确之后就跳转到407A44即注册成功的位置。因此注册码的后三位其实可以随便写,只要前五位正确即可。
从上面的407994处判断第一位不正确的情况下会跳转到这里:

00407A04 > \B0 33 mov al,33
00407A06 . 3AD8 cmp bl,al
00407A08 . 0F85 97000000 jnz midi2mp3.00407AA5
00407A0E . 384424 14 cmp byte ptr ss:[esp+14],al
00407A12 . 0F85 8D000000 jnz midi2mp3.00407AA5
00407A18 . 384424 18 cmp byte ptr ss:[esp+18],al ; 前三位都是al=33
00407A1C . 0F85 83000000 jnz midi2mp3.00407AA5
00407A22 . 8A5424 1C mov dl,byte ptr ss:[esp+1C]
00407A26 . B0 36 mov al,36
00407A28 . 3AD0 cmp dl,al
00407A2A . 75 79 jnz short midi2mp3.00407AA5
00407A2C . 384424 20 cmp byte ptr ss:[esp+20],al ; 四、五位都是al=36
00407A30 . 75 73 jnz short midi2mp3.00407AA5
00407A32 . 807C24 12 31 cmp byte ptr ss:[esp+12],31 ; 第六位是31
00407A37 . 75 6C jnz short midi2mp3.00407AA5
00407A39 . 807C24 13 34 cmp byte ptr ss:[esp+13],34 ; 第七位是34
00407A3E . 75 65 jnz short midi2mp3.00407AA5
00407A40 . 3AC8 cmp cl,al ; 往前看,cl就是第八位,应该是al=36
00407A42 . 75 61 jnz short midi2mp3.00407AA5
00407A44 > 6A 00 push 0 ; /Arg3 = 00000000
00407A46 . 6A 00 push 0 ; |Arg2 = 00000000
00407A48 . 68 38AD4300 push midi2mp3.0043AD38 ; |Arg1 = 0043AD38 ASCII “Registration has succeeded!”
00407A4D . E8 D2060200 call midi2mp3.00428124 ; \midi2mp3.00428124

可以看到只要跳转到407AA5就是注册码错误,一位位比较可以得到另外一个固定的注册码33366146。

由上面的分析可以得出注册码有两个:
1、第一位是用户名第一位与4D取或之后除以0A的余数
第二位是用户名第二位与44取或之后除以0A的余数
第三位是用户名第一位与32取或之后除以0A的余数
第四位是用户名第二位与4D取或之后除以0A的余数
第五位是用户名各位ASCII码求和之后除以0A的余数
后面三位可以随便写
例如我的ID是ssfighter,注册码可以是79575888

2、还有一个固定注册码33366146

以上两个注册码均通过注册。



发表评论

昵称:  (必须)
邮件:  (必须)
网址: 
评论: