首页
社区
课程
招聘
[原创]mucki's crackme#2分析
发表于: 2006-10-6 00:01 9424

[原创]mucki's crackme#2分析

2006-10-6 00:01
9424

【文章标题】: mucki's crackme#2分析
【文章作者】: llydd
【作者邮箱】: mainzo@163.com
【编写语言】: MASM32 / TASM32
【使用工具】: OD+PEID
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  用PEID查壳发现好像加了壳,本人壳盲一个,直接用PEID找到程序入口,得用OD字符插件找到关键点如下
  
    004011BB  /$  55            push ebp
    004011BC  |.  8BEC          mov ebp, esp
    004011BE  |.  57            push edi
    004011BF  |.  56            push esi
    004011C0  |.  53            push ebx
    004011C1  |>  6A 32         /push 32                                 ; /Count = 32 (50.)
    004011C3  |.  68 84624000   |push 00406284                           ; |Buffer = crackme2.00406284
    004011C8  |.  6A 01         |push 1                                  ; |ControlID = 1
    004011CA  |.  FF75 08       |push dword ptr [ebp+8]                  ; |hWnd
    004011CD  |.  E8 16020000   |call <jmp.&user32.GetDlgItemTextA>      ; \GetDlgItemTextA
    004011D2  |.  64:8B15 18000>|mov edx, dword ptr fs:[18]
    004011D9  |.  8B52 30       |mov edx, dword ptr [edx+30]
    004011DC  |.  0FB652 02     |movzx edx, byte ptr [edx+2]
    004011E0  |.  83F8 00       |cmp eax, 0                                ;取出用户名,比较用户名的位数是不否大于0,大于则跳
    004011E3  |.  7F 11         |jg short 004011F6
   
   
   
    004011FE  /movsx eax, byte ptr [esi]    ;取出用户名每位的ASCII码移至EAX
    00401201  |mov ebx, eax                        ;ASCII码也移至EBX
    00401203  |sub esi, edx
    00401205  |shl eax, 4                        ;然后将存于EAX中的ASCII码左移四位,
    00401208  |shr ebx, 5                        ;将存于EBX中的ASCII码右移五位
    0040120B  |xor eax, ebx                        ;将上面两步的结果相加送EAX
    0040120D  |add eax, 26                        ;将EAX+26H
    00401210  |xor eax, ecx                        ;(注:ECX存放操作的结果)将上面操作的结果(EAX)与以前所得结果(ECX)异或送至EAX
    00401212  |add ecx, eax                        ;将以前操作的结果(ECX)与该结果(EAX)相加保存至ECX
    00401214  |inc esi
    00401215  |cmp byte ptr [esi], 0        ;重复上面的操作
    00401218  \jnz short 004011FE
   
    CM2-2769-9F190E24
   
   
    0040121A  mov eax, 0C0DEF
    0040121F  sub eax, ecx                        ;用0C0DEF减上面求得的结果(ECX),然后平方送EAX
    00401221  imul eax, eax
    00401224  push eax                                 ; /<%lX>
    00401225  push ecx                                 ; |<%lX>
    00401226  push 004060E1                            ; |cm2-%lx-%lx           ;将EAX,与ECX的值按CM2-%lx-%lx的格式转换成注册码
    0040122B  push 004062B6                            ; |s = crackme2.004062B6
    00401230  call <jmp.&user32.wsprintfA>             ; \wsprintfA
   
   
    00401235  |.  6A 4B         push 4B                                  ; /Count = 4B (75.)
    00401237  |.  68 B1604000   push 004060B1                            ; |                                       nameless
    0040123C  |.  6A 02         push 2                                   ; |ControlID = 2
    0040123E  |.  FF75 08       push dword ptr [ebp+8]                   ; |hWnd
    00401241  |.  E8 A2010000   call <jmp.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA   ;取假注册码^_^
    00401246  |.  68 B1604000   push 004060B1                            ; /                                       nameless
    0040124B  |.  68 B6624000   push 004062B6                            ; |String1 = ""
    00401250  |.  E8 DB010000   call <jmp.&kernel32.lstrcmpA>            ; \lstrcmpA          ;比较注册码与假码是否相同,相同则注册成功,
    00401255  |.  75 16         jnz short 0040126D
    00401257  |.  6A 00         push 0                                   ; /Style = MB_OK|MB_APPLMODAL
    00401259  |.  68 00604000   push 00406000                            ; |crackme2
    0040125E  |.  68 3D604000   push 0040603D                            ; |valid serial - now write a keygen!
    00401263  |.  FF75 08       push dword ptr [ebp+8]                   ; |hOwner
    00401266  |.  E8 89010000   call <jmp.&user32.MessageBoxA>           ; \MessageBoxA
   
   
    注册机代码:
   
    #include "string.h"
    #include "stdio.h"
    int main()
    {char szID[20];
     int  i;
     long nSum=0,nconst=0x0c0def;
     printf("ID=");
     gets(szID);
     while(strlen(szID)<=0)
            {
                    printf("ID=");
                    gets(szID);
            }
    for(i=0;i<strlen(szID);i++)
            nSum+=(long)(szID[i]*16+szID[i]/32+0x26)^nSum;
    nconst-=nSum;
    nconst*=nconst;
    printf("serial=CM2-%lX-%lX\n",nSum,nconst);
    system("pause");
    return 0;
    }
   
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年10月06日 0:00:44


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
2
怎么在本地格式都好好的,可一发上来,格式就变型了
2006-10-6 00:03
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
3
哦,支持的说。。。。。。。。。。。。。。。
2006-10-6 01:06
0
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
最初由 llydd 发布
怎么在本地格式都好好的,可一发上来,格式就变型了


