首页
社区
课程
招聘
[讨论]一个crackme
发表于: 2013-7-16 12:59 12724

[讨论]一个crackme

2013-7-16 12:59
12724
一个crackme, 大家有空可以玩玩

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 47
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
呃~~~~  追到UPX1里 要吐血了~~~
2013-7-16 16:36
0
雪    币: 2835
活跃值: (2643)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
00401240 $ 68 00E04500 push CrackMe_.0045E000
00401245 .- E9 B6CD0400 jmp CrackMe_.0044E000


45E000就是pcode,操作码与操作符混合在一起
esi是veip
eax是操作码(操作码只有1位  lea esi,dword ptr ds:[esi+0x1])

0044E029 FEC8 dec al
0044E02B C0C8 04 ror al,0x4
0044E02E C0C8 00 ror al,0x0
0044E031 C0C8 02 ror al,0x2
0044E034 F6D0 not al
0044E036 FEC8 dec al
0044E038 FEC8 dec al
0044E03A C0C8 0C ror al,0xC
0044E03D FEC8 dec al
0044E03F 80F0 0C xor al,0xC
0044E042 80F0 0A xor al,0xA
0044E045 F6D8 neg al
0044E047 FEC8 dec al
0044E049 80F0 07 xor al,0x7
0044E04C 80F0 01 xor al,0x1


解码操作码,过程是可逆的。

通过查表,进入操作码对应的handle
比如
A1 = push(这个略坑,各种跳)
…………

可能得把所有的操作码弄明白,才能破解出程序吧。

或者取巧的办法,就是记录VEIP,根据跳转,爆破?
2013-7-16 18:11
0
雪    币: 100
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
验证的逻辑判断就几个if判断。 加了VMP
给一组可以弹ok的码先

用户名 V5555555
序列号 C666

(前后没有空格)
2013-7-16 18:32
0
雪    币: 47
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
第一次玩 就碰到个带VM的 回去补习一下VM的知识 再来挑战一下。
2013-7-16 19:09
0
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这个虚拟机太恶心了,判断很简单
用户名第一个字符是V,注册码第一个字符是C,用户名长度是注册码长度两倍就行
2013-7-17 18:03
0
雪    币: 100
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
膜拜,解出来了。
2013-7-17 23:24
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这个还真有难度。。。
2013-7-18 12:18
0
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
我的技术比较水,或者说根本就没什么技术,我只找到了比较V和C 还有 两个字符串长度相减,至于结果等于多少才能成功我还是看了你给出的一组可以弹出ok的注册码才猜到的
2013-7-18 14:23
0
雪    币: 233
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
开眼界了,虽然搞不太明白呵呵~但爆破好像很简单:

方法1)OD载入,输入用户名和序列号,点注册,下面由于 ESI = 0 出现异常:
00456000    F7FE            IDIV ESI
改为       F7FB           IDIV EBX
就算爆破了!(难道这个异常是个bug?)

方法2)
0044FF0B    85C8            TEST EAX,ECX
需要NOP掉,否则序列号不对的话,ZF=1
2013-7-20 01:48
0
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
那个 ESI为0我觉得不是BUG应该是故意的

0044FF0B    85C8            TEST EAX,ECX 这个你是怎么找到的?能说下思路吗
2013-7-20 18:10
0
雪    币: 233
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我是从后往前找的
以错误的序列号为例。当(操作码)EAX= 77, (VEIP) ESI = 45E829 时(略过JMP):
0044FE99    8B0424          MOV EAX,DWORD PTR SS:[ESP] //[17F0E0] = 0 送 EAX
0044FEA9    8B8C24 04000000 MOV ECX,DWORD PTR SS:[ESP+4] //[17F0E4] = 0 送 ECX
0044FEFD    50              PUSH EAX
0044FED6    8B87 24000000   MOV EAX,DWORD PTR DS:[EDI+24] //5C 送 EAX
0044FEC4    8B0438          MOV EAX,DWORD PTR DS:[EDI+EAX] // 202 ->EAX 
0044FE79    50              PUSH EAX  -|
0044FEBD    9D              POPFD -----| 标志寄存器EFL初始化为202
0044FF04    50              PUSH EAX
0044FF0B    85C8            TEST EAX,ECX //如果序列号不对,两者都是0,ZF=1;否则,都是1, ZF=0
0044FE8D    8B87 24000000   MOV EAX,DWORD PTR DS:[EDI+24] 
0044FEB6    9C              PUSHFD // 这个很关键。保存判断后的EFL标志
/* 这里序列号不对, EFL =246 (ZF=1);对的话 EFL = 202 (ZF=0) */

