【逆向入门】简单的crake me题解

尽小者大,慎微者著

一道简单的crake me题目

题目

【逆向入门】简单的crake me题解_第1张图片
放到网盘里了,有兴趣可以自取。戳我拿文件
提取码:46v2

因为是第一次用od,
写题解也不太会。
可能会有不恰当的地方欢迎指正。

拖进PE

没有壳,上OD。
【逆向入门】简单的crake me题解_第2张图片

OD打开

先使用查找文本字符串
【逆向入门】简单的crake me题解_第3张图片发现倒数第二句。双击进入。
在这里插入图片描述向上找到跳转处。发现关键。

00401305  |.  33C0          xor eax,eax                              ;  -------------------------
00401307  |.  33DB          xor ebx,ebx
00401309  |.  33C9          xor ecx,ecx                              ;  d2k2_cra.<ModuleEntryPoint>
0040130B  |.  33D2          xor edx,edx                              ;  d2k2_cra.<ModuleEntryPoint>
0040130D  |.  8D05 B4314000 lea eax,dword ptr ds:[0x4031B4]          ;  取偏移地址
00401313  |>  8A1C01        mov bl,byte ptr ds:[ecx+eax]             ;  将bl依次赋值为输入的密码
00401316  |.  8A91 3C314000 mov dl,byte ptr ds:[ecx+0x40313C]        ;  dl依次赋值为用户名产生的密码
0040131C  |.  80FB 00       cmp bl,0x0                               ;  一直进行到前面都一致,后面bl与0x0比较

继续向上。

004012E5  |> \33C0          xor eax,eax                              ;  -----------------------------
004012E7  |.  6A 28         push 0x28                                ; /Count = 28 (40.)
004012E9  |.  68 B4314000   push d2k2_cra.004031B4                   ; |Buffer = d2k2_cra.004031B4
004012EE  |.  6A 04         push 0x4                                 ; |ControlID = 0x4
004012F0  |.  FF75 08       push [arg.1]                             ; |hWnd = 00220000
004012F3  |.  E8 F0000000   call <jmp.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004012F8  |.  66:85C0       test ax,ax                               ;  存放用户密码0x4031B4
004012FB  |.  74 55         je short d2k2_cra.00401352               ;  NULL跳出
004012FD  |.  66:83F8 0A    cmp ax,0xA
00401301  |.  7F 4F         jg short d2k2_cra.00401352               ;  大于10跳出
00401303  |.  7C 4D         jl short d2k2_cra.00401352               ;  小于10跳出

发现密码存储地址,可以继续向上找跳转。