文章不错,论坛页面有宽度限制。你可以加代码标签试试。
2006-10-6 10:38
0
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
zcg
5
冒昧问一下,这个???
怎么和 http://bbs.pediy.com/showthread.php?s=&threadid=32925 的有点相像呀???
2006-10-6 10:45
0
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
6
呵呵,不是同一个人撒,文章发的时候不同
终于混 到两个精华了,这个国庆没白过谢谢看雪老大
2006-10-6 12:39
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
以前好像还看过一个这个craekme的分析教程
2006-11-15 11:09
0
雪    币: 404
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
楼主的keygen并非按照原样还原的-_-!
#include <stdio.h>
#include <string.h>
int main(void)
{
        signed long int g_const=0x0c0def;
        char name[20];
        signed long int X_name;
        signed long int Y_name;
        signed long int count=0;
        signed long int result;
        signed int i=0;
        printf("Please input your Name:");
        gets(name);
        while(strlen(name)==0)
                {       
                        printf("Please input your Name:");
                        gets(name);
                }
        for(i=0;i<(signed int)(strlen(name));i++)       
                {       
                        X_name=(signed long int)name[i];
                        Y_name=(signed long int)name[i];
                        X_name*=16;
                        Y_name/=32;
                        X_name^=Y_name;
                        X_name+=0x26;
                        X_name^=count;
                        count+=X_name;
                }
        result=g_const-count;
        result*=result;
        printf("CM2-%lx-%lx\n",count,result);
}
for循环简化后:
        for(i=0;i<strlen(name);i++)
g_count+=(long)(((long)(name[i]*16)^(long)(name[i]/32))+0x26)^g_count;
        g_const-=g_count;
        g_const*=g_const;
搂主用的是+连接name[i]*16,name[i]/32
2006-11-15 23:20
0
雪    币: 136
活跃值: (1475)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
9
00401218  \jnz short 004011FE   在这个地方无限循环呀,您是怎么跳过去的?指点下
2010-4-5 17:10
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
10
06年的了,估计人都退出密界了
2010-4-6 13:13
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
11
#include "stdafx.h"
#include <string.h>
int main(int argc, char* argv[])
{
	char name[10],serial[18];
	int i,total=0,k;
	printf("Plz input your name:\n");
	scanf("%s",name);
	for(i=0;i<strlen(name);i++)
	{
		total=total+(((name[i]<<4^name[i]>>5)+0x26)^total);
	}
	k=(0xC0DEF-total)*(0xC0DEF-total);
	printf("Your serial is:CM2-%lX-%lX\n",total,k);
	return 0;
}
2010-4-8 16:14
0
雪    币: 180
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
代码是看懂了.
请高手们求解如下问题.

在实际操作过程中,跳过SEH后,下面代码每次都拿第一个字节并无限循环.
004011FE  |>  0FBE06        /MOVSX   EAX, BYTE PTR DS:[ESI]
00401201  |.  8BD8          |MOV     EBX, EAX
00401203  |.  2BF2          |SUB     ESI, EDX
00401205  |.  C1E0 04       |SHL     EAX, 4
00401208  |.  C1EB 05       |SHR     EBX, 5
0040120B  |.  33C3          |XOR     EAX, EBX
0040120D  |.  83C0 26       |ADD     EAX, 26
00401210  |.  33C1          |XOR     EAX, ECX
00401212  |.  03C8          |ADD     ECX, EAX
00401214  |.  46            |INC     ESI
00401215  |.  803E 00       |CMP     BYTE PTR DS:[ESI], 0
00401218  |.^ 75 E4         \JNZ     SHORT crackme2.004011FE

怎么解决?   ^^
2010-4-9 21:33
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
13
[QUOTE=末日星魂;788739]代码是看懂了.
请高手们求解如下问题.

在实际操作过程中,跳过SEH后,下面代码每次都拿第一个字节并无限循环.
004011FE  |>  0FBE06        /MOVSX   EAX, BYTE PTR DS:[ESI]
00401201  |.  8BD8       ...[/QUOTE]

那是一个简单的anti-debug
往回看,看看edx那个1是怎么来的

004011D2  |.  64:8B15 18000>|mov     edx, dword ptr fs:[18]
004011D9  |.  8B52 30       |mov     edx, dword ptr [edx+30]
004011DC  |.  0FB652 02     |movzx   edx, byte ptr [edx+2]
这几句就是在检测,程序是否被调试,如果被调试,edx为1,否则为0
这里你让edx强制为0就可以正常调试了

这个anti实在太弱了,连我都看出来了,所以估计楼主没有讲
2010-4-11 15:05
0
游客
登录 | 注册 方可回帖
返回
//