吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 4516|回复: 18

[原创逆向图文] 分析160个CrackMe之91

  [复制链接]
李沉舟 发表于 2018-3-1 16:01 | 显示全部楼层 |阅读模式

【目标】160个CrackMe之91号
【工具】IDA Pro v6.8 | OllyDbg v1.1
【说明】有较低难度的反静态分析,适合练手
一、初试探反静态分析之修复API调用
首先载入OllyDbg,发现有奇怪的CALL。
[Asm] 纯文本查看 复制代码
00401043   .  6A 00           push 0x0
00401045   .  68 80000000     push 0x80
0040104A   .  6A 03           push 0x3
0040104C   .  6A 00           push 0x0
0040104E   .  6A 00           push 0x0
00401050   .  68 000000C0     push 0xC0000000
00401055   .  68 76214000     push crueme.00402176                     ;  ASCII "CRUEME.DAT"
0040105A   .  B0 1F           mov al,0x1F
0040105C   .  FF15 64234000   call dword ptr ds:[0x402364]

第一句对0x402364进行了赋值为0x401493的操作。
转入0x401493,发现AL是上下文,0x401493实际上是一个Dispatch,对上下文计算出正确的IAT地址,并转向一个stub桩函数调用之。随便看一个stub桩函数。
[Asm] 纯文本查看 复制代码
00401AC6   > \E8 8F020000     call <jmp.&USER32.LoadCursorA>                ; \LoadCursorA
00401ACB   .  EB 44           jmp short crueme.00401B11

再转入0x401B11查看。
[Asm] 纯文本查看 复制代码
00401B11   > \A3 68234000     mov dword ptr ds:[0x402368],eax
00401B16   .  FF35 70234000   push dword ptr ds:[0x402370]
00401B1C   .  C3              retn

保存了返回值进全局变量,又从全局变量里取出返回地址。返回地址是Dispatch里面填充的。
这样分析很不爽,载入IDA。写一个脚本Fix它。
程序启动的时候,对于上下文的计算用一个时间值填充了一个KEY,然后利用这个KEY初始化了一个数组,Dispatch用AL作索引从数组里面取出来元素进行运算。因为是时间值填充KEY,所以KEY应该可以为任意值。
用IDA载入程序,执行这段IDC脚本即可。
[C] 纯文本查看 复制代码
#include <idc.idc>

extern byte_key;


static main()
{
	byte_key = 1; //可随机取
	auto addr;
	xor();
	addr = DfirstB(0x402364);
	if (addr == -1)
	{
		Message("修复失败,找不到0x402364的引用");
		return;
	}
	//第一个引用是写,故无需修复
	addr = DnextB(0x402364, addr);
	while (addr != - 1)
	{
		fix(addr);
		addr = DnextB(0x402364, addr);
		
	} //循环修复

}

static and(a) //取低8位
{
	return a & 0xFF;
}

static xor() //解密数据
{
	auto esi, al;
	PatchDword(0x402380, 0x401224);
	PatchByte(0x402363, byte_key);
	al = byte_key;
	for (esi = 0x40211C; esi > 0x4020F2; esi--)
	{
		PatchByte(esi, Byte(esi) ^ al);
		al = al + 8;
		al = and(al);
	}
}

static patch(addr, to) //修复一个call, 传入mov al,xx地址, 以及对应jz loc_xxxxxx的名称
{
	auto call, jmp;
	PatchByte(addr, 0xFF);
	PatchByte(addr + 1, 0x15); //call [xxxxxxxx]
	call = LocByName(to);
	jmp = LocByName(GetOpnd(call, 0)); //得到jmp [xxxxxxxx]的地址
	PatchDword(addr + 2, GetOperandValue(jmp, 0)); //修复为call [xxxxxxxx]的形式
	PatchWord(addr + 6, 0x9090);
}

static fix(addr) //修复API调用
{
	auto p, al, bl, k;
	p = addr - 2;
	if (Byte(p) != 0xB0)
	{
		Message("%X 修复失败", addr);
		return;
	}
	p++;
	al = Byte(p);
	bl = Byte(0x40211D - al);
	al--;
	al = and(al);
	al = al << 3;
	al = and(al);
	al = al + byte_key;
	al = and(al);
	al = al ^ bl;
	al = and(al);
	//计算出al的初始值,并与0x20匹配,如果不对则往后面继续匹配
	
	if (al == 0x20)
	{
		patch(addr - 2, "loc_401AC6");
		return;
	}
	
	bl = al;
	
	p = 0x004014D7;
	k = GetOperandValue(p, 1); //得到对比值
	if (bl == k)
	{
		patch(addr - 2, "loc_4019B4");
		return;
	}

	while (bl != k)
	{
		p = p + 0x1E;
		k = GetOperandValue(p, 1);
	}

	patch(addr - 2, GetOpnd(p + 2, 0));
}

运行完成后,所有API调用被修复了。
1.png

