首页
社区
课程
招聘
[原创]西南某比赛的三个简单逆向题分析
发表于: 2012-11-6 21:26 7944

[原创]西南某比赛的三个简单逆向题分析

2012-11-6 21:26
7944

忙碌了一周,虽然很辛苦,但屏幕上不时跳出的KEY还是会让我们信心倍增。这次参加西南某大学的信息安全大赛,收获挺多,也深刻了解到自己和大牛的差距,这里分享三个简单的逆向题。
比赛还有一个多小时就结束了,大家都没做题了,希望这时候发破文出来对比赛没有影响。
第一题:
这是一个非常简单的CrackMe,找注册码很容易,写注册机也只需简要分析。
首先载入OD,在GetDlgItemTextA函数处下断,运行后来到这里。

00401241  |.  6A 0A         PUSH 0A                                  ; /Count = A (10.)
00401243  |.  52            PUSH EDX                                 ; |Buffer => CrackMe.0040300C
00401244  |.  68 F2030000   PUSH 3F2                                 ; |ControlID = 3F2 (1010.)
00401249  |.  FFB5 FCFEFFFF PUSH DWORD PTR SS:[EBP-104]              ; |hWnd
0040124F  |.  E8 1A010000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
00401254  |.  8D05 0C304000 LEA EAX,DWORD PTR DS:[40300C]
0040125A  |.  50            PUSH EAX                                 ; /Arg1 => 0040300C ASCII "Speday"
0040125B  |.  E8 2DFEFFFF   CALL CrackMe.0040108D                    ; \CrackMe.0040108D
00401260  |.  8D15 0C304000 LEA EDX,DWORD PTR DS:[40300C]
00401266  |.  6A 0A         PUSH 0A                                  ; /Count = A (10.)
00401268  |.  52            PUSH EDX                                 ; |Buffer => CrackMe.0040300C
00401269  |.  68 F3030000   PUSH 3F3                                 ; |ControlID = 3F3 (1011.)
0040126E  |.  FFB5 FCFEFFFF PUSH DWORD PTR SS:[EBP-104]              ; |hWnd
00401274  |.  E8 F5000000   CALL <JMP.&user32.GetDlgItemTextA>       ; \GetDlgItemTextA
00401279  |.  68 20304000   PUSH CrackMe.00403020                    ; /String2 = ""
0040127E  |.  68 0C304000   PUSH CrackMe.0040300C                    ; |String1 = "Speday"
00401283  |.  E8 3A010000   CALL <JMP.&kernel32.lstrcmpA>            ; \lstrcmpA
00401288  |.  85C0          TEST EAX,EAX
0040128A  |.  75 1B         JNZ SHORT CrackMe.004012A7
0040128C  |.  6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040128E  |.  FF35 A1204000 PUSH DWORD PTR DS:[4020A1]               ; |Title = "成功"
00401294  |.  FF35 A5204000 PUSH DWORD PTR DS:[4020A5]               ; |Text = "注册成功!"
0040129A  |.  FFB5 FCFEFFFF PUSH DWORD PTR SS:[EBP-104]              ; |hOwner
004012A0  |.  E8 E7000000   CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA

0040108D  /$  55            PUSH EBP
0040108E  |.  8BEC          MOV EBP,ESP
00401090  |.  83C4 F4       ADD ESP,-0C
00401093  |.  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]             ;  计算name字段的长度
00401096  |.  50            PUSH EAX                                 ; /String
00401097  |.  E8 2C030000   CALL <JMP.&kernel32.lstrlenA>            ; \lstrlenA
0040109C  |.  48            DEC EAX                                  ;  长度减1,后面有用
0040109D  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
004010A0  |.  8B75 08       MOV ESI,DWORD PTR SS:[EBP+8]
004010A3  |.  8D3D 20304000 LEA EDI,DWORD PTR DS:[403020]
004010A9  |.  33DB          XOR EBX,EBX
004010AB  |.  895D F8       MOV DWORD PTR SS:[EBP-8],EBX
004010AE  |.  EB 4B         JMP SHORT CrackMe.004010FB
004010B0  |>  33C0          /XOR EAX,EAX
004010B2  |.  8A0433        |MOV AL,BYTE PTR DS:[EBX+ESI]            ;  取name的第一个字符
004010B5  |.  C1F8 04       |SAR EAX,4                               ;  右移4位
004010B8  |.  8845 F7       |MOV BYTE PTR SS:[EBP-9],AL              ;  存到变量中
004010BB  |.  33D2          |XOR EDX,EDX
004010BD  |.  8B45 F8       |MOV EAX,DWORD PTR SS:[EBP-8]
004010C0  |.  B9 02000000   |MOV ECX,2
004010C5  |.  F7F1          |DIV ECX                                 ;  eax=eax/2
004010C7  |.  33C0          |XOR EAX,EAX                             ;  edx=eax%ecx
004010C9  |.  33C9          |XOR ECX,ECX
004010CB  |.  83FA 01       |CMP EDX,1                               ;  判断edx(余数)是否等于1
004010CE  |.  74 0F         |JE SHORT CrackMe.004010DF
004010D0  |.  8A4433 01     |MOV AL,BYTE PTR DS:[EBX+ESI+1]          ;  取后一个字符
004010D4  |.  C1E0 1C       |SHL EAX,1C                              ;  左移28位
004010D7  |.  C1E8 1C       |SHR EAX,1C                              ;  右移28位
004010DA  |.  83C0 41       |ADD EAX,41                              ;  加上大写字母A的ascii码
004010DD  |.  EB 0D         |JMP SHORT CrackMe.004010EC
004010DF  |>  8A4433 FF     |MOV AL,BYTE PTR DS:[EBX+ESI-1]          ;  取前一个字符
004010E3  |.  C1E0 1C       |SHL EAX,1C                              ;  左移28位
004010E6  |.  C1E8 1C       |SHR EAX,1C                              ;  右移28位
004010E9  |.  83C0 61       |ADD EAX,61                              ;  加上小写字母a的ascii码
004010EC  |>  8A4D F7       |MOV CL,BYTE PTR SS:[EBP-9]              ;  取出上面变量中存的值
004010EF  |.  03C1          |ADD EAX,ECX                             ;  加在eax上
004010F1  |.  88043B        |MOV BYTE PTR DS:[EBX+EDI],AL            ;  存起来
004010F4  |.  8B5D F8       |MOV EBX,DWORD PTR SS:[EBP-8]
004010F7  |.  43            |INC EBX
004010F8  |.  895D F8       |MOV DWORD PTR SS:[EBP-8],EBX
004010FB  |>  8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004010FE  |.  3BD8          |CMP EBX,EAX                             ;  判断是不是倒数第二个字符
00401100  |.^ 7C AE         \JL SHORT CrackMe.004010B0
00401102  |.  8A0433        MOV AL,BYTE PTR DS:[EBX+ESI]             ;  取最后一位字符
00401105  |.  C1E0 1C       SHL EAX,1C                               ;  左移28位
00401108  |.  C1F8 1C       SAR EAX,1C                               ;  右移28位
0040110B  |.  83C0 31       ADD EAX,31                               ;  加上数字1的ascii码
0040110E  |.  88043B        MOV BYTE PTR DS:[EBX+EDI],AL             ;  存起来
00401111  |.  33C0          XOR EAX,EAX
00401113  |.  43            INC EBX
00401114  |.  88043B        MOV BYTE PTR DS:[EBX+EDI],AL             ;  末尾置0
00401117  |.  C9            LEAVE
00401118  \.  C2 0400       RETN 4

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

