飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 6986|回复: 6

[原创] MP3 WAV OGG WMA AC3 to CD Burner算法分析+简单逆向汇编

[复制链接]
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2008-9-15 11:18:19 | 显示全部楼层 |阅读模式
    【破文标题】MP3 WAV OGG WMA AC3 to CD Burner算法分析+简单逆向汇编
    【破文作者】Playbo ysen
    【作者邮箱】playb [email protected]
    【作者主页】playbo ysen2.photo.163.com
    破解工具】PEiD,OD
    【破解平台】Windows XP
    【软件名称】MP3 WAV OGG WMA AC3 to CD Burner V.1.2.33: (09/09/2008)
    【软件大小】2.38 MB
    【软件类别】国外软件/光碟工具
    【软件授权】共享版
    【软件语言】英文
    【更新时间】2008-09-09
    【原版下载】http://www.divxtodvd.net/
    【保护方式】注册码
    【软件简介】烧录CD光盘,支持 MP3 WAV WMA OGG AC3 音频格式,支持650M(74min),700M(80min),730M(83min)光盘,支持所有CDRs,支持大部分IDE,USB,IEEE1384,SCSI CD 设备,内置高速烧录 CD 光盘引擎!
    【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享:)
    初学破解与编程,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
    --------------------------------------------------------------
    【破解内容】
    --------------------------------------------------------------

        前几天闲来无事,找了两本汇编语言程序设计来玩玩,主要目的当然并非学习汇编程序设计,只是平时分析算法和程序逆向如果不懂汇编举步维艰,算是大四每天自习或者茶余饭后的消遣,今天来分析一个软件,然后用汇编语言搞个注册机,算是这十来天的书没有白看,同时也给大家开阔一下视野,提供算法分析或者dll文件注册方式破解的另外一种思路吧~~

        打开软件试运行,知道软件是注册名加注册码的保护方式,有错误提示,未加壳,编写语言VC++。OK,Come on...
        OD载入,查找关键字符找到以下关键代码:
    1. 00406456   .  53            push    ebx
    2. 00406457   .  56            push    esi
    3. 00406458   .  6A 01         push    1
    4. 0040645A   .  8BD9          mov     ebx, ecx                        
    5. 0040645C   .  E8 71AF0000   call    <jmp.&MFC42.#6334>
    6. 00406461   .  8B43 64       mov     eax, dword ptr [ebx+64]          ;  注册名放入EAX
    7. 00406464   .  8D5424 08     lea     edx, dword ptr [esp+8]
    8. 00406468   .  2BD0          sub     edx, eax
    9. 0040646A   >  8A08          mov     cl, byte ptr [eax]
    10. 0040646C   .  880C02        mov     byte ptr [edx+eax], cl
    11. 0040646F   .  40            inc     eax
    12. 00406470   .  84C9          test    cl, cl
    13. 00406472   .^ 75 F6         jnz     short 0040646A
    14. 00406474   .  8B43 60       mov     eax, dword ptr [ebx+60]
    15. 00406477   .  8D5424 48     lea     edx, dword ptr [esp+48]
    16. 0040647B   .  2BD0          sub     edx, eax
    17. 0040647D   >  8A08          mov     cl, byte ptr [eax]
    18. 0040647F   .  880C02        mov     byte ptr [edx+eax], cl
    19. 00406482   .  40            inc     eax
    20. 00406483   .  84C9          test    cl, cl
    21. 00406485   .^ 75 F6         jnz     short 0040647D
    22. 00406487   .  68 5C814100   push    0041815C                         ; /既然这一段代码是核心算法部分,此处加载ether.dll,不得不让人生疑......
    23. 0040648C   .  FF15 18314100 call    dword ptr [<&KERNEL32.LoadLibrar>; \LoadLibraryA
    24. 00406492   .  8BF0          mov     esi, eax
    25. 00406494   .  68 E0904100   push    004190E0                         ; /reg_code
    26. 00406499   .  56            push    esi                              ; |hModule
    27. 0040649A   .  FF15 14314100 call    dword ptr [<&KERNEL32.GetProcAdd>; \GetProcAddress
    28. 004064A0   .  8D8C24 880000>lea     ecx, dword ptr [esp+88]          ;  这个地址是用来存放等会计算好的注册码的
    29. 004064A7   .  8D5424 08     lea     edx, dword ptr [esp+8]           ;  用户名地址放入
    30. 004064AB   .  51            push    ecx                              ;  ECX,EDX就是ether.dll中的ether.reg_code函数的两个参数
    31. 004064AC   .  52            push    edx
    32. 004064AD   .  FFD0          call    eax                              ;  ether.reg_code函数----求注册码的核心哦
    33. 004064AF   .  83C4 08       add     esp, 8
    34. 004064B2   .  56            push    esi                              ; /hLibModule
    35. 004064B3   .  FF15 10314100 call    dword ptr [<&KERNEL32.FreeLibrar>; \FreeLibrary 释放DLL文件
    36. 004064B9   .  8D8424 880000>lea     eax, dword ptr [esp+88]          ;  这里出现了真正的注册码
    37. 004064C0   .  8D4C24 48     lea     ecx, dword ptr [esp+48]
    38. 004064C4   .  50            push    eax
    39. 004064C5   .  51            push    ecx
    40. 004064C6   .  E8 45DCFFFF   call    00404110                         ;  此Call并非关键,这里是真假注册码的比较
    41. 004064CB   .  83C4 08       add     esp, 8
    42. 004064CE   .  85C0          test    eax, eax
    43. 004064D0   .  0F85 DF000000 jnz     004065B5                         ;  关键跳转
    44. 004064D6   >  8A4C04 08     mov     cl, byte ptr [esp+eax+8]
    45. 004064DA   .  8888 F09A4100 mov     byte ptr [eax+419AF0], cl
    46. 004064E0   .  40            inc     eax
    47. 004064E1   .  84C9          test    cl, cl
    48. 004064E3   .^ 75 F1         jnz     short 004064D6
    49. 004064E5   .  33C0          xor     eax, eax
    50. 004064E7   >  8A4C04 48     mov     cl, byte ptr [esp+eax+48]
    51. 004064EB   .  8888 F0994100 mov     byte ptr [eax+4199F0], cl
    复制代码
    经过以上的分析,很明显ether.dll中的ether.reg_code导出函数就是此dll文件提供给软件注册的一个接口,其中需要两个参数:一个是输入的用户名;一个是用来储存计算好的注册码的变量(或地址)
        既然如此,我们就不看软件具体的算法(从004064AD进入ether.dll可以看到,懒婆娘的裹脚布——又臭又长的一堆算法),来直接写注册机
        首先,我们应该预设等会要用到的一些常量和变量,这些可以写到.const、.data或者.data?段;
        其次,我们需要实现Dll文件的加载。在程序初始化的时候我们使用LoadLibrary函数,如果加载成功再用GetProcAddress函数来得到ether.reg_code的地址,如果加载失败则提示错误!
        最后,就可以根据我们刚才反汇编时得出的ether.reg_code导出函数的参数入栈方式来直接做注册机!当然,求出注册码不可以得意忘形哦,最后不要忘了FreeLibrary来释放掉刚才加载DLL文件。
    关键源码如下:(此注册机使用了CCDebugger大虾的汇编模板,在此做出说明并感谢)
    1. KeyGen.inc头文件源码:
    2. include windows.inc
    3. include kernel32.inc
    4. include user32.inc
    5. include Comctl32.inc
    6. include shell32.inc

    7. includelib kernel32.lib
    8. includelib user32.lib
    9. includelib Comctl32.lib
    10. includelib shell32.lib

    11. DlgProc      PROTO  :HWND,:UINT,:WPARAM,:LPARAM

    12. .const

    13. MAIN_DIALOG      equ 101
    14. DLG_ABOUT      equ 102
    15. IDC_NAME      equ 1001
    16. IDC_SN        equ 1002
    17. IDC_GEN        equ 1005
    18. IDC_EXIT      equ 1006
    19. IDC_ABOUT      equ 1007
    20. IDC_OK        equ 1008
    21. ICON_MAIN      equ 10

    22. szError        db 'ether.dll文件未找到或者加载失败,注册机无法正常使用!',0
    23. szDll          db 'ether.dll',0
    24. szRegcode      db 'reg_code',0
    25. .data

    26. szFormat      db '%08lX',0  ;跟踪进ether.dll可得知注册码的输出形式
    27. error         db 'Please input your name!',0

    28. .data?

    29. hDllInstance      dd ?
    30. lpRegcode         dd ?
    31. hInstance         dd ?
    32. username          dd ?
    33. serial            dd ?
    复制代码
    Keygen.Asm文件源码如下:
    1. .386
    2. .model flat, stdcall  ;32 bit memory model
    3. option casemap :none  ;case sensitive

    4. include Keygen.inc

    5. .code

    6. start:

    7.   invoke GetModuleHandle,NULL
    8.   mov  hInstance,eax

    9.   invoke InitCommonControls
    10.   invoke DialogBoxParam,hInstance,MAIN_DIALOG,NULL,addr DlgProc,NULL
    11.   invoke ExitProcess,0

    12. ;########################################################################
    13. AboutProc proc hAWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    14.   
    15.   mov  eax,uMsg
    16.   .if eax == WM_INITDIALOG
    17.     invoke LoadIcon,hInstance,ICON_MAIN
    18.     invoke SendMessage, hAWin, WM_SETICON, ICON_SMALL, eax
    19.   .elseif eax == WM_COMMAND
    20.     mov eax,wParam
    21.     .if eax == IDC_OK
    22.       invoke EndDialog,hAWin,0
    23.     .endif  
    24.   .elseif eax == WM_CLOSE
    25.   invoke EndDialog,hAWin,NULL
    26.   .else
    27.     mov    eax,FALSE
    28.     ret
    29.   .endif
    30.   mov    eax,TRUE
    31.   ret

    32. AboutProc endp
    33. ;########################################################################

    34. DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

    35.     mov  eax,uMsg
    36.     .if eax == WM_INITDIALOG
    37.       invoke LoadLibrary,addr szDll
    38.       .if eax
    39.         mov hDllInstance,eax
    40.         invoke GetProcAddress,hDllInstance,addr szRegcode
    41.         mov lpRegcode,eax
    42.       .else
    43.         invoke MessageBox,hWin,addr szError,NULL,MB_OK or MB_ICONWARNING
    44.       .endif
    45.       invoke LoadIcon,hInstance,ICON_MAIN
    46.       invoke SendMessage, hWin, WM_SETICON, ICON_SMALL, eax
    47.       pop edi
    48.     .elseif eax == WM_COMMAND
    49.       mov eax,wParam
    50.       .if eax == IDC_GEN
    51.         invoke GetDlgItemText,hWin,IDC_NAME, addr username, 255
    52.         .if eax == 0
    53.           invoke SetDlgItemText,hWin,IDC_SN,addr error
    54.           ret                        
    55.         .else
    56.           push offset serial
    57.           push offset username
    58.           call lpRegcode                  
    59.           invoke SetDlgItemText,hWin,IDC_SN,addr serial
    60.           ret
    61.         .endif
    62.       .elseif eax == IDC_ABOUT
    63.       invoke CreateDialogParam,hInstance,DLG_ABOUT,hWin,addr AboutProc,FALSE
    64.         
    65.       .elseif eax == IDC_EXIT
    66.               .if hDllInstance
    67.                 xor eax,eax
    68.                 mov lpRegcode,eax
    69.                 invoke FreeLibrary,hDllInstance
    70.               .endif
    71.         invoke    EndDialog,hWin,NULL
    72.       .endif
    73.       
    74.     .elseif eax == WM_CLOSE
    75.       invoke EndDialog,hWin,0
    76.     .else
    77.       mov    eax,FALSE
    78.       ret
    79.     .endif
    80.   mov    eax,TRUE
    81.   ret

    82. DlgProc endp

    83. end start
    复制代码
    另外我把整个注册机的工程文件也全部打包上传(所有文件加一起还不到30K,注册机只有几Kb),方便大家跟踪练习。想看源码的朋友可以把文件夹解压到RadASM\Masm\Projects目录下,即可使用RadASM打开工程。
         注意:请把注册机拷贝到软件根目录下运行或者把软件根目录中的ether.dll复制到注册机目录即可!

    [ 本帖最后由 playboysen 于 2008-9-15 11:21 编辑 ]

    Keygen.rar

    2.01 KB, 下载次数: 9, 下载积分: 飘云币 -2 枚

    Keygen工程文件.rar

    6.8 KB, 下载次数: 8, 下载积分: 飘云币 -2 枚

    评分

    参与人数 1飘云币 +120 收起 理由
    Nisy + 120 PYG有你更精彩!

    查看全部评分

    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-9-17 13:19:03 | 显示全部楼层

    很强悍~!!!!!!!!

    /:014 /:014
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 555 天

    [LV.9]以坛为家II

    发表于 2008-9-18 19:30:42 | 显示全部楼层
    看见算法就晕!/:L
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-9-18 20:49:15 | 显示全部楼层
    很费解/:023
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-9-18 21:11:25 | 显示全部楼层
    很强悍,只会一点点爆破~~~~~~
    PYG19周年生日快乐!
  • TA的每日心情
    难过
    2022-2-6 09:25
  • 签到天数: 6 天

    [LV.2]偶尔看看I

     楼主| 发表于 2008-9-19 10:51:13 | 显示全部楼层
    原帖由 天使的锁链 于 2008-9-18 20:49 发表
    很费解/:023


    其实这么长的汇编代码关键部分只有十几行的,其他代码都是模板自动生成的,因为不知道为什么我们论坛发贴无法设置粗体字,郁闷,就没有标出来的,关键部分如下(下面所用到的变量的声明在Keygen.inc头文件里面):

    加载DLL文件:
    1. .if eax == WM_INITDIALOG
    2.       invoke LoadLibrary,addr szDll
    3.       .if eax
    4.         mov hDllInstance,eax
    5.         invoke GetProcAddress,hDllInstance,addr szRegcode
    6.         mov lpRegcode,eax
    7.       .else
    8.         invoke MessageBox,hWin,addr szError,NULL,MB_OK or MB_ICONWARNING
    9.       .endif
    复制代码
    取用户名并且调用DLL函数源码如下:
    1. .elseif eax == WM_COMMAND
    2.       mov eax,wParam
    3.       .if eax == IDC_GEN
    4.         invoke GetDlgItemText,hWin,IDC_NAME, addr username, 255
    5.         .if eax == 0
    6.           invoke SetDlgItemText,hWin,IDC_SN,addr error
    7.           ret                        
    8.         .else
    9.           push offset serial
    10.           push offset username
    11.           call lpRegcode                  
    12.           invoke SetDlgItemText,hWin,IDC_SN,addr serial
    13.           ret
    14.         .endif
    复制代码
    释放DLL文件的代码:
    1. .elseif eax == IDC_EXIT
    2.               .if hDllInstance
    3.                 xor eax,eax
    4.                 mov lpRegcode,eax
    5.                 invoke FreeLibrary,hDllInstance
    6.               .endif
    7.         invoke    EndDialog,hWin,NULL
    8.       .endif
    复制代码

    [ 本帖最后由 playboysen 于 2008-9-19 10:52 编辑 ]
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-9-19 15:31:20 | 显示全部楼层
    看了这么代码,头就晕乎乎的!
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表