- UID
 - 37950
 
 注册时间2007-12-1
阅读权限30
最后登录1970-1-1
龙战于野 
  
 
 
 
TA的每日心情  | 难过 2022-2-6 09:25 | 
|---|
 
  签到天数: 6 天 [LV.2]偶尔看看I  
 | 
 
【破文标题】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载入,查找关键字符找到以下关键代码:- 00406456   .  53            push    ebx
 
 - 00406457   .  56            push    esi
 
 - 00406458   .  6A 01         push    1
 
 - 0040645A   .  8BD9          mov     ebx, ecx                         
 
 - 0040645C   .  E8 71AF0000   call    <jmp.&MFC42.#6334>
 
 - 00406461   .  8B43 64       mov     eax, dword ptr [ebx+64]          ;  注册名放入EAX
 
 - 00406464   .  8D5424 08     lea     edx, dword ptr [esp+8]
 
 - 00406468   .  2BD0          sub     edx, eax
 
 - 0040646A   >  8A08          mov     cl, byte ptr [eax]
 
 - 0040646C   .  880C02        mov     byte ptr [edx+eax], cl
 
 - 0040646F   .  40            inc     eax
 
 - 00406470   .  84C9          test    cl, cl
 
 - 00406472   .^ 75 F6         jnz     short 0040646A
 
 - 00406474   .  8B43 60       mov     eax, dword ptr [ebx+60]
 
 - 00406477   .  8D5424 48     lea     edx, dword ptr [esp+48]
 
 - 0040647B   .  2BD0          sub     edx, eax
 
 - 0040647D   >  8A08          mov     cl, byte ptr [eax]
 
 - 0040647F   .  880C02        mov     byte ptr [edx+eax], cl
 
 - 00406482   .  40            inc     eax
 
 - 00406483   .  84C9          test    cl, cl
 
 - 00406485   .^ 75 F6         jnz     short 0040647D
 
 - 00406487   .  68 5C814100   push    0041815C                         ; /既然这一段代码是核心算法部分,此处加载ether.dll,不得不让人生疑......
 
 - 0040648C   .  FF15 18314100 call    dword ptr [<&KERNEL32.LoadLibrar>; \LoadLibraryA
 
 - 00406492   .  8BF0          mov     esi, eax
 
 - 00406494   .  68 E0904100   push    004190E0                         ; /reg_code
 
 - 00406499   .  56            push    esi                              ; |hModule
 
 - 0040649A   .  FF15 14314100 call    dword ptr [<&KERNEL32.GetProcAdd>; \GetProcAddress
 
 - 004064A0   .  8D8C24 880000>lea     ecx, dword ptr [esp+88]          ;  这个地址是用来存放等会计算好的注册码的
 
 - 004064A7   .  8D5424 08     lea     edx, dword ptr [esp+8]           ;  用户名地址放入
 
 - 004064AB   .  51            push    ecx                              ;  ECX,EDX就是ether.dll中的ether.reg_code函数的两个参数
 
 - 004064AC   .  52            push    edx
 
 - 004064AD   .  FFD0          call    eax                              ;  ether.reg_code函数----求注册码的核心哦
 
 - 004064AF   .  83C4 08       add     esp, 8
 
 - 004064B2   .  56            push    esi                              ; /hLibModule
 
 - 004064B3   .  FF15 10314100 call    dword ptr [<&KERNEL32.FreeLibrar>; \FreeLibrary 释放DLL文件
 
 - 004064B9   .  8D8424 880000>lea     eax, dword ptr [esp+88]          ;  这里出现了真正的注册码
 
 - 004064C0   .  8D4C24 48     lea     ecx, dword ptr [esp+48]
 
 - 004064C4   .  50            push    eax
 
 - 004064C5   .  51            push    ecx
 
 - 004064C6   .  E8 45DCFFFF   call    00404110                         ;  此Call并非关键,这里是真假注册码的比较
 
 - 004064CB   .  83C4 08       add     esp, 8
 
 - 004064CE   .  85C0          test    eax, eax
 
 - 004064D0   .  0F85 DF000000 jnz     004065B5                         ;  关键跳转
 
 - 004064D6   >  8A4C04 08     mov     cl, byte ptr [esp+eax+8]
 
 - 004064DA   .  8888 F09A4100 mov     byte ptr [eax+419AF0], cl
 
 - 004064E0   .  40            inc     eax
 
 - 004064E1   .  84C9          test    cl, cl
 
 - 004064E3   .^ 75 F1         jnz     short 004064D6
 
 - 004064E5   .  33C0          xor     eax, eax
 
 - 004064E7   >  8A4C04 48     mov     cl, byte ptr [esp+eax+48]
 
 - 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大虾的汇编模板,在此做出说明并感谢)- KeyGen.inc头文件源码:
 
 - include windows.inc
 
 - include kernel32.inc
 
 - include user32.inc
 
 - include Comctl32.inc
 
 - include shell32.inc
 
  
- includelib kernel32.lib
 
 - includelib user32.lib
 
 - includelib Comctl32.lib
 
 - includelib shell32.lib
 
  
- DlgProc      PROTO  :HWND,:UINT,:WPARAM,:LPARAM
 
  
- .const
 
  
- MAIN_DIALOG      equ 101
 
 - DLG_ABOUT      equ 102
 
 - IDC_NAME      equ 1001
 
 - IDC_SN        equ 1002
 
 - IDC_GEN        equ 1005
 
 - IDC_EXIT      equ 1006
 
 - IDC_ABOUT      equ 1007
 
 - IDC_OK        equ 1008
 
 - ICON_MAIN      equ 10
 
  
- szError        db 'ether.dll文件未找到或者加载失败,注册机无法正常使用!',0
 
 - szDll          db 'ether.dll',0
 
 - szRegcode      db 'reg_code',0
 
 - .data
 
  
- szFormat      db '%08lX',0  ;跟踪进ether.dll可得知注册码的输出形式
 
 - error         db 'Please input your name!',0
 
  
- .data?
 
  
- hDllInstance      dd ?
 
 - lpRegcode         dd ?
 
 - hInstance         dd ?
 
 - username          dd ?
 
 - serial            dd ?
 
  复制代码 Keygen.Asm文件源码如下:- .386
 
 - .model flat, stdcall  ;32 bit memory model
 
 - option casemap :none  ;case sensitive
 
  
- include Keygen.inc
 
  
- .code
 
  
- start:
 
  
-   invoke GetModuleHandle,NULL
 
 -   mov  hInstance,eax
 
  
-   invoke InitCommonControls
 
 -   invoke DialogBoxParam,hInstance,MAIN_DIALOG,NULL,addr DlgProc,NULL
 
 -   invoke ExitProcess,0
 
  
- ;########################################################################
 
 - AboutProc proc hAWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
 
 -   
 
 -   mov  eax,uMsg
 
 -   .if eax == WM_INITDIALOG
 
 -     invoke LoadIcon,hInstance,ICON_MAIN
 
 -     invoke SendMessage, hAWin, WM_SETICON, ICON_SMALL, eax
 
 -   .elseif eax == WM_COMMAND
 
 -     mov eax,wParam
 
 -     .if eax == IDC_OK
 
 -       invoke EndDialog,hAWin,0
 
 -     .endif  
 
 -   .elseif eax == WM_CLOSE
 
 -   invoke EndDialog,hAWin,NULL
 
 -   .else
 
 -     mov    eax,FALSE
 
 -     ret
 
 -   .endif
 
 -   mov    eax,TRUE
 
 -   ret
 
  
- AboutProc endp
 
 - ;########################################################################
 
  
- DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
 
  
-     mov  eax,uMsg
 
 -     .if eax == WM_INITDIALOG
 
 -       invoke LoadLibrary,addr szDll
 
 -       .if eax
 
 -         mov hDllInstance,eax
 
 -         invoke GetProcAddress,hDllInstance,addr szRegcode
 
 -         mov lpRegcode,eax
 
 -       .else 
 
 -         invoke MessageBox,hWin,addr szError,NULL,MB_OK or MB_ICONWARNING
 
 -       .endif
 
 -       invoke LoadIcon,hInstance,ICON_MAIN
 
 -       invoke SendMessage, hWin, WM_SETICON, ICON_SMALL, eax
 
 -       pop edi
 
 -     .elseif eax == WM_COMMAND
 
 -       mov eax,wParam
 
 -       .if eax == IDC_GEN
 
 -         invoke GetDlgItemText,hWin,IDC_NAME, addr username, 255
 
 -         .if eax == 0
 
 -           invoke SetDlgItemText,hWin,IDC_SN,addr error
 
 -           ret                        
 
 -         .else
 
 -           push offset serial
 
 -           push offset username
 
 -           call lpRegcode                  
 
 -           invoke SetDlgItemText,hWin,IDC_SN,addr serial
 
 -           ret
 
 -         .endif
 
 -       .elseif eax == IDC_ABOUT
 
 -       invoke CreateDialogParam,hInstance,DLG_ABOUT,hWin,addr AboutProc,FALSE
 
 -         
 
 -       .elseif eax == IDC_EXIT
 
 -               .if hDllInstance
 
 -                 xor eax,eax
 
 -                 mov lpRegcode,eax
 
 -                 invoke FreeLibrary,hDllInstance
 
 -               .endif
 
 -         invoke    EndDialog,hWin,NULL
 
 -       .endif
 
 -       
 
 -     .elseif eax == WM_CLOSE
 
 -       invoke EndDialog,hWin,0
 
 -     .else
 
 -       mov    eax,FALSE
 
 -       ret
 
 -     .endif
 
 -   mov    eax,TRUE
 
 -   ret
 
  
- DlgProc endp
 
  
- end start
 
  复制代码 另外我把整个注册机的工程文件也全部打包上传(所有文件加一起还不到30K,注册机只有几Kb),方便大家跟踪练习。想看源码的朋友可以把文件夹解压到RadASM\Masm\Projects目录下,即可使用RadASM打开工程。 
     注意:请把注册机拷贝到软件根目录下运行或者把软件根目录中的ether.dll复制到注册机目录即可! 
 
[ 本帖最后由 playboysen 于 2008-9-15 11:21 编辑 ] |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |