吾爱破解安全大赛cm1分析
算法部分在内存加载的DLL中 PE头被蹂躏了 不会修GG对GetDlgItemTextA下断 执行到返回后对缓冲区内容下硬件访问断点 可到达算法部分
算法函数在RVA为0x00001450的地方 可以下硬件执行断点方便调试
10001464 8B5D 08 mov ebx,dword ptr ss:
10001467 899D 38FFFFFF mov dword ptr ss:,ebx
1000146D 57 push edi
1000146E 8B7D 0C mov edi,dword ptr ss:
10001471 85DB test ebx,ebx
10001473 0F84 FE040000 je 10001977
10001479 8BCB mov ecx,ebx
1000147B 8D51 01 lea edx,dword ptr ds:
1000147E 8BFF mov edi,edi
10001480 8A01 mov al,byte ptr ds:
10001482 41 inc ecx
10001483 84C0 test al,al
10001485^ 75 F9 jnz short 10001480
10001487 2BCA sub ecx,edx
10001489 0F84 E8040000 je 10001977
1000148F 85FF test edi,edi
10001491 0F84 E0040000 je 10001977
10001497 56 push esi
10001498 8BF7 mov esi,edi
1000149A 8D4E 01 lea ecx,dword ptr ds:
1000149D 8D49 00 lea ecx,dword ptr ds:
100014A0 8A06 mov al,byte ptr ds:
100014A2 46 inc esi
100014A3 84C0 test al,al
100014A5^ 75 F9 jnz short 100014A0
100014A7 2BF1 sub esi,ecx
100014A9 8D46 ED lea eax,dword ptr ds:
100014AC 83F8 31 cmp eax,0x31
100014AF 0F87 AD040000 ja 10001962
首先检查serial长度是否大于18小于68
第一部分 矩阵运算检查serial前十八位
100014FC 8BCB mov ecx,ebx
100014FE E8 FDFCFFFF call 10001200
10001503 83E0 01 and eax,0x1 // 当ascii码之和为奇数时为1
10001506 C785 58FFFFFF 0>mov dword ptr ss:,0x3
10001510 8D8D 58FFFFFF lea ecx,dword ptr ss:
10001516 8985 3CFFFFFF mov dword ptr ss:,eax
取name的ascii码之和 检查结果的奇偶并放在ebp-0xC4中
10001533 0FB6C0 movzx eax,al
10001536 32FF xor bh,bh
10001538 8985 64FFFFFF mov dword ptr ss:,eax
1000153E 8D0440 lea eax,dword ptr ds:
10001541 0FB6FF movzx edi,bh
10001544 83C9 FF or ecx,-0x1
10001547 8D3407 lea esi,dword ptr ds:
1000154A 8A5475 E8 mov dl,byte ptr ss:
1000154E 8AC2 mov al,dl
10001550 2C 30 sub al,0x30
10001552 3C 09 cmp al,0x9
10001554 77 08 ja short 1000155E
10001556 0FBECA movsx ecx,dl
10001559 83E9 30 sub ecx,0x30
1000155C EB 1E jmp short 1000157C
1000155E 8AC2 mov al,dl
10001560 2C 41 sub al,0x41
10001562 3C 05 cmp al,0x5
10001564 77 08 ja short 1000156E
10001566 0FBECA movsx ecx,dl
10001569 83E9 37 sub ecx,0x37
1000156C EB 0E jmp short 1000157C
1000156E 8AC2 mov al,dl
10001570 2C 61 sub al,0x61
10001572 3C 05 cmp al,0x5
10001574 77 06 ja short 1000157C
10001576 0FBECA movsx ecx,dl
10001579 83E9 57 sub ecx,0x57
1000157C 81E1 01000080 and ecx,0x80000001 // 检查serial奇数
10001582 79 05 jns short 10001589
10001584 49 dec ecx
10001585 83C9 FE or ecx,-0x2
10001588 41 inc ecx
10001589 8A5C75 E9 mov bl,byte ptr ss:
1000158D 83CA FF or edx,-0x1
10001590 8AC3 mov al,bl
10001592 2C 30 sub al,0x30
10001594 3C 09 cmp al,0x9
10001596 77 08 ja short 100015A0
10001598 0FBED3 movsx edx,bl
1000159B 83EA 30 sub edx,0x30
1000159E EB 1E jmp short 100015BE
100015A0 8AC3 mov al,bl
100015A2 2C 41 sub al,0x41
100015A4 3C 05 cmp al,0x5
100015A6 77 08 ja short 100015B0
100015A8 0FBED3 movsx edx,bl
100015AB 83EA 37 sub edx,0x37
100015AE EB 0E jmp short 100015BE
100015B0 8AC3 mov al,bl
100015B2 2C 61 sub al,0x61
100015B4 3C 05 cmp al,0x5
100015B6 77 06 ja short 100015BE
100015B8 0FBED3 movsx edx,bl
100015BB 83EA 57 sub edx,0x57
100015BE 66:0F6ECA movd mm1,edx
100015C2 0F5B ??? ; 未知命令
100015C4 C9 leave
100015C5 3B8D 3CFFFFFF cmp ecx,dword ptr ss: // 当serial奇数位数字奇偶与name的ascii码之和不同时 偶数位数值取负值
100015CB 74 0A je short 100015D7
100015CD 0F57C0 xorps xmm0,xmm0
100015D0 F3:0F5CC1 subss xmm0,xmm1
100015D4 0F28C8 movaps xmm1,xmm0
100015D7 8B8D 64FFFFFF mov ecx,dword ptr ss:
100015DD 3B8D 58FFFFFF cmp ecx,dword ptr ss:
100015E3 0F8D 79030000 jge 10001962
100015E9 8B95 5CFFFFFF mov edx,dword ptr ss:
100015EF 3BFA cmp edi,edx
100015F1 0F8D 6B030000 jge 10001962
100015F7 8BC2 mov eax,edx
100015F9 FEC7 inc bh
100015FB 8B95 60FFFFFF mov edx,dword ptr ss: ; CrackMe.0040565D
10001601 0FAFC1 imul eax,ecx
10001604 03C7 add eax,edi
10001606 F3:0F110C82 movss dword ptr ds:,xmm1
1000160B 8D0449 lea eax,dword ptr ds:
1000160E 80FF 03 cmp bh,0x3
10001611^ 0F82 2AFFFFFF jb 10001541
10001617 8A85 6BFFFFFF mov al,byte ptr ss:
1000161D 04 01 add al,0x1
1000161F 8885 6BFFFFFF mov byte ptr ss:,al
10001625 3C 03 cmp al,0x3
10001627^ 0F82 06FFFFFF jb 10001533
然后一个大循环 取serial前十八位进行第一部分校验
每两个数字为一组 生成一个3x3共9个数字的矩阵
name为360 serial前十八位为323031303330213032时生成矩阵1如下
201
030
-102
设为矩阵A
A与如下矩阵B进行乘法操作得矩阵C
矩阵B
101
020
-101
矩阵C
1 0 3
0 6 0
-3 0 1
C再与矩阵D进行加法得矩阵E
矩阵D
100
010
001
矩阵E
2 0 3
0 7 0
-3 0 2
矩阵B与矩阵B进行乘法操作得矩阵F
0 0 2
0 4 0
-2 0 0
F与A进行加法操作得矩阵G
2 0 3
0 7 0
-3 0 2
矩阵G与矩阵E逐位进行比较 不相等则失败
void FuncAdd(const int arg1, const int arg2, int arg3)
{
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
arg3 = arg1 + arg2;
}
}
}
void FuncMul(const int arg1, const int arg2, int arg3)
{
int temp;
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
temp = 0;
for(int k=0; k<3; k++)
{
temp += arg1 * arg2;
}
arg3 = temp;
}
}
}
化简即 A*B+D=B*B+A (B D为常量)
第二部分 小游戏 我的理解是九格滑块拼图
用name生成一个初始棋盘 保存在RVA为0x00013F10的地方
取serial第19位开始作为解拼图的步骤
当name为360时生成的棋盘为
07 01 00 04 03 08 02 05 06
转换为3*3棋盘
7 1 0
4 3 8
2 5 6
其中0为空块 用于移动 1-8对应要移动的图块
已有key给出的解为14521036741034587634103478
10001931 0FB6CA movzx ecx,dl
10001934 8A81 103F0110 mov al,byte ptr ds:
1000193A 3A81 0F3F0110 cmp al,byte ptr ds:
10001940 7C 07 jl short 10001949
10001942 FEC2 inc dl
10001944 80FA 08 cmp dl,0x8
10001947^ 72 E8 jb short 10001931
移动完毕检查棋盘 此处检查不严谨 只检查了棋盘前8位是否从小到大排序
另一种解法是使棋盘最终为00 01 02 03 04 05 06 07 08
3*3对应
0 1 2
3 4 5
6 7 8
对应name为360时另一种解法key为14785430143674125430145210
currwin 发表于 2016-3-31 20:01
好厉害,分析得好透彻。那个dll不需要修复,内存中dump出来,map也dump出来,IDA直接二进制载入分析即可
大大,怎么把内存dump出来,把map dump出来,是借助什么工具吗?求解答{:1_932:}{:1_931:} currwin 发表于 2016-3-31 20:01
好厉害,分析得好透彻。那个dll不需要修复,内存中dump出来,map也dump出来,IDA直接二进制载入分析即可
map如何dump?一般不都是IDA的标签和注释map到OD吗? 先占个前排卖瓜子 这么深奥 难怪我没破出来 前排膜拜靶子牛 这么深奥啊 难怪我没破出来 本帖最后由 机器猫 于 2016-3-31 09:55 编辑
感谢楼主整理分享{:1_932:} 哇,好厉害哦
不做伸手党,下载就回复下 感谢楼主整理分享,学习了
前排膜拜靶子牛