0044FECD    8F0438          POP DWORD PTR DS:[EDI+EAX] //将EFL(246)保存到[EDI+EAX]
/* 由于EAX是变量,所以保存的地址或许会不同;用内存断点搞它会很痛苦呵 */


接着,在EAX=0D9,ESI=45E837时:

0044EF72    8B0438          MOV EAX,DWORD PTR DS:[EDI+EAX] //将246 从[EDI+EAX]读出->eax
0044EF7B    50              PUSH EAX
0044EF82    9D              POPFD //映射到EFL标志
0044EF89    58              POP EAX //45E892 -> EAX
0044EFB7    0F443424        CMOVE ESI,DWORD PTR SS:[ESP] 
/* 如果序列号错误则条件满足,然后 [17F0E4]中的45E892 -> ESI;
序列号对的话,条件不满足, 还是原来的 ESI=45E838; */


后面,如果ESI=45E838,记得有个偏移变量就指向"ok";如果ESI=45E892 则指向"fail"。
很变态的感觉~~,建议大家用conditional log把EAX,ESI记录下来,便于分析。
2013-7-21 07:55
0
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
[QUOTE=moonlite;1201141]我是从后往前找的
以错误的序列号为例。当(操作码)EAX= 77, (VEIP) ESI = 45E829 时(略过JMP):

0044FE99    8B0424          MOV EAX,DWORD PTR SS:[ESP] //[17F0E0] = 0 送 EAX
0...[/QUOTE]

一开始我也是从后往前找但是不知道是从什么地方跳转过来的
从后往前找怎么知道是从哪跳过来的?用conditional log?  这个是啥怎么用?
2013-7-21 20:06
0
雪    币: 233
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
就是内存断点,很不易,因为地址总在变化。
右键-Breakpoint-conditional log (或者 Shift + F4)
它的作用就是自动追踪地址,寄存器的变化,设定条件来中断。
2013-7-21 23:36
0
雪    币: 100
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
[QUOTE=moonlite;1201141]我是从后往前找的
以错误的序列号为例。当(操作码)EAX= 77, (VEIP) ESI = 45E829 时(略过JMP):

0044FE99    8B0424          MOV EAX,DWORD PTR SS:[ESP] //[17F0E0] = 0 送 EAX
0...[/QUOTE]

膜拜,爆破就可以了。    花指令模板还没写完,现在只是把handle乱序了一下。
2013-7-22 00:25
0
雪    币: 100
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这个VM只是拿来加自己写的一些程序, 因为没有加壳的程序用来加一些demo来测试跟踪,
所以楼上的几位爆破。我个人感觉已经很强大了。 再次膜拜。 明天去公司发crackme的源码。
2013-7-22 01:02
0
雪    币: 100
活跃值: (328)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
BOOL Check(const char* pName, const char* pPassword)
{
	BOOL bret = FALSE;
	int nameLen = 0;
	int pawsswordlen = 0;
	
	__try
	{
		while(*(pName + nameLen))
		{
			++nameLen;
		}
		
		while(*(pPassword + pawsswordlen))
		{
			++pawsswordlen;
		}
		
		bret = (nameLen + pawsswordlen) / bret;
	}
	__except(1)
	{
		if (pName[0] == 'V' 
			&& pPassword[0] == 'C'
			&& pawsswordlen == (nameLen - pawsswordlen))
		{
			bret = TRUE;
			//return bret;
		}
		else
		{
			bret = FALSE;
		}
	}
	
	char szbuf[MAX_PATH] = {0};
	szbuf[0] = 'o';
	szbuf[1] = 'k';

	char szbuf2[MAX_PATH] = {0};
	szbuf2[0] = 'f';
	szbuf2[1] = 'a';
	szbuf2[2] = 'i';
	szbuf2[3] = 'l';

	if (bret)
	{
		::MessageBoxA(NULL, szbuf, szbuf, 0);
	}
	else
	{
		::MessageBoxA(NULL, szbuf2, szbuf2, 0);
	}

	return bret; 
}

void CCrackMeDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here

	UpdateData();

	if (m_name.GetLength() == 0
		|| m_pwd.GetLength() == 0)
	{
		::MessageBoxA(NULL, "名字和密码不能为空", "名字和密码不能为空", 0);
	}
	else
	{
		if (Check(m_name, m_pwd))
		{
			
		}
		else
		{
			
		}
	}
}



顺路问问爆破的亲, 你是正确的码和错误的码比较得到不同的ESI跳转, 还是只从错误的码从后往前一步一步看handle的?
2013-7-22 10:10
0
雪    币: 403
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
明白了 谢谢
2013-7-22 14:36
0
雪    币: 233
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
我是从后者推断出前者的,呵呵
另外谢谢你的分享!
2013-7-22 20:54
0
游客
登录 | 注册 方可回帖
返回
//