• 标 题:olldbg小解音频转换工具ezConverter!入门级 (14千字)
  • 作 者:chenjiwl  
  • 时 间:2003-06-15 16:18:25
  • 链 接:http://bbs.pediy.com

软件名称:ezConverter 2.0.746(Microsoft Visual C++ 6.0)

使用工具:olldbg 1.09c 

方法:先暴破,再找注册码,生成注册文件

程度:初级

用peid查壳,没有加壳。使用的是VC6.0。比较好下手

首先试运行程序,发现未注册时启动时有提示窗口,这就是突破口。在程序的注册窗口中随便输入用户名(chenji)和注册码(abcdefg1234567),程序提示重新运行软件再进行注册检验。下面正式开始:

打开OLLDBG选择debug->select import libraries将MFC42.lib文件载入 ,破解此软件必须使用!

再载入ezConverter.exe文件,在CPU窗口点右键快捷菜单,选择search for-->Name(label) in current module或直接按ctrl+N。找到MFC42.#1199_AfxMessageBox和MFC.#1200_AfxMessageBox,在这两项上点右键选择set breakpoint on every reference,将每个引用这两个函数的语句都设断点,这两个函数就是显示提示窗口的。 按F9运行程序:很快就在00405791处中断:
00405791   .  E8 7>call            提示未注册信息
00405796   .  8D4C>lea     ecxdword ptr ss:[esp+8]
0040579A   .  C784>mov     dword ptr ss:[esp+AC4], -1
004057A5   .  E8 E>call    
004057AA   >  8BCE mov     ecxesi                                EZCONVER.004136E0
004057AC   .  E8 5>call    EZCONVER.00405A10
004057B1   .  57   push    edi
004057B2   .  8D4C>lea     ecxdword ptr ss:[esp+7C]
.
.
.
中断后,向上翻看发现有几个跳转语句,有两个内部调用可疑。有门!!!

