crackme是一个师兄传给我的,放了很长时间了,最近有空分析了一下,把分析的小结发上来,希望能给像我一样的菜鸟些帮助。没去查是否有人写过这个crackme的分析文章,就先发上来吧。
第一次发文章,大家轻拍
我是新手,高手飘过~~~
一、PEiD查看知道,编译环境是Microsoft Visual Studio .NET 2005 – 2008,没有加壳。如果不能运行,需要安装.net插件。
二、LoadPE查看导入表和导入函数信息,知道程序用GetDlgItemTextW函数获取输入的name和code值。
三、详细分析
Od加载,对GetDlgItemTextW下断。F9运行起来对话框,输入信息
点reg按钮,程序停在
77D247AD > 8BFF MOV EDI,EDI ;
77D247AF 55 PUSH EBP
77D247B0 8BEC MOV EBP,ESP
77D247B2 FF75 0C PUSH DWORD PTR SS:[EBP+C]
77D247B5 FF75 08 PUSH DWORD PTR SS:[EBP+8]
77D247B8 E8 59000000 CALL USER32.GetDlgItem
//GetDlgItemTextW在user32.dll中的实现代码
首先F2,取消77D247AD 处的断点;Alt+F9,回到用户程序
004013B3 6A 40 PUSH 40
004013B5 8D85 7CFFFFFF LEA EAX,DWORD PTR SS:[EBP-84]
004013BB 50 PUSH EAX
004013BC 68 EA030000 PUSH 3EA
004013C1 53 PUSH EBX
004013C2 FFD7 CALL EDI
//主程序调用GetDlgItemTextW 的位置,从这里走到user32.dll中的实现代码
004013C4 6A 40 PUSH 40 //返回到这里
004013C6 8BF0 MOV ESI,EAX
004013C8 8D45 BC LEA EAX,DWORD PTR SS:[EBP-44]
004013CB 50 PUSH EAX
004013CC 68 EB030000 PUSH 3EB
004013D1 53 PUSH EBX
004013D2 FFD7 CALL EDI //主程序调用GetDlgItemTextW 的位置
004013D4 50 PUSH EAX
004013D5 8D45 BC LEA EAX,DWORD PTR SS:[EBP-44]
004013D8 50 PUSH EAX
004013D9 E8 9CFDFFFF CALL 复件_Cra.0040117A //code在这里处理
004013DE 59 POP ECX
004013DF 59 POP ECX
004013E0 8D8D 7CFFFFFF LEA ECX,DWORD PTR SS:[EBP-84]
004013E6 66:8BF8 MOV DI,AX
004013E9 E8 E2FCFFFF CALL 复件_Cra.004010D0 //name在这里处理
004013EE 66:3BC7 CMP AX,DI
//name、code处理的结果在这里比较;其中di中是code的处理结果,ax中是name的处理结果。
004013F1 5F POP EDI
004013F2 5E POP ESI
004013F3 74 07 JE SHORT 复件_Cra.004013FC //爆破位置
004013F5 68 E4214000 PUSH 复件_Cra.004021E4
;UNICODE "Error Code. plz retry!"
004013FA EB 05 JMP SHORT 复件_Cra.00401401
004013FC 68 14224000 PUSH 复件_Cra.00402214
;UNICODE "u got it. Congratulations!"
00401401 68 E9030000 PUSH 3E9
00401406 53 PUSH EBX
00401407 FF15 C8204000 CALL DWORD PTR DS:[<&USER32.SetDlgItemTe>
;\SetDlgItemTextW
在004013D9,F4;F7跟进,F8单步或直接F4到004011B5
…
004011B5 E8 94FEFFFF CALL 复件_Cra.0040104E //F7跟进
来到这里
0040104E /$ 66:8338 43 CMP WORD PTR DS:[EAX],43
00401052 |. 75 79 JNZ SHORT 复件_Cra.004010CD
00401054 |. 66:8378 02 43 CMP WORD PTR DS:[EAX+2],43
00401059 |. 75 72 JNZ SHORT 复件_Cra.004010CD
0040105B |. 66:8378 04 4E CMP WORD PTR DS:[EAX+4],4E
00401060 |. 75 6B JNZ SHORT 复件_Cra.004010CD
00401062 |. 66:8378 06 54 CMP WORD PTR DS:[EAX+6],54
00401067 |. 75 64 JNZ SHORT 复件_Cra.004010CD
00401069 |. 66:8378 08 2D CMP WORD PTR DS:[EAX+8],2D
0040106E |. 75 5D JNZ SHORT 复件_Cra.004010CD
//判断code前五个字符是否为CCNT-
00401070 |. 83C0 0A ADD EAX,0A //Unicode,取后面的字符
00401073 |. 33D2 XOR EDX,EDX
00401075 |> 0FB70C50 /MOVZX ECX,WORD PTR DS:[EAX+EDX*2]
00401079 |. 66:83F9 30 |CMP CX,30
0040107D |. 72 06 |JB SHORT 复件_Cra.00401085
0040107F |. 66:83F9 39 |CMP CX,39
00401083 |. 76 0C |JBE SHORT 复件_Cra.00401091
00401085 |> 66:83F9 41 |CMP CX,41
00401089 |. 72 42 |JB SHORT 复件_Cra.004010CD
0040108B |. 66:83F9 46 |CMP CX,46
0040108F |. 77 3C |JA SHORT 复件_Cra.004010CD
00401091 |> 42 |INC EDX
00401092 |. 83FA 04 |CMP EDX,4
00401095 |.^ 7C DE \JL SHORT 复件_Cra.00401075
//判断CCNT-后面的四个字符是否是数字或字符A~F
00401097 |. 83C0 08 ADD EAX,8
0040109A |. 66:8B08 MOV CX,WORD PTR DS:[EAX]
0040109D |. 40 INC EAX
0040109E |. 40 INC EAX
0040109F |. 66:83F9 2D CMP CX,2D
//判断CCNT-XXXX接着的第十个字符是否是“-”
004010A3 |. 75 28 JNZ SHORT 复件_Cra.004010CD
004010A5 |. 33D2 XOR EDX,EDX
004010A7 |> 0FB70C50 /MOVZX ECX,WORD PTR DS:[EAX+EDX*2]
004010AB |. 66:83F9 30 |CMP CX,30
004010AF |. 72 06 |JB SHORT 复件_Cra.004010B7
004010B1 |. 66:83F9 39 |CMP CX,39
004010B5 |. 76 0C |JBE SHORT 复件_Cra.004010C3
004010B7 |> 66:83F9 41 |CMP CX,41
004010BB |. 72 10 |JB SHORT 复件_Cra.004010CD
004010BD |. 66:83F9 46 |CMP CX,46
004010C1 |. 77 0A |JA SHORT 复件_Cra.004010CD
004010C3 |> 42 |INC EDX
004010C4 |. 83FA 04 |CMP EDX,4
004010C7 |.^ 7C DE \JL SHORT 复件_Cra.004010A7
//判断最后四个字符是否是数字或字符A~F
004010C9 |. 33C0 XOR EAX,EAX
004010CB |. 40 INC EAX
004010CC |. C3 RETN //满足条件返回TURE
004010CD |> \33C0 XOR EAX,EAX
004010CF \. C3 RETN //不满足条件返回FALSE
//返回到这里
004011BA |. 85C0 TEST EAX,EAX
004011BC |. 0F84 14010000 JE 复件_Cra.004012D6 //判断,FALSE就不继续了
……
//真正的处理在这里
004011F2 |. 83F8 08 CMP EAX,8 //code有效字符是否为8个
004011F5 |. 0F85 DB000000 JNZ 复件_Cra.004012D6
004011FB |. 8B45 BC MOV EAX,DWORD PTR SS:[EBP-44]
004011FE |. E8 43FFFFFF CALL 复件_Cra.00401146
//对字符1运算,数字的话,减去0x30;A~F的话,减去0x37
00401203 |. 0FB7F0 MOVZX ESI,AX //结果放esi
……//其余七个字符做相同处理
00401259 |. 8BCB MOV ECX,EBX
0040125B |. C1E1 04 SHL ECX,4
0040125E |. 03CF ADD ECX,EDI
00401260 |. C1E1 04 SHL ECX,4
00401263 |. 0FB7FF MOVZX EDI,DI
00401266 |. 03CE ADD ECX,ESI
//把字符1、2、3处理后的结果运算;[ecx] = code[0]+code[1]*0x10+code[2]*0x100,设为a
00401268 |. 0FB7DB MOVZX EBX,BX
0040126B |. 0FB7F6 MOVZX ESI,SI
0040126E |. 03FB ADD EDI,EBX
00401270 |. 03FE ADD EDI,ESI
00401272 |. 81E7 0F000080 AND EDI,8000000F
//字符1、2、3处理后的结果相加取低四位的值
00401278 |. 0FB7C0 MOVZX EAX,AX
0040127B |. 0FB7C9 MOVZX ECX,CX
0040127E |. 79 05 JNS SHORT 复件_Cra.00401285
00401280 |. 4F DEC EDI
00401281 |. 83CF F0 OR EDI,FFFFFFF0
00401284 |. 47 INC EDI
00401285 |> 0FB775 C8 MOVZX ESI,WORD PTR SS:[EBP-38]
00401289 |. 3BFE CMP EDI,ESI
//字符4处理后的结果,与上面字符1、2、3处理后结果相加取低4位的和的值相比较;相等继续
0040128B |. 75 3A JNZ SHORT 复件_Cra.004012C7
0040128D |. 0FB77D C4 MOVZX EDI,WORD PTR SS:[EBP-3C]
00401291 |. 0FB775 C0 MOVZX ESI,WORD PTR SS:[EBP-40]
00401295 |. 03F7 ADD ESI,EDI
00401297 |. 0FB7FA MOVZX EDI,DX
0040129A |. 03F7 ADD ESI,EDI
0040129C |. 81E6 0F000080 AND ESI,8000000F
004012A2 |. 79 05 JNS SHORT 复件_Cra.004012A9
004012A4 |. 4E DEC ESI
004012A5 |. 83CE F0 OR ESI,FFFFFFF0
004012A8 |. 46 INC ESI
004012A9 |> 0FB7C0 MOVZX EAX,AX
004012AC |. 3BF0 CMP ESI,EAX
//字符8处理后的结果,与上面字符5、6、7处理后结果相加取低4位的和的值相比较;相等继续
004012AE |. 75 17 JNZ SHORT 复件_Cra.004012C7
004012B0 |. C1E2 04 SHL EDX,4
004012B3 |. 0355 C4 ADD EDX,DWORD PTR SS:[EBP-3C]
004012B6 |. C1E2 04 SHL EDX,4
004012B9 |. 0355 C0 ADD EDX,DWORD PTR SS:[EBP-40]
//把字符5、6、7处理后的结果运算;[edx] = code[4]+code[5]*0x10+code[6]*0x100,设为b
004012BC |. 81F2 CE080000 XOR EDX,8CE
//结果与0x8CE异或
004012C2 |. 0FB7C2 MOVZX EAX,DX
004012C5 |. EB 07 JMP SHORT 复件_Cra.004012CE
004012C7 |> B8 FFFF0000 MOV EAX,0FFFF
004012CC |. 8BC8 MOV ECX,EAX
004012CE |> C1E0 0C SHL EAX,0C
004012D1 |. 0BC1 OR EAX,ECX
//b*0x1000+a
004012D3 |. 0FB7D8 MOVZX EBX,AX
004012D6 |> 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
004012D9 |. 5F POP EDI
004012DA |. 5E POP ESI
004012DB |. 66:8BC3 MOV AX,BX
004012DE |. 33CD XOR ECX,EBP
004012E0 |. 5B POP EBX
004012E1 |. E8 D2010000 CALL 复件_Cra.004014B8
004012E6 |. C9 LEAVE
004012E7 \. C3 RETN
//返回到这里
004013DE |. 59 POP ECX
004013DF |. 59 POP ECX
004013E0 |. 8D8D 7CFFFFFF LEA ECX,DWORD PTR SS:[EBP-84]
004013E6 |. 66:8BF8 MOV DI,AX
//(b*0x1000+a)&0xffff 的值放di中,这是我们code计算的最后结果
004013E9 |. E8 E2FCFFFF CALL CrackMe.004010D0 //name计算函数
//F7,进入004010d0
004010D0 /$ 55 PUSH EBP
004010D1 |. 8BEC MOV EBP,ESP
004010D3 |. 51 PUSH ECX //ecx里面放的是name值
004010D4 |. 8365 FC 00 AND DWORD PTR SS:[EBP-4],0
004010D8 |. 85C9 TEST ECX,ECX //判断指针是否为空
004010DA |. 74 64 JE SHORT CrackMe.00401140
004010DC |. 66:8339 00 CMP WORD PTR DS:[ECX],0 //判断指向的内容是否为空
004010E0 74 5E JE SHORT CrackMe.00401140
004010E2 |. 8D46 FD LEA EAX,DWORD PTR DS:[ESI-3]
004010E5 |. 83F8 07 CMP EAX,7 //判断name的个数,应该为:3~10
004010E8 77 56 JA SHORT CrackMe.00401140
//name的个数符合要求,继续
004010EA |. 33D2 XOR EDX,EDX
004010EC |. 85F6 TEST ESI,ESI
004010EE |. 7E 2D JLE SHORT CrackMe.0040111D
004010F0 |> 0FB70451 /MOVZX EAX,WORD PTR DS:[ECX+EDX*2]
004010F4 |. 66:3D 3000 |CMP AX,30
004010F8 |. 72 06 |JB SHORT CrackMe.00401100
004010FA |. 66:3D 3900 |CMP AX,39
004010FE |. 76 18 |JBE SHORT CrackMe.00401118
00401100 |> 66:3D 4100 |CMP AX,41
00401104 |. 72 06 |JB SHORT CrackMe.0040110C
00401106 |. 66:3D 5A00 |CMP AX,5A
0040110A |. 76 0C |JBE SHORT CrackMe.00401118
0040110C |> 66:3D 6100 |CMP AX,61
00401110 |. 72 2E |JB SHORT CrackMe.00401140
00401112 |. 66:3D 7A00 |CMP AX,7A
00401116 |. 77 28 |JA SHORT CrackMe.00401140
00401118 |> 42 |INC EDX
00401119 |. 3BD6 |CMP EDX,ESI
0040111B |.^ 7C D3 \JL SHORT CrackMe.004010F0
//以上部分是对name字符是否为数字或大小写字符的检查
0040111D |> 33C0 XOR EAX,EAX
0040111F |. 85F6 TEST ESI,ESI
00401121 |. 7E 11 JLE SHORT CrackMe.00401134
00401123 |> 8D50 01 /LEA EDX,DWORD PTR DS:[EAX+1]
00401126 |. 66:0FAF1441 |IMUL DX,WORD PTR DS:[ECX+EAX*2]
0040112B |. 66:0155 FC |ADD WORD PTR SS:[EBP-4],DX
0040112F |. 40 |INC EAX
00401130 |. 3BC6 |CMP EAX,ESI
00401132 |.^ 7C EF \JL SHORT CrackMe.00401123
//name计算部分,name[i]*(i+1)的值累加,0<=i<=num(name)
00401134 |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00401137 |. C1E0 02 SHL EAX,2
//上一步计算结果*4
0040113A |. 0FB7C0 MOVZX EAX,AX
0040113D |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX
00401140 |> 66:8B45 FC MOV AX,WORD PTR SS:[EBP-4]
//结果&0xffff,放eax作为最后结果
00401144 |. C9 LEAVE
00401145 \. C3 RETN
//返回到这里
004013EE |. 66:3BC7 CMP AX,DI ; name与code在这里比较
详细分析完成,小结如下:
1.f(name)=g(code),分别对输入的name和code进行计算,然后比较运算后的结果;
2.g(code),首先code必须满足“CCNT-XXXX-XXXX”格式,其中XXXX中的X必需是数字或大小写字符,后面分析知,更严格的限制是必须是数字或字符A~F;然后,对其中的八个X处理,如果是数字,减去0x30,如果是字符,减去0x37,结果我们设为一个code[8];最后计算,计算过程要对code[8]中八个值的制约关系进行检查(code[3]==(code[0]+code[1]+code[2])&0x000f并且code[7]==(code[4]+code[5]+code[6])&0x000f)),计算的公式为:g(code) = code[0] + code[1]*0x10 +code[2]*0x100 +(code[4]^0x000e) * 0x1000
3.f(name),首先,对字符的特征和字符的个数进行检查,特征必需是数字或大小写字符,个数必需在3到10之间;然后计算,公式为:
f(name)=
CrackMe.rar
KeyGen.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)