00401248  |.  6A 28         push 0x28                                ; /Count = 28 (40.)
0040124A  |.  68 8C314000   push d2k2_cra.0040318C                   ; |Buffer = d2k2_cra.0040318C
0040124F  |.  6A 02         push 0x2                                 ; |ControlID = 0x2
00401251  |.  FF75 08       push [arg.1]                             ; |hWnd = 00220000
00401254  |.  E8 8F010000   call <jmp.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
00401259  |.  84C0          test al,al                               ;  获取用户输入用户名,存放至0040318c
0040125B  |.  0F84 06010000 je d2k2_cra.00401367                     ;  用户名为NULL不合法跳出
00401261  |.  3C 20         cmp al,0x20
00401263  |.  0F8F 13010000 jg d2k2_cra.0040137C                     ;  用户名大于32跳出
00401269  |.  3C 05         cmp al,0x5
0040126B  |.  0F8C 20010000 jl d2k2_cra.00401391                     ;  用户名小于5跳出
00401271  |.  8D1D 8C314000 lea ebx,dword ptr ds:[0x40318C]
00401277  |.  33C9          xor ecx,ecx                              ;  ------------------------------------
00401279  |.  B0 05         mov al,0x5                               ;  al的值为5,目的是为了下面的循环50040127B  |.  33D2          xor edx,edx                              ;  d2k2_cra.<ModuleEntryPoint>
0040127D  |>  8A0C1A        mov cl,byte ptr ds:[edx+ebx]             ;  CL赋值为用户的前五个字符
00401280  |.  80F1 29       xor cl,0x29
00401283  |.  02C8          add cl,al                                ;  cl与0x29异或后,加al
00401285  |.  80F9 41       cmp cl,0x41
00401288  |.  7C 1C         jl short d2k2_cra.004012A6               ;  小于0x41
0040128A  |.  80F9 5A       cmp cl,0x5A
0040128D  |.  7F 17         jg short d2k2_cra.004012A6               ;  大于0x5A
0040128F  |>  888A 3C314000 mov byte ptr ds:[edx+0x40313C],cl        ;  将处理之后的字符值放入0x40313C首地址中
00401295  |.  C682 3D314000>mov byte ptr ds:[edx+0x40313D],0x0       ;  清空下一位
0040129C  |.  FEC2          inc dl                                   ;  dl自增
0040129E  |.  FEC8          dec al                                   ;  循环al每次-10停止
004012A0  |.  3C 00         cmp al,0x0
004012A2  |.  74 08         je short d2k2_cra.004012AC               ;  结束后跳转
004012A4  |.^ EB D7         jmp short d2k2_cra.0040127D
004012A6  |>  B1 52         mov cl,0x52                              ;  赋值 cl=0x52
004012A8  |.  02C8          add cl,al                                ;  cl加上al
004012AA  |.^ EB E3         jmp short d2k2_cra.0040128F              ;5个字符放在地址中
004012AC  |>  33D2          xor edx,edx                              ;  -----------------------------------------------
004012AE  |.  B8 05000000   mov eax,0x5
004012B3  |>  8A0C1A        mov cl,byte ptr ds:[edx+ebx]
004012B6  |.  80F1 27       xor cl,0x27                              ;0x27异或
004012B9  |.  02C8          add cl,al
004012BB  |.  80C1 01       add cl,0x1                               ;  加上al+1
004012BE  |.  80F9 41       cmp cl,0x41
004012C1  |.  7C 1C         jl short d2k2_cra.004012DF               ;  小于41
004012C3  |.  80F9 5A       cmp cl,0x5A
004012C6  |.  7F 17         jg short d2k2_cra.004012DF               ;  大于5A
004012C8  |>  888A 41314000 mov byte ptr ds:[edx+0x403141],cl
004012CE  |.  C682 42314000>mov byte ptr ds:[edx+0x403142],0x0
004012D5  |.  FEC2          inc dl
004012D7  |.  FEC8          dec al                                   ;  循环al每次-10停止
004012D9  |.  3C 00         cmp al,0x0                               ;  判断处理完毕与否
004012DB  |.  74 08         je short d2k2_cra.004012E5               ;  读取用户名并且生成密码完毕,跳转至输入密码处
004012DD  |.^ EB D4         jmp short d2k2_cra.004012B3
004012DF  |>  B1 4D         mov cl,0x4D                              ;  cl赋值0x4D
004012E1  |.  02C8          add cl,al                                ;  cl+al
004012E3  |.^ EB E3         jmp short d2k2_cra.004012C8              ;  接着存放后5个字符
004012E5  |>  33C0          xor eax,eax                              ;  -----------------------------

结合字符串信息和提示可以完成题目了。

题目综合解释

【逆向入门】简单的crake me题解_第4张图片

注册机

尝试写了一下注册机。因为对汇编还是不太熟练,对于cl寄存器这里理解一开始出现了误区。导致一开始怎么都不对。后来知道问题在哪了。和寄存器cl有关系。

#include
#include
int main()
{
	char s[100];
	int cl[10];
	int mima[10];
	for(int i=0;i<5;i++)
	 scanf("%c",&s[i]);
	if(strlen(s)>32||strlen(s)<5)
	 {
	 	printf("用户名格式为5-32个字符!");
	 	return 0;
	 }//用户格式有误,无法继续 
	for(int k=0,a=5;k<5;k++,a--)
	{
	  cl[k]=s[k]^0x29+a;
	if(cl[k]<0x41||cl[k]>0x5a)
	cl[k]=0x52+a;
	} //前五位密码生成步骤1 
	for(int l=0,b=5;l<5;l++,b--)
	{
	cl[l+5]=s[l]^0x27+b+1;
	if(cl[l+5]<0x41||cl[l+5]>0x5a)
		cl[l+5]=0x4d+b;
		} //后五位密码生成步骤1 
	for(int w=0;w<10;w++)
	{
	mima[w]=cl[w]+5;
	if(mima[w]>0x5a)
		mima[w]-=0xd; 
	mima[w]^=0xc;
	if(mima[w]>0x5a)
		mima[w]=0x4b-w;//原错误理解:mima[w]=0x4b-cl[w]
	else if(mima[w]<0x41)
		mima[w]=0x4b+w;//原错误理解:mima[w]=0x4b+cl[w] 
	}//密码生成步骤2
	printf("生成的密码为:\n");
	for(int n=0;n<10;n++)
	printf("%c",mima[n]);

}

因为是第一次写,并且对汇编没有太掌握,可能在用词上有不当、错误之处。希望可以被指正。不胜感激。

你可能感兴趣的:(逆向,汇编)