首页
社区
课程
招聘
[原创]HappytownCrackme006的分析及注册机源码
发表于: 2006-10-31 13:32 4357

[原创]HappytownCrackme006的分析及注册机源码

2006-10-31 13:32
4357

下面是HappyTown的Crackme006 注册分析
这个Crackme有点意思,就把算法分析过程也贴上来了,呵!
不过这次认了一点真,把汇编码仔细检查了一下,自以为是最精炼的了。
没什么好东东,只是在做作业,就着这几天空闲时多,自娱自乐型。

ASM程序,用典型的断点:
GetDlgItemTextA----取文本函数

0040122A    68 04314000        push CrackMe_.00403104                      ; ASCII "wofan"
0040122F    68 EC030000        push 3EC
00401234    FF75 08            push dword ptr ss:[ebp+8]
00401237    E8 FC000000        call <jmp.&user32.GetDlgItemTextA>
0040123C    8945 F4            mov dword ptr ss:[ebp-C],eax
0040123F    837D F4 04         cmp dword ptr ss:[ebp-C],4                  ; 注册名不少于4位
00401243    73 04              jnb short CrackMe_.00401249
00401245    C9                 leave
00401246    C2 1000            retn 10
00401249    68 04314000        push CrackMe_.00403104                      ; ASCII "wofan"
0040124E    E8 E3FDFFFF        call CrackMe_.00401036                      ; 计算
00401253    6A 01              push 1                                      ; 压栈一个数:1
00401255    50                 push eax                                    ; 计算值压栈
00401256    E8 26FEFFFF        call CrackMe_.00401081                      ; 把计算值ROL一次
0040125B    0B45 F0            or eax,dword ptr ss:[ebp-10]                ; 加上一个数:44886452 ,得看看这个数是怎么来的,应该不会是个常数?
0040125E    25 FFFFFF0F        and eax,0FFFFFFF                            ; 去掉最高位
00401263    8945 EC            mov dword ptr ss:[ebp-14],eax               ; 保存
00401266    33C9               xor ecx,ecx
00401268    33D2               xor edx,edx
0040126A    8D35 00304000      lea esi,dword ptr ds:[403000]
00401270    8B45 EC            mov eax,dword ptr ss:[ebp-14]
00401273    8945 EC            mov dword ptr ss:[ebp-14],eax
00401276    6A 10              push 10                                     ; 压一个数10
00401278    50                 push eax                                    ; 计算值
00401279    E8 82FDFFFF        call CrackMe_.00401000                      ; 原来是把计算值对10取余,保存余数
0040127E    8BC8               mov ecx,eax
00401280    8D3D 73204000      lea edi,dword ptr ds:[402073]               ; 一个小小的字串:071362de9f8ab45c
00401286    8A0439             mov al,byte ptr ds:[ecx+edi]                ; 凭那个余数,从字串中取得注册码
00401289    8806               mov byte ptr ds:[esi],al                    ; 保存注册码
0040128B    8B45 EC            mov eax,dword ptr ss:[ebp-14]               ; 计算值
0040128E    6A 04              push 4                                      ; 压一个数4
00401290    50                 push eax
00401291    E8 86FDFFFF        call CrackMe_.0040101C                      ; 对4取余,保存余数
00401296    8945 EC            mov dword ptr ss:[ebp-14],eax
00401299    0BC0               or eax,eax                                  ; 看看除4之后,是否已经除尽了,除尽了也就结束了
0040129B    74 04              je short CrackMe_.004012A1
0040129D    46                 inc esi                                     ; 移动注册码指针
0040129E    47                 inc edi                                     ; 这是那个字串,移动指针有什么用呀!这里应该是个错误。
0040129F  ^ EB D2              jmp short CrackMe_.00401273                 ; 循环处理注册名
004012A1    68 00010000        push 100
004012A6    8D85 ECFEFFFF      lea eax,dword ptr ss:[ebp-114]
004012AC    50                 push eax
004012AD    68 ED030000        push 3ED                                    ; 3ED是控件ID号,这些已经很熟悉了
004012B2    FF75 08            push dword ptr ss:[ebp+8]
004012B5    E8 7E000000        call <jmp.&user32.GetDlgItemTextA>
004012BA    0BC0               or eax,eax                                  ; 注册码不能为空
004012BC    75 04              jnz short CrackMe_.004012C2
004012BE    C9                 leave
004012BF    C2 1000            retn 10
004012C2    68 00304000        push CrackMe_.00403000                      ; ASCII "5cefd"
004012C7    8D85 ECFEFFFF      lea eax,dword ptr ss:[ebp-114]              ; 假注册码
004012CD    50                 push eax
004012CE    E8 53000000        call <jmp.&kernel32.lstrcmpA>
004012D3    0BC0               or eax,eax
004012D5    75 18              jnz short CrackMe_.004012EF
004012D7    6A 40              push 40
004012D9    68 08214000        push CrackMe_.00402108                      ; ASCII "Congratulations"
004012DE    68 F9204000        push CrackMe_.004020F9                      ; ASCII "GOOD JOB, MAN!"