main()
{
	char name[100];
	char key[100];
	unsigned int i,j,a,b,c,d;
	int m;
	printf("Please input a name:\t");
	scanf("%s",name);
	j=lstrlen(name);
	for(i=0;i<j-1;i++)
	{
		m=name[i];
		a=m>>4;
		c=a;
		d=i%2;
		if(d==1)
		{
			a=name[i-1];
			a=a<<0x1c;
			a=a>>0x1c;
			a=a+0x61;
			a=a+c;
			key[i]=a;
		}
		else
		{
			a=name[i+1];
			a=a<<0x1c;
			a=a>>0x1c;
			a=a+0x41;
			a=a+c;
			key[i]=a;
		}
	}
	m=name[j-1];
	m=m<<0x1c;
	m=m>>0x1c;
	m=m+0x31;
	key[i]=m;
	key[i+1]=0;
	printf("The key is :\t%s\n",key);
	getchar();
	getchar();
}


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

上传的附件:
收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 30
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
强啊,,

学习下
2012-11-7 09:57
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
3
现在玩这个的貌似很少了,我也应该继续向前走了。
2012-11-7 14:32
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
期待后续 ...
2012-11-8 22:58
0
雪    币: 18
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
pretty good!注释很充分 新手可以看一下
2012-11-8 23:10
0
雪    币: 108
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
第一个Crack的注册码生成算法:

char g_pszUserPass[4064] = {0};
int GetPassword(BYTE *lpszUserName)
{
        int v1; // ebx@1
        char v2; // al@3
        int v3; // eax@6
        int result; // eax@7
        unsigned int count; // [sp+4h] [bp-8h]@1
        int length; // [sp+8h] [bp-4h]@1

        length = lstrlenA((LPCSTR)lpszUserName) - 1;
        v1 = 0;
        for ( count = 0; ; ++count )
        {
                v3 = length;
                if ( v1 >= length )
                        break;
                if ( count % 2 == 1 )
                        v2 = (lpszUserName[v1 - 1] & 0xF) + 'a';
                else
                        v2 = (lpszUserName[v1 + 1] & 0xF) + 'A';
                g_pszUserPass[v1] = ((signed int)lpszUserName[v1] >> 4) + v2;
                v1 = count + 1;
        }
        v3 = lpszUserName[v1];
        g_pszUserPass[v1] = (v3 << 28 >> 28) + '1';
        result = 0;
        g_pszUserPass[v1 + 1] = 0;
        return result;
}

用IDA的超牛插件逆向了sub_40108D,结果很强大。。。
2012-11-12 09:59
0
雪    币: 458
活跃值: (306)
能力值: ( LV12,RANK:400 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=wolfhome;1117016]第一个Crack的注册码生成算法:

char g_pszUserPass[4064] = {0};
int GetPassword(BYTE *lpszUserName)
{
        int v1; // ebx@1
        char v2; // al@3
        int v3; // eax@6
        int re...[/QUOTE]

IDA是很强大,我也在试着在用中。
2012-11-13 19:05
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
楼主厉害啊。不过不知道这个比赛有没有带壳破解的?
说到西南某大学,我就想起了我们学校。。。碰巧也是信安的,难道是学长?呵呵。
晚上回宿舍下载下来试试,先谢过楼主无私分享啦:)
加油。
2012-11-17 15:09
0
游客
登录 | 注册 方可回帖
返回
//