004056AF   .  8BF1 mov     esiecx  先设个断点
004056B1   .  57   push    edi
004056B2   .  E8 7>call    
004056B7   .  83C4>add     esp, 4
004056BA   .  E8 6>call             ;初始化运行环境
004056BF   .  8BCE mov     ecxesi                                EZCONVER.004136E0
004056C1   .  E8 5>call    ;初始化运行环境
004056C6   .  8D86>lea     eaxdword ptr ds:[esi+C4]
004056CC   .  50   push    eax                                    /Buffer = 006CDB08
004056CD   .  68 F>push    0FF                                    |BufSize = FF (255.)
004056D2   .  FF15>call    near dword ptr ds:[<&KERNEL32.GetCurr>; \GetCurrentDirectoryA
004056D8   .  8BCE mov     ecxesi                                EZCONVER.004136E0
004056DA   .  E8 4>call    EZCONVER.00405E20   处理注册码的调用,F7跟进去
004056DF   .  84C0 test    alal
004056E1   .  0F85>jnz     EZCONVER.004057AA                     ;关键的跳转,一定要跳走
004056E7   .  57   push    edi                                    /Arg1 = 00000000
004056E8   .  8BCE mov     ecxesi                               |EZCONVER.004136E0
004056EA   .  E8 6>call    EZCONVER.00406450                      \EZCONVER.00406450
004056EF   .  B9 1>mov     ecx, 1E
004056F4   .  2BC8 sub     ecxeax
004056F6   .  83F9>cmp     ecx, -64
004056F9   .  898E>mov     dword ptr ds:[esi+1C4], ecx
004056FF   .  0F8C>jl      EZCONVER.004058BE
00405705   .  83F9>cmp     ecx, 1
00405708   .  7D 5>jge     short EZCONVER.0040575D
0040570A   .  57   push    edi
0040570B   .  8D4C>lea     ecxdword ptr ss:[esp+14]
0040570F   .  E8 2>call    EZCONVER.0040CF40
00405714   .  8D4C>lea     ecxdword ptr ss:[esp+10]
00405718   .  89BC>mov     dword ptr ss:[esp+AC4], edi
0040571F   .  E8 3>call    
00405724   .  8D4C>lea     ecxdword ptr ss:[esp+74]
00405728   .  C784>mov     dword ptr ss:[esp+AC4], 2
00405733   .  E8 5>call    
00405738   .  8D4C>lea     ecxdword ptr ss:[esp+70]
0040573C   .  C684>mov     byte ptr ss:[esp+AC4], 1
00405744   .  E8 4>call    
00405749   .  C784>mov     dword ptr ss:[esp+AC4], -1
00405754   .  8D4C>lea     ecxdword ptr ss:[esp+10]
00405758   .  E9 5>jmp     EZCONVER.004058B9
0040575D   >  8D4C>lea     ecxdword ptr ss:[esp+8]
00405761   .  E8 4>call    
00405766   .  8B8E>mov     ecxdword ptr ds:[esi+1C4]
0040576C   .  8D54>lea     edxdword ptr ss:[esp+8]
00405770   .  51   push    ecx
00405771   .  68 9>push    92
00405776   .  52   push    edx
00405777   .  C784>mov     dword ptr ss:[esp+AD0], 3
00405782   .  E8 9>call    
00405787   .  8B44>mov     eaxdword ptr ss:[esp+14]
0040578B   .  83C4>add     esp, 0C
0040578E   .  57   push    edi
0040578F   .  57   push    edi
00405790   .  50   push    eax
00405791   .  E8 7>call            提示未注册信息
00405796   .  8D4C>lea     ecxdword ptr ss:[esp+8]
0040579A   .  C784>mov     dword ptr ss:[esp+AC4], -1
004057A5   .  E8 E>call    
004057AA   >  8BCE mov     ecxesi                                EZCONVER.004136E0
004057AC   .  E8 5>call    EZCONVER.00405A10
004057B1   .  57   push    edi
004057B2   .  8D4C>lea     ecxdword ptr ss:[esp+7C]

转到004056AF处先设个断点,然后按ctrl+f2重新载入程序,再次运行在004056AF处停下来。用F8运行到004056DA后,再用F7跟进去(建议在004056DA处设个断点)。 跟进去后再用F8单步走,在00405EA8处得知软件的注册信息保存在erf.dat文件中。

00405E9C  |.  C7>mov     dword ptr ss:[esp+130], 0
00405EA7  |.  51 push    ecx                                     EZCONVER.004136E0
00405EA8  |.  68>push    EZCONVER.004133CC                       ASCII "%s\\erf.dat"
00405EAD  |.  52 push    edx                                     KERNEL32.BFFC9490
00405EAE  |.  E8>call    

再继续用F8往下走,在00405F93处发现了上次输入的用户名(chenji),看来跟的路是对的!!

00405F93  |.  8D>lea     edidword ptr ss:[esp+40]            ;发现了用户名
00405F97  |.  8B>mov     ecxebp
00405F99  |.  33>xor     eaxeax
00405F9B  |.  F2>repne   scas byte ptr es:[edi]
00405F9D  |.  F7>not     ecx
00405F9F  |.  49 dec     ecx        ;得到用户名的长度
00405FA0  |.  83>cmp     ecx, 1         如果是空的
00405FA3  |.  0F>jb      EZCONVER.00406165                      跳走就完完了

再继续用F8往下走,在00405FA9处发现了上次输入的注册码(abcdefg1234567),进行很基本的检查,同上

00405FA9  |.  8D>lea     edidword ptr ss:[esp+64] ;注册码
00405FAD  |.  8B>mov     ecxebp
00405FAF  |.  F2>repne   scas byte ptr es:[edi]
00405FB1  |.  F7>not     ecx
00405FB3  |.  49 dec     ecx
00405FB4  |.  83>cmp     ecx, 1
00405FB7  |.  0F>jb      EZCONVER.00406165                       跳走就完了

再继续用F8往下走,有一个判断语句,不用管一直走下去
00405FBD  |.  8D>lea     edidword ptr ss:[esp+40]
00405FC1  |.  8B>mov     ecxebp                           KERNEL32.BFF70000
00405FC3  |.  F2>repne   scas byte ptr es:[edi]
00405FC5  |.  8B>mov     ebxdword ptr ds:[<&USER32.Char>;  将用户名转为大写
00405FCB  |.  8B>mov     esiebp                           KERNEL32.BFF70000
00405FCD  |.  F7>not     ecx
00405FCF  |.  49 dec     ecx
00405FD0  |.  8B>mov     ediecx
00405FD2  |.  8D>lea     ecxdword ptr ss:[esp+40]
00405FD6  |.  51 push    ecx                               /StringOrChar = "."
00405FD7  |.  FF>call    near ebx                          \CharUpperA
00405FD9  |.  33>xor     ecxecx
00405FDB  |.  85>test    ediedi
00405FDD  |.  7E>jle     short EZCONVER.0040604A            可能要进行运算
00405FDF  |>  8B>/mov     eaxecx
00405FE1  |.  BD>|mov     ebp, 3
00405FE6  |.  99 |cdq
00405FE7  |.  F7>|idiv    ebp                               KERNEL32.BFF70000
00405FE9  |.  46 |inc     esi
00405FEA  |.  85>|test    edxedx                          Switch (cases 0..2)
00405FEC  |.  75>|jnz     short EZCONVER.00406005
00405FEE  |.  8A>|mov     albyte ptr ss:[esp+ecx+40]      Case 0 of switch 00405FEA
00405FF2  |.  0F>|movsx   edxal
00405FF5  |.  83>|sub     edx, 5
00405FF8  |.  83>|cmp     edx, 41
00405FFB  |.  7E>|jle     short EZCONVER.00406001
00405FFD  |.  2C>|sub     al, 5
00405FFF  |.  EB>|jmp     short EZCONVER.0040603B
00406001  |>  04>|add     al, 5
00406003  |.  EB>|jmp     short EZCONVER.0040603B
00406005  |>  83>|cmp     edx, 1
00406008  |.  75>|jnz     short EZCONVER.00406021
0040600A  |.  8A>|mov     albyte ptr ss:[esp+ecx+40]      Case 1 of switch 00405FEA
0040600E  |.  0F>|movsx   edxal
00406011  |.  83>|add     edx, 7
00406014  |.  83>|cmp     edx, 5A
00406017  |.  7D>|jge     short EZCONVER.0040601D
00406019  |.  04>|add     al, 7
0040601B  |.  EB>|jmp     short EZCONVER.0040603B
0040601D  |>  2C>|sub     al, 7
0040601F  |.  EB>|jmp     short EZCONVER.0040603B
00406021  |>  83>|cmp     edx, 2
00406024  |.  75>|jnz     short EZCONVER.00406042
00406026  |.  8A>|mov     albyte ptr ss:[esp+ecx+40]      Case 2 of switch 00405FEA
0040602A  |.  0F>|movsx   edxal
0040602D  |.  83>|sub     edx, 9
00406030  |.  83>|cmp     edx, 41
00406033  |.  7E>|jle     short EZCONVER.00406039
00406035  |.  2C>|sub     al, 9
00406037  |.  EB>|jmp     short EZCONVER.0040603B
00406039  |>  04>|add     al, 9
0040603B  |>  88>|mov     byte ptr ss:[esp+esi+88], al
00406042  |>  41 |inc     ecx                               Default case of switch 00405FEA
00406043  |.  3B>|cmp     ecxedi
00406045  |.^ 7C>\jl      short EZCONVER.00405FDF

一直F8向下走,有一大堆的浮点运算,看不过来,可能是想转移我们的注意力,再向下
00406047  |.  83>or      ebp, FFFFFFFF
0040604A  |>  DD>fld     qword ptr ds:[40FE00] ;浮点运算
00406050  |.  33>xor     eaxeax
00406052  |.  85>test    esiesi
00406054  |.  7E>jle     short EZCONVER.0040606D
00406056  |>  0F>/movsx   ecxbyte ptr ss:[esp+eax+88]
0040605E  |.  89>|mov     dword ptr ss:[esp+14], ecx
00406062  |.  40 |inc     eax
00406063  |.  DB>|fild    dword ptr ss:[esp+14] ;浮点运算
00406067  |.  3B>|cmp     eaxesi
00406069  |.  DE>|faddp   st(1), st ;浮点运算
0040606B  |.^ 7C>\jl      short EZCONVER.00406056
0040606D  |>  D9>fld     st ;浮点运算,完全是无聊的举动
0040606F  |.  D9>fsin ;浮点运算,完全是无聊的举动
00406071  |.  D9>fcos ;浮点运算,完全是无聊的举动
00406073  |.  D9>fsin ;浮点运算,完全是无聊的举动
00406075  |.  D9>fcos ;浮点运算,完全是无聊的举动
00406077  |.  D9>fsin ;浮点运算,完全是无聊的举动
00406079  |.  DD>fst     qword ptr ss:[esp+14] ;浮点运算,完全是无聊的举动
0040607D  |.  DC>fcomp   qword ptr ds:[40FE00] ;浮点运算,完全是无聊的举动
00406083  |.  DF>fstsw   ax
00406085  |.  F6>test    ah, 1
00406088  |.  74>je      short EZCONVER.004060AD
0040608A  |>  DC>/fmul    qword ptr ds:[40FDF8] ;浮点运算
00406090  |.  D9>|fld     st
00406092  |.  D9>|fsin ;浮点运算,完全是无聊的举动
00406094  |.  D9>|fcos ;浮点运算,完全是无聊的举动
00406096  |.  D9>|fsin ;浮点运算,完全是无聊的举动
00406098  |.  D9>|fcos ;浮点运算,完全是无聊的举动
0040609A  |.  D9>|fsin ;浮点运算,完全是无聊的举动
0040609C  |.  DD>|fst     qword ptr ss:[esp+14] ;浮点运算,完全是无聊的举动
004060A0  |.  DC>|fcomp   qword ptr ds:[40FE00] ;浮点运算,完全是无聊的举动
004060A6  |.  DF>|fstsw   ax ;浮点运算,完全是无聊的举动
004060A8  |.  F6>|test    ah, 1
004060AB  |.^ 75>\jnz     short EZCONVER.0040608A
004060AD  |> \8B>mov     edxdword ptr ss:[esp+18]
004060B1  |.  8B>mov     eaxdword ptr ss:[esp+14]
004060B5  |.  52 push    edx
004060B6  |.  50 push    eax                               / <%.14f> = 0.0
004060B7  |.  8D>lea     ecxdword ptr ss:[esp+E0]        |
004060BE  |.  68>push    EZCONVER.004133C4                 |format = "%.14f"
004060C3  |.  51 push    ecx                               |s = 0000000E
004060C4  |.  DD>fstp    st                                |
004060C6  |.  FF>call    near dword ptr ds:[<&MSVCRT.spri>; \sprintf
004060CC  |.  8D>lea     edidword ptr ss:[esp+E8]
004060D3  |.  8B>mov     ecxebp
004060D5  |.  33>xor     eaxeax
004060D7  |.  83>add     esp, 10
004060DA  |.  33>xor     edxedx
004060DC  |.  F2>repne   scas byte ptr es:[edi]
004060DE  |.  F7>not     ecx
004060E0  |.  49 dec     ecx
004060E1  |.  83>sub     ecx, 2
004060E4  |.  74>je      short EZCONVER.0040610D
004060E6  |>  8A>/mov     albyte ptr ss:[esp+edx+DA]
004060ED  |.  8D>|lea     edidword ptr ss:[esp+D8]
004060F4  |.  04>|add     al, 41
004060F6  |.  8B>|mov     ecxebp
004060F8  |.  88>|mov     byte ptr ss:[esp+edx+88], al
004060FF  |.  33>|xor     eaxeax
00406101  |.  42 |inc     edx
00406102  |.  F2>|repne   scas byte ptr es:[edi]
00406104  |.  F7>|not     ecx
00406106  |.  83>|add     ecx, -3
00406109  |.  3B>|cmp     edxecx
0040610B  |.^ 72>\jb      short EZCONVER.004060E6

运行到0040610D时,请注意dword ptr ss:[esp+88]中的值。在CPU窗口下的小窗口中显示:
stack address=006AF1FC   在这一行上点右键,选择follow address in dump。在内存窗口中将显示:
wszysyvzusurvx           ;很怀疑这个字符串是正确的注册码。

0040610D  |> \8D>lea     ecxdword ptr ss:[esp+88]         可能是正确的注册码
00406114  |.  C6>mov     byte ptr ss:[esp+esi+88], 0
0040611C  |.  51 push    ecx
0040611D  |.  FF>call    near ebx    ;转换成大写字母
0040611F  |.  8D>lea     edidword ptr ss:[esp+64]        这里是自己输入的注册码
00406123  |.  8B>mov     ecxebp
00406125  |.  33>xor     eaxeax
00406127  |.  8D>lea     esidword ptr ss:[esp+88]
0040612E  |.  F2>repne   scas byte ptr es:[edi]
00406130  |.  F7>not     ecx
00406132  |.  49 dec     ecx
00406133  |.  8D>lea     edidword ptr ss:[esp+64]
00406137  |.  33>xor     edxedx
00406139  |.  89>mov     dword ptr ss:[esp+130], ebp
经过上面的变换"wszysyvzusurvx"就成了"WSZYS vzusurvx"了。中间不是空格,而是二进制0x00。

再用F8走到 00406140 这里是很关键的一个串比较语句!!!而到了00406146这个跳转语句更是关键,一定不能跳。如果想暴破就将这条语句改为nop就可以了。具体方法就不说了

00406140  |.  F3>repe    cmps byte ptr es:[edi], byte ptr>  ;关键的比较
00406142  |.  8D>lea     ecxdword ptr ss:[esp+10]
00406146      75>jnz     short EZCONVER.00406170              关键关键!万万跳不得
00406148  |.  E8>call     
0040614D  |.  B0>mov     al, 1
0040614F  |.  8B>mov     ecxdword ptr ss:[esp+128]
00406156  |.  64>mov     dword ptr fs:[0], ecx
0040615D  |.  5F pop     edi
0040615E  |.  5E pop     esi
0040615F  |.  5D pop     ebp
00406160  |.  5B pop     ebx
00406161  |.  8B>mov     espebp
00406163  |.  5D pop     ebp
00406164  |.  C3 retn
00406165  |>  89>mov     dword ptr ss:[esp+130], ebp
0040616C  |>  8D>lea     ecxdword ptr ss:[esp+10]
00406170  |>  E8>call        ;进来就完蛋了
00406175  |>  8B>mov     ecxdword ptr ss:[esp+128]
0040617C  |.  5F pop     edi
0040617D  |.  32>xor     alal
0040617F  |.  64>mov     dword ptr fs:[0], ecx
00406186  |.  5E pop     esi
00406187  |.  5D pop     ebp
00406188  |.  5B pop     ebx
00406189  |.  8B>mov     espebp
0040618B  |.  5D pop     ebp
0040618C  \.  C3 retn

"WSZYS vzusurvx"就是正确的注册码!
建议:在00406140这个关键比较前,将内存窗口中自己先前输入的注册码(在正确的注册码的上面一点)改成正确的注册码,然后实验一下不改语句而注册成功的效果。这样会在erf.dat文件中写入了正确的注册信息,以后就不要再进行注册和修改了,只需要保存erf.dat这个注册授权文件中可以了。

(注意:程序在后面会进行5次注册码的校验)
 
注册码的运算过程没有进行分析,只想很快得到效果!目标是最重要的!  

先收工了!用时30分钟。今天我在值班很无聊!


CCWW