二、再分析之可怖SMC
[Asm] 纯文本查看 复制代码
CODE:00401224 loc_401224:                             ; DATA XREF: DATA:lpBaseAddresso
CODE:00401224                 push    edx             ; lParam
CODE:00401225                 push    0Eh             ; wParam
CODE:00401227                 push    0Dh             ; Msg
CODE:00401229                 push    3EAh            ; nIDDlgItem
CODE:0040122E                 push    [ebp+hDlg]      ; hDlg
CODE:00401231                 call    ds:__imp_SendDlgItemMessageA
CODE:00401237                 nop
CODE:00401238                 nop
CODE:00401239                 call    sub_401B73
CODE:0040123E                 push    eax
CODE:0040123F                 mov     edi, 1
CODE:00401244                 call    SMC

执行到CALL SMC时,从0x401224开始起的代码会被替换掉。
3.png
这是用来替换的代码。
4.png
走到这里又还原了SMC。

难道这个SMC是为了反动态调试?接着往下面看看。
1.png
发现没有?这里不管你成功还是失败都会直接往下面走提示你失败,会把成功覆盖掉。
难道这里是BUG?
我往尾部走了两圈,柳暗花明。
2.png
这里又走回去执行了流程。是什么意思?
这次深入看一下SMC。
3.png
恐怖如斯。稍有不慎即中招。
现在执行这段IDC脚本。
[C] 纯文本查看 复制代码
static main()
{
	auto i, esi, edi;
	esi = 0x40238C;
	edi = 0x401224;
	for (i = 0; i < 25; i++)
	{
		PatchByte(edi, Byte(esi));
		edi++;
		esi++;
	}
	return;
}

执行完后,SMC代码已经覆盖完。
4.png
因为只有1个API重定向,我就不用脚本FIX了。直接猜也知道是GetDlgItemTextA。
接着往下面看。

[Asm] 纯文本查看 复制代码
CODE:00401B8E loc_401B8E:                             ; CODE XREF: Check:loc_401C16j
CODE:00401B8E                 mov     eax, [ebx]
CODE:00401B90                 add     eax, 12D687h
CODE:00401B95                 add     eax, [ebx+8]
CODE:00401B98                 sub     eax, 2B67h
CODE:00401B9D                 xor     edx, edx
CODE:00401B9F                 mul     ds:iLength
CODE:00401BA5                 mov     edx, [ebx+4]
CODE:00401BA8                 add     edx, 48FF4EAh
CODE:00401BAE                 xor     eax, edx
CODE:00401BB0                 mov     edx, [ebx+8]
CODE:00401BB3                 sub     edx, 0BC5C01h
CODE:00401BB9                 sub     edx, [ebx]
CODE:00401BBB                 add     edx, 2B67h
CODE:00401BC1                 xor     eax, edx
CODE:00401BC3                 or      eax, 29359E2h
CODE:00401BC8                 add     edi, eax
CODE:00401BCA                 and     edi, ds:dword_402162
CODE:00401BD0                 mov     eax, [ebx]
CODE:00401BD2                 sub     eax, 12D687h
CODE:00401BD7                 sub     eax, [ebx+8]
CODE:00401BDA                 add     eax, 56CEh
CODE:00401BDF                 xor     edx, edx
CODE:00401BE1                 div     ds:iLength
CODE:00401BE7                 mov     edx, [ebx+4]
CODE:00401BEA                 sub     edx, 48FF4EAh
CODE:00401BF0                 xor     eax, edx
CODE:00401BF2                 mov     edx, [ebx+8]
CODE:00401BF5                 add     edx, 0BC5C01h
CODE:00401BFB                 add     edx, [ebx]
CODE:00401BFD                 sub     edx, 56CEh
CODE:00401C03                 xor     eax, edx
CODE:00401C05                 and     eax, 29359E2h
CODE:00401C0A                 add     esi, eax
CODE:00401C0C                 or      esi, ds:dword_402166
CODE:00401C12                 loop    loc_401C16
CODE:00401C14                 jmp     short loc_401C1B
CODE:00401C16 ; ---------------------------------------------------------------------------
CODE:00401C16
CODE:00401C16 loc_401C16:                             ; CODE XREF: Check+9Fj
CODE:00401C16                 jmp     loc_401B8E
CODE:00401C1B ; ---------------------------------------------------------------------------
CODE:00401C1B
CODE:00401C1B loc_401C1B:                             ; CODE XREF: Check+A1j
CODE:00401C1B                 add     edi, 911h
CODE:00401C21                 sub     esi, 911h
CODE:00401C27                 dec     ds:byte_402133
CODE:00401C2D                 cmp     ds:byte_402133, 0
CODE:00401C34                 jnz     loc_401B89