============================计算==========================================================
00401039    8B75 08            mov esi,dword ptr ss:[ebp+8]
0040103C    FC                 cld                                         ; 清方向标志
0040103D    33D2               xor edx,edx
0040103F    B8 01000000        mov eax,1                                   ; 累加器置初值1
00401044    0FB60E             movzx ecx,byte ptr ds:[esi]                 ; 注册名ASCII码送ECX
00401047    46                 inc esi                                     ; 移动指针
00401048    0BC9               or ecx,ecx                                  ; 不为零,表示有效,还不应该结束,因为:0 or 0=0
0040104A    74 06              je short CrackMe_.00401052
0040104C    F7E1               mul ecx                                     ; mul:注册名ASCII乘累加值
0040104E    03C2               add eax,edx                                 ; 累加,如果产生高32位数,也得加上来
00401050  ^ EB F2              jmp short CrackMe_.00401044                 ; 继续循环
00401052    C9                 leave                                       ; 结束
===========================================================================================

===========================================================================================
==========加上一个数:44886452 ,得看看这个数是怎么来的,应该不会是个常数?=================
===========================================================================================
向上可以找到:GetVolumeInformationA  
莫非与它有关?
重新下断。

004010C2    55                 push ebp
004010C3    8BEC               mov ebp,esp
004010C5    81C4 F8FEFFFF      add esp,-108
004010CB    53                 push ebx
004010CC    57                 push edi
004010CD    56                 push esi
004010CE    68 80000000        push 80
004010D3    8D85 F8FEFFFF      lea eax,dword ptr ss:[ebp-108]
004010D9    50                 push eax
004010DA    8D85 78FFFFFF      lea eax,dword ptr ss:[ebp-88]
004010E0    50                 push eax
004010E1    68 FF000000        push 0FF
004010E6    8D85 7CFFFFFF      lea eax,dword ptr ss:[ebp-84]                 ;需要的就是这个参数
004010EC    50                 push eax
004010ED    68 80000000        push 80
004010F2    8D45 80            lea eax,dword ptr ss:[ebp-80]
004010F5    50                 push eax
004010F6    FF75 08            push dword ptr ss:[ebp+8]
004010F9    E8 22020000        call <jmp.&kernel32.GetVolumeInformationA>    ;这就是获取磁盘信息的函数。
004010FE    8B85 7CFFFFFF      mov eax,dword ptr ss:[ebp-84]                 
----------------------------------------------
004011D0    68 43204000        push CrackMe_.00402043               ; ASCII "c:\"
004011D5    E8 E8FEFFFF        call CrackMe_.004010C2               ; 取C盘信息
004011DA    8945 FC            mov dword ptr ss:[ebp-4],eax
004011DD    6A 05              push 5                               ; push 5
004011DF    FF75 FC            push dword ptr ss:[ebp-4]            ; 参数
004011E2    E8 B1FEFFFF        call CrackMe_.00401098               ; 对它进行移位SHL。移5次
004011E7    6A 0D              push 0D                              ; push 0xD
004011E9    50                 push eax
004011EA    E8 92FEFFFF        call CrackMe_.00401081               ; 再ROL 0xD次
004011EF    68 47204000        push CrackMe_.00402047               ; ASCII "d:\"
004011F4    E8 C9FEFFFF        call CrackMe_.004010C2               ; 取D盘信息
004011F9    8945 F8            mov dword ptr ss:[ebp-8],eax         ; 得取了返回值:44886452
004011FC    FF75 F8            push dword ptr ss:[ebp-8]
004011FF    FF75 FC            push dword ptr ss:[ebp-4]
00401202    E8 A8FEFFFF        call CrackMe_.004010AF               ; 加1
00401207    6A 05              push 5
00401209    50                 push eax
0040120A    E8 89FEFFFF        call CrackMe_.00401098               ; SHL 5
0040120F    6A 0D              push 0D
00401211    50                 push eax
00401212    E8 6AFEFFFF        call CrackMe_.00401081               ; ROL 0xD
00401217    FF75 F8            push dword ptr ss:[ebp-8]            ; 得到了原来的数:44886452,靠!!
0040121A    FF75 FC            push dword ptr ss:[ebp-4]
0040121D    E8 34FEFFFF        call CrackMe_.00401056               ; 这里还进进了浮点运算,靠,还是原数,不知在别的机器上是不是这样?
--------------------------------------------------
原来它是取本D盘的卷标信息。不知道,如果有只有一个分区时,会是怎样?

