爆破unabexcm5fl(已补上注册机)

系统 : Windows xp

程序 : unabexcm5fl

程序下载地址 :http://pan.baidu.com/s/1pJYaNUV

要求 : 爆破

使用工具 :OD 

可在“PEDIY CrackMe 2007”中查找关于此程序的破文,标题为“菜鸟必看的破解文章(2)-追出软件注册码”。

 

看上去是个很小的程序所以直接OD载入,对GetDlgItemTextA下断并运行程序,返回用户领空后的汇编指令如下:

0040106C  |> 6A 25         push    25                               ; /Count = 25 (37.)
0040106E  |.  68 24234000   push    00402324                         ; |Buffer = unabexcm.00402324
00401073  |.  6A 68         push    68                               ; |ControlID = 68 (104.)
00401075  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
00401078  |.  E8 F4000000   call    <jmp.&USER32.GetDlgItemTextA>    ; GetDlgItemTextA
0040107D  |.  6A 00         push    0                                ; /pFileSystemNameSize = NULL
0040107F  |.  6A 00         push    0                                ; |pFileSystemNameBuffer = NULL
00401081  |.  68 C8204000   push    004020C8                         ; |pFileSystemFlags = unabexcm.004020C8
00401086  |.  68 90214000   push    00402190                         ; |pMaxFilenameLength = unabexcm.00402190
0040108B  |.  68 94214000   push    00402194                         ; |pVolumeSerialNumber = unabexcm.00402194
00401090  |.  6A 32         push    32                               ; |MaxVolumeNameSize = 32 (50.)
00401092  |.  68 5C224000   push    0040225C                         ; |VolumeNameBuffer = unabexcm.0040225C
00401097  |.  6A 00         push    0                                ; |RootPathName = NULL
00401099  |.  E8 B5000000   call    <jmp.&KERNEL32.GetVolumeInformat>; GetVolumeInformationA
0040109E  |.  68 F3234000   push    004023F3                         ; /StringToAdd = "4562-ABEX"
004010A3  |.  68 5C224000   push    0040225C                         ; |ConcatString = "曙?
004010A8  |.  E8 94000000   call    <jmp.&KERNEL32.lstrcatA>         ; lstrcatA
004010AD  |.  B2 02         mov     dl, 2                            ;  ↑↑GetVolumeInformation获取磁盘信息
004010AF  |>  8305 5C224000>/add     dword ptr [40225C], 1           ;  存放卷标的内存每个字节+1
004010B6  |.  8305 5D224000>|add     dword ptr [40225D], 1
004010BD  |.  8305 5E224000>|add     dword ptr [40225E], 1
004010C4  |.  8305 5F224000>|add     dword ptr [40225F], 1
004010CB  |.  FECA          |dec     dl                              ;  循环两次
004010CD  |.^ 75 E0         jnz     short 004010AF                  ;  ↓‘L2C-5781’+累加处理之后的卷标名就是序列号啦。
004010CF  |.  68 FD234000   push    004023FD                         ; /StringToAdd = "L2C-5781"
004010D4  |.  68 00204000   push    00402000                         ; |ConcatString = "L2C-5781曙?
004010D9  |.  E8 63000000   call    <jmp.&KERNEL32.lstrcatA>         ; lstrcatA
004010DE  |.  68 5C224000   push    0040225C                         ; /StringToAdd = "曙?
004010E3  |.  68 00204000   push    00402000                         ; |ConcatString = "L2C-5781曙?
004010E8  |.  E8 54000000   call    <jmp.&KERNEL32.lstrcatA>         ; lstrcatA
004010ED  |.  68 24234000   push    00402324                         ; /String2 = "fewagweag"
004010F2  |.  68 00204000   push    00402000                         ; |String1 = "L2C-5781曙?
004010F7  |.  E8 51000000   call    <jmp.&KERNEL32.lstrcmpiA>        ; lstrcmpiA
004010FC  |.  83F8 00       cmp     eax, 0
004010FF  |.  74 16         je      short 00401117
00401101  |.  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401103  |.  68 34244000   push    00402434                         ; |Title = "Error!"
00401108  |.  68 3B244000   push    0040243B                         ; |Text = "The serial you entered is not correct!"
0040110D  |.  FF75 08       push    dword ptr [ebp+8]                ; |hOwner
00401110  |.  E8 56000000   call    <jmp.&USER32.MessageBoxA>        ; MessageBoxA
00401115  |.  EB 16         jmp     short 0040112D
00401117  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401119  |.  68 06244000   push    00402406                         ; |Title = "Well Done!"
0040111E  |.  68 11244000   push    00402411                         ; |Text = "Yep, you entered a correct serial!"
00401123  |.  FF75 08       push    dword ptr [ebp+8]                ; |hOwner
00401126  |.  E8 40000000   call    <jmp.&USER32.MessageBoxA>        ; MessageBoxA
0040112B  |.  EB 00         jmp     short 0040112D
0040112D  |$  6A 00         push    0                                ; /Result = 0
0040112F  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
00401132  |.  E8 22000000   call    <jmp.&USER32.EndDialog>          ; EndDialog
00401137  |.  C9            leave
00401138  .  C2 1000       retn    10

这里有个陌生的函数调用,其定义如下:

BOOL WINAPI GetVolumeInformation(
    _In_opt_   LPCTSTR lpRootPathName,
    _Out_opt_  LPTSTR lpVolumeNameBuffer,
    _In_       DWORD nVolumeNameSize,
    _Out_opt_  LPDWORD lpVolumeSerialNumber,
    _Out_opt_  LPDWORD lpMaximumComponentLength,
    _Out_opt_  LPDWORD lpFileSystemFlags,
    _Out_opt_  LPTSTR lpFileSystemNameBuffer,
    _In_       DWORD nFileSystemNameSize
);

这里主要就是获取程序所在磁盘的信息,比如本次在D盘下运行,就获取了卷标“软件”这个字串,再对字串做一些操作然后连接一个固定字串就是正确的序列号了。

这里,我们直接将4010FF处的指令修改为JNE,然后选择保存,这样爆破就完成了:

-------------------------------------------------------------------------------------------------------------------

后记:之前存放程序的盘卷标名是中文,所以该cm连接字符时出了问题,这次写出了注册机也是专门把卷标名“软件”改成了“SoftWarre”配合。

算法很简单,所以直接用c写一个无界面的注册机:

#include   <windows.h> 
#include   <stdio.h> 

int main(int argc,char **argv) 
{ 
    DWORD   VolumeSerialNumber; 
    char   VolumeName[256]; 
    GetVolumeInformation( NULL,VolumeName,12,&VolumeSerialNumber,NULL,NULL,NULL,10); 
        
    printf( "本程序所在盘的卷标:%s
 ",VolumeName); 
    VolumeName[0] += 2;
    VolumeName[1] += 2;
    VolumeName[2] += 2;
    VolumeName[3] += 2;

    printf( "经过累加之后的卷标:%s
 ",VolumeName); 

    char* Prefix = "L2C-5781";
    char* Suffix = "4562-ABEX";
    printf( "生成的序列号:%s%s%s
 ",Prefix,VolumeName,Suffix); 

    getchar();

    return   0; 
} 

运行效果:

原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5149245.html