描述这段算法。
我输入的注册码是12345678
[C] 纯文本查看 复制代码
	int i, j;
	
	unsigned int edi = 0, esi = 0;
	
	unsigned int k1 = '4321', k2 = '8765', k3 = 0;
	
	//k1是1-4位,k2是5-8位,k3是9-12位
	
	unsigned int eax = 0, edx = 0;
	
	unsigned iLen = 8; //实际位数
	
	for (i = 0xFF; i != 0; i--)
	{
		for (j = 0xFF; j != 0; j--)
		{ 
			eax = k1 + 0x12D687 + k3 - 0x2B67;
			eax *= iLen;
			eax ^= (k2 + 0x48FF4EA);
			eax ^= (k3 - 0xBC5C01 - k1 + 0x2B67);
			eax |= 0x29359E2;
			edi += eax;
			edi &= 0x15263748;
			eax = (k1 - 0x12D687 - k3 + 0x56CE) / iLen;
			eax ^= (k2 - 0x48FF4EA);
			eax ^= (k3 + 0xBC5C01 + k1 - 0x56CE);
			eax &= 0x29359E2;
			esi += eax;
			esi |= 0x596A7B8C;
		}
		edi += 0x911;
		esi -= 0x911;
	}


最后运算结果,EDI = 0xEFFDE3AF,ESI = 0xA4948D23。若不成立,则失败。
到了这一步,我真的是有点怕怕了。本高一数学渣渣看到这玩意已是不知所措。我只能想到猜解的办法。如果有数学大神,还请赐教啊。


我猜解4位看看。可打印字符有95个,95*95*95*95,千万级别运算量。
看来运气比较好,我没跑完,跑了几组解出来。
解.png
每一组解后面都有空格。
测试第一组解。
6.png
注意解后面是空格,重要的事说3遍。
比如<B2s >,直接复制尖括号内即可。

附上我的猜解源码(VC6)
[C] 纯文本查看 复制代码
#include <iostream>
#include <string>

bool check(unsigned int k1, unsigned int k2, unsigned int k3, unsigned iLen)
{
	int i, j;
	
	unsigned int edi = 0, esi = 0;
		
	unsigned int eax = 0, edx = 0;
	
	for (i = 0xFF; i != 0; i--)
	{
		for (j = 0xFF; j != 0; j--)
		{ 
			eax = k1 + 0x12D687 + k3 - 0x2B67;
			eax *= iLen;
			eax ^= (k2 + 0x48FF4EA);
			eax ^= (k3 - 0xBC5C01 - k1 + 0x2B67);
			eax |= 0x29359E2;
			edi += eax;
			edi &= 0x15263748;
			eax = (k1 - 0x12D687 - k3 + 0x56CE) / iLen;
			eax ^= (k2 - 0x48FF4EA);
			eax ^= (k3 + 0xBC5C01 + k1 - 0x56CE);
			eax &= 0x29359E2;
			esi += eax;
			esi |= 0x596A7B8C;
		}
		edi += 0x911;
		esi -= 0x911;
	}
	return (edi + 0xEFFDE3AF == 0 && esi + 0xA4948D23 == 0);
}

int main()
{
	using namespace std;
	char k1[5] = {0};
	for (unsigned int i = 0; i <= 0xFFFFFFFF; i++) //确定1-4位
	{
		memcpy(k1, &i, 4);
		if (isprint(k1[0]) && isprint(k1[1]) && isprint(k1[2]) && isprint(k1[3])) //确定1-4位都是可打印字符
		{
			if (check(i, 0, 0, 4))
				cout << "猜解成功,解为:" << k1;
		}
		else
			continue;
	}
	
	return 0;
}

2.png
2.png

评分

参与人数 20威望 +1 HB +48 THX +12 收起 理由
longge188 + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
一路走来不容易 + 1
消逝的过去 + 1
冷亦飞 + 1
纯英文 + 1
temp + 1 + 1
kkk1l + 1
凌夏随缘 + 1
kway + 1
hotD + 2 + 1
missaa + 1
bnjzzheng + 1 [吾爱汇编论坛52HB.COM]-吃水不忘打井人,给个评分懂感恩!
EMT + 1
jackwuwei + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
lies + 1
海天一色001 + 1 + 1 [快捷评语] - 评分=感恩!简单却充满爱!感谢您的作品!
海东 + 5 + 1 [快捷评语] - 吃水不忘打井人,给个评分懂感恩!
sxin0807 + 1 + 1 [快捷评语] - 2018,狗年发发发,狗年旺旺旺!
syzh802618 + 1 [快捷评语] - 2018,狗年发发发,狗年旺旺旺!
Shark恒 + 1 + 30 + 1 [快捷评语] - 2018,狗年发发发,狗年旺旺旺!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
 楼主| 李沉舟 发表于 2018-3-1 16:04 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
Shark恒 发表于 2018-3-1 17:28 | 显示全部楼层

这么可怖的SMC,感谢沉舟童鞋带来精彩分析
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
yqdyqzdstrm 发表于 2018-4-11 12:48 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
stevenli886 发表于 2018-6-3 15:39 | 显示全部楼层

学习!!!!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
bnjzzheng 发表于 2022-1-3 21:29 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
zhmtao 发表于 2022-1-5 18:10 | 显示全部楼层


支持一下,谢谢了
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
胡富贵 发表于 2022-1-5 20:35 | 显示全部楼层

感谢楼主分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
bnjzzheng 发表于 2022-1-8 19:05 | 显示全部楼层

感谢分享,感谢
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
wuxin162 发表于 2022-1-8 19:11 | 显示全部楼层


学习!!!!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表