BOOL GetVolumeInformation(
  LPCTSTR lpRootPathName,        // address of root directory of the
                                 // file system
  LPTSTR lpVolumeNameBuffer,     // address of name of the volume
  DWORD nVolumeNameSize,         // length of lpVolumeNameBuffer
  LPDWORD lpVolumeSerialNumber,  // address of volume serial number============>就是它了
  LPDWORD lpMaximumComponentLength,
                                 // address of system's maximum
                                 // filename length
  LPDWORD lpFileSystemFlags,     // address of file system flags
  LPTSTR lpFileSystemNameBuffer, // address of name of file system
  DWORD nFileSystemNameSize      // length of lpFileSystemNameBuffer
);

=====================================================================================================

Delphi内联汇编注册机关键部分源码:
//=============  函数,过程,回调函数  ==================================
//=======================================================================
Function Get_D_VolumeInfo:DWORD;
var
  lpSerialNumber:DWORD;                   //序列号
  lpFileSystemName:array[0..10] of char;  //文件系统
  lpMaximumComponentLength:DWORD;
  lpFileSystemFlags:DWORD;
Begin
  GetVolumeInformation(pchar('d:\'),
                       nil,
                       0,
                       @lpSerialNumber,
                       lpMaximumComponentLength,
                       lpFileSystemFlags,
                       lpFileSystemName,
                       sizeof(lpFileSysTemName)
                       );
  result:=lpSerialNumber;
End;
procedure wofanKeygen(hdlg:HWND);
var
  Title,text:string;
const
  temp:array[0..15]of char=('0','7','1','3','6','2','d','e','9','f','8','a','b','4','5','c');
Begin
  Title:='提示';
  Text:='注册名至少4位!';
  ZeroMemory(@mCode,sizeof(mCode));
  ZeroMemory(@mName,sizeof(mName));
  GetDlgItemText(hDlg,IDC_Name,@mName,sizeof(mName));
  asm
    LEA ESI,mName  //把注册名的地址传到ESI
    cmp eax,4      //EAX 是GetDlgItemText函数返回值,它是字串实际长度
    JL @Err
    mov eax,1      //累加器置初值
@CalBegin:
    movzx ecx,byte ptr ds:[esi]  //注册名ASCII码逐个送ECX
    inc esi                      //移动指针
    or ecx,ecx
    je @EndCal
    mul ecx
    add eax,edx
    jmp @CalBegin
@EndCal:
    mov ecx,1
    rol eax,cl
    mov ecx,eax
    call Get_D_VolumeInfo
    or eax,ecx
    and eax,0FFFFFFFH
    lea esi,mCode                //注册码地址
    lea edi,temp                //临时字串的地址
@loop:
    push eax                    //压栈保存这个计算值
    xor edx,edx
    mov ecx,10H
    idiv ecx
    mov al,byte ptr ds:[edi+edx]
    mov byte ptr ds:[esi],al
    pop eax                     //计算值出栈
    mov ecx,4
    xor edx,edx
    idiv ecx
    or eax,eax
    je @End
    inc esi
    jmp @loop
@Err:
    push 0
    MOV EAX,DWORD PTR SS:[Title]
    PUSH EAX
    MOV EAX,DWORD PTR SS:[Text]
    PUSH EAX
    PUSH MB_OK
    Call MessageBox            //提示:注册名长度至少要4位
@End:
  End;  //End ASM
End;


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//