分析CrackMe2014#001,算法分析,注册机等
本帖最后由 tree_fly 于 2014-11-25 22:16 编辑【破文标题】CrackMe2014#001 破解分析算法注册机
【破文作者】tree_fly
【作者邮箱】
【作者主页】
【破解工具】PYG_ODBG PE
【破解平台】XPSp3 x86
【软件名称】CrackMe.exe
【软件大小】227,328 字节
【原版下载】https://www.chinapyg.com/thread-72325-1-1.html
【保护方式】ASPack 2.12 -> Alexey Solodovnikov
【软件简介】1.过第一关--20分
2.过第二关--10分
3.成功进入界面--10分
4.分析算法--30分
5.写出注册机--20分
6.不主动修改EXE任何字节完成所有要求--10分
7.若采用loader加载,只允许patch nag部分,其他部分一切视为无效!
对于第6点,各位可以充分采用猥琐的方法~~
过关要求,只要XP 32Bit能成功即可
【破解声明】
------------------------------------------------------------------------
【破解过程】感谢PYG。
多谢飘云大大指出错误,这个CM破解期间中断了一段时间,一时都忘记加壳了。这份马虎对于破解者要不得,不好意思了。这里及时修改以下吧 o(∩_∩)o 哈哈。
0.加壳篇
PE检测CM,提示ASPack 2.12 -> Alexey Solodovnikov,入口点:0456ADC。
CM导入OD,F8单步走过,ESP下硬件断点,运行后程序定在这里:
0048C415 61 POPAD
0048C416 75 08 JNZ SHORT CrackMe.0048C420
0048C418 B8 01000000 MOV EAX, 1
0048C41D C2 0C00 RETN 0C
0048C420 68 DC6A4500 PUSH CrackMe.00456ADC
0048C425 C3 RETN
入口点地址也出现了。为了调试方便,脱壳程序后继续调试。
1.下面来过第一关,我们说重点,细节略过。
00456259 .8B45 F8 MOV EAX, DWORD PTR SS:
0045625C .0345 F4 ADD EAX, DWORD PTR SS: ;A+B
0045625F .F76D F0 IMUL DWORD PTR SS: ;C*(A+B)
00456262 .D1F8 SAR EAX, 1 ;/2
00456264 .79 03 JNS SHORT CrackMe.00456269
00456266 .83D0 00 ADC EAX, 0
00456269 >8945 EC MOV DWORD PTR SS:, EAX ;结果记录在里
00456298 .8B45 EC MOV EAX, DWORD PTR SS:
0045629B .3B45 E8 CMP EAX, DWORD PTR SS: ;这里比较计算结果与第四位是否相等。
0045629E .74 02 JE SHORT CrackMe.004562A2
004562A0 >01E4 ADD ESP, ESP ;否则ESP累加,退出。
004562A2 E8 7DFEFFFF CALL CrackMe.00456124
004562A7 .33C0 XOR EAX, EAX
所以第一个过关条件是:
1.格式A-B-C-D
2.满足条件:int[(A+B)*C/2] = D
构建个可行性结果:1-1-1-1,或者1-2-3-4.
2.下面来看第二关。
程序断在这里:
00456744/$53 PUSH EBX
00456745|.8BD8 MOV EBX, EAX
00456747|.E8 30FAFFFF CALL CrackMe.0045617C
0045674C 803D A89F4500>CMP BYTE PTR DS:, 1 ;这里调全局变量了。
00456753 74 02 JE SHORT CrackMe.00456757 ;不相等程序退出。
00456755|.01E4 ADD ESP, ESP
00456757|>8BC3 MOV EAX, EBX
00456759|.E8 4EFFFFFF CALL CrackMe.004566AC
0045675E|.8BC3 MOV EAX, EBX
00456760|.E8 0BFEFFFF CALL CrackMe.00456570
00456765|.5B POP EBX
00456766\.C3 RETN
对459FA8地址查看参考:
参考位于 CrackMe:CODE 于 00459FA8
00456137 MOV BYTE PTR DS:, 1 DS:=02
00456153 MOV BYTE PTR DS:, 2 DS:=02
0045674C CMP BYTE PTR DS:, 1 (初始 CPU 选择)
全局赋值2处代码:
0045614E|.E8 996CFDFF CALL CrackMe.0042CDEC
00456153|.C605 A89F4500 02 MOV BYTE PTR DS:, 2
0045615A|.33C0 XOR EAX, EAX
这里选择爆破。
我们让全局变量成为1,或修改跳转。构建如下方案:
方案1:
00456753 7402 修改 7502
方案2:
00456153 C605 A89F4500 02修改C605 A89F4500 01
当然可能还有其他办法,这里1字节解决了
考虑第六条,不可以主动修改EXE字节,可以使用Loader、DLL劫持。 附件里已提供补丁。
3.为了调试方便,我们暂时修改EXE字节,另存为新文件CrackMe_C1.exe,重新调试新文件,开始第4关。
输入自定义用户名:AAAAA 密码123456,暂停后,在内存中存放的密码字节处下硬件断点,重新运行程序,一步一步走到算法CALL处(此处省略N多字):
00455B80/$55 PUSH EBP
00455B81|.8BEC MOV EBP, ESP
00455B83|.83C4 D0 ADD ESP, -30
00455B86|.53 PUSH EBX
00455B87|.56 PUSH ESI
00455B88|.57 PUSH EDI ;ntdll.7C930228
00455B89|.33DB XOR EBX, EBX
00455B8B|.895D D0 MOV , EBX
00455B8E|.895D D8 MOV , EBX
00455B91|.895D D4 MOV , EBX
00455B94|.895D E0 MOV , EBX
00455B97|.895D DC MOV , EBX
00455B9A|.895D EC MOV , EBX
00455B9D|.894D F4 MOV , ECX
00455BA0|.8955 F8 MOV , EDX ;ntdll.KiFastSystemCallRet
00455BA3|.8945 FC MOV , EAX
00455BA6|.8B45 FC MOV EAX,
00455BA9|.E8 26EDFAFF CALL CrackMe_.004048D4
00455BAE|.8B45 F8 MOV EAX, ;kernel32.7C816040
00455BB1|.E8 1EEDFAFF CALL CrackMe_.004048D4
00455BB6|.33C0 XOR EAX, EAX
00455BB8|.55 PUSH EBP
00455BB9|.68 DB5C4500 PUSH CrackMe_.00455CDB
00455BBE|.64:FF30 PUSH DWORD PTR FS:
00455BC1|.64:8920 MOV DWORD PTR FS:, ESP
00455BC4|.8B45 F8 MOV EAX, ;kernel32.7C816040
00455BC7|.E8 18EBFAFF CALL CrackMe_.004046E4
00455BCC|.8945 F0 MOV , EAX
00455BCF|.837D F0 00 CMP , 0
00455BD3|.75 0D JNZ SHORT CrackMe_.00455BE2
00455BD5|.8D45 F8 LEA EAX,
00455BD8|.BA F45C4500 MOV EDX, CrackMe_.00455CF4 ;PiaoYun
00455BDD|.E8 DAE8FAFF CALL CrackMe_.004044BC
00455BE2|>33F6 XOR ESI, ESI
00455BE4|.8D45 DC LEA EAX,
00455BE7|.50 PUSH EAX
00455BE8|.B9 02000000 MOV ECX, 2
00455BED|.BA 01000000 MOV EDX, 1
00455BF2|.8B45 FC MOV EAX,
00455BF5|.E8 4AEDFAFF CALL CrackMe_.00404944
00455BFA|.8B4D DC MOV ECX,
00455BFD|.8D45 E0 LEA EAX,
00455C00|.BA 045D4500 MOV EDX, CrackMe_.00455D04 ;$
00455C05|.E8 26EBFAFF CALL CrackMe_.00404730
00455C0A|.8B45 E0 MOV EAX,
00455C0D|.E8 0E29FBFF CALL CrackMe_.00408520
00455C12|.8BF8 MOV EDI, EAX
00455C14|.C745 E8 03000000 MOV , 3
00455C1B|>8D45 D4 /LEA EAX,
00455C1E|.50 |PUSH EAX
00455C1F|.B9 02000000 |MOV ECX, 2 ;每次取字符串位数
00455C24|.8B55 E8 |MOV EDX, ;位置位
00455C27|.8B45 FC |MOV EAX, ;被取的字符串
00455C2A|.E8 15EDFAFF |CALL CrackMe_.00404944 ;取字符串 Mid(L1,L6,2)
00455C2F|.8B4D D4 |MOV ECX, ;取出的值存放 L11
00455C32|.8D45 D8 |LEA EAX,
00455C35|.BA 045D4500 |MOV EDX, CrackMe_.00455D04 ;$
00455C3A|.E8 F1EAFAFF |CALL CrackMe_.00404730
00455C3F|.8B45 D8 |MOV EAX, ;
00455C42|.E8 D928FBFF |CALL CrackMe_.00408520 ;val()
00455C47|.8945 E4 |MOV , EAX
00455C4A|.3B75 F0 |CMP ESI, ;
00455C4D|.7D 03 |JGE SHORT CrackMe_.00455C52
00455C4F|.46 |INC ESI
00455C50|.EB 05 |JMP SHORT CrackMe_.00455C57
00455C52|>BE 01000000 |MOV ESI, 1
00455C57|>8B45 F8 |MOV EAX, ;
00455C5A|.33DB |XOR EBX, EBX
00455C5C|.8A5C30 FF |MOV BL, BYTE PTR DS: ;取内置字节与注册码xor运算
00455C60|.335D E4 |XOR EBX, ;val()
00455C63|.3BFB |CMP EDI, EBX
00455C65|.7C 0A |JL SHORT CrackMe_.00455C71
00455C67|.81C3 FF000000 |ADD EBX, 0FF ;处理越位问题
00455C6D|.2BDF |SUB EBX, EDI ;
00455C6F|.EB 02 |JMP SHORT CrackMe_.00455C73
00455C71|>2BDF |SUB EBX, EDI ;做减法
00455C73|>8D45 D0 |LEA EAX,
00455C76|.8BD3 |MOV EDX, EBX ;
00455C78|.E8 8FE9FAFF |CALL CrackMe_.0040460C
00455C7D|.8B55 D0 |MOV EDX,
00455C80|.8D45 EC |LEA EAX,
00455C83|.E8 64EAFAFF |CALL CrackMe_.004046EC
00455C88|.8B7D E4 |MOV EDI,
00455C8B|.8345 E8 02 |ADD , 2
00455C8F|.8B45 FC |MOV EAX,
00455C92|.E8 4DEAFAFF |CALL CrackMe_.004046E4
00455C97|.3B45 E8 |CMP EAX,
00455C9A|.^ 0F8F 7BFFFFFF \JG CrackMe_.00455C1B
00455CA0|.8B45 F4 MOV EAX, ;kernel32.7C839B48
00455CA3|.8B55 EC MOV EDX,
00455CA6|.E8 CDE7FAFF CALL CrackMe_.00404478
00455CAB|.33C0 XOR EAX, EAX
.........
00455CDA\.C3 RETN
我们来仔细分析一下代码含义:
内部字节:
009825C4D6 D0 B9 FA C6 AE D4 C6 B8 F3 B9 DC C0 ED CD C5中国飘云阁管理团
009825D4B6 D3 D7 A3 B8 F7 CE BB D0 C2 C4 EA BF EC C0 D6队祝各位新年快乐
009825E4A3 A1 !
ASCII "中国飘云阁管理团队祝各位新年快乐!"
长度0x22
程序对注册码前2位没有特殊判断,可以考虑随机数,我们用“10”来演算1次:
取用户名:ABCDE,逆操作如下(从下向上计算):0x41+0x10=0x51, 0x51 XOR D6=0x87,0x87再用于下一次运算 ....
1087 19 E5 D0 D0
D6 D0 B9 FA C6 AE D4 C6 B8 F3 B9 DC C0 ED CD
51 C9 5C 2A 16
-FF ?
10 87 19 E5 D0
用户名: 41 42 43 44 45
ABCDE
目测可行性方案,用户名:ABCDE,注册码:108719E5D0D0.
标题行已修改:恭喜你,顺利通过,另调试时,CM作者向我们表示恭喜,大大的微笑:
009825C04F 28 A1 C9 5F A1 C9 29 4F B9 FE B9 FE B9 FE 7EO(∩_∩)O哈哈哈~
4.至此算法就分析完了,下面写注册机:
char[] users = textBox1.Text.ToCharArray();
if (users.Length > 0x22) { textBox2.Text = "User string's too long!"; return; }
else if (users.Length == 0x00) { textBox2.Text = "Please input user string. "; return; }
//hex "中国飘云阁管理团队祝各位新年快乐!"
string encode_str = "D6 D0 B9 FA C6 AE D4 C6 B8 F3 B9 DC C0 ED CD C5 ";
encode_str += "B6 D3 D7 A3 B8 F7 CE BB D0 C2 C4 EA BF EC C0 D6 A3 A1";
string[] ENCODEBYTES = encode_str.Split(' ');
//随机生成第一对字符串
Random ran = new Random();
byte[] b = new byte;
ran.NextBytes(b);
int ex_HexValue = Convert.ToInt32(b);
int i = 0;
string hexOutput = null;
foreach (char letter in users)
{
//1.加法运算
int value = Convert.ToInt32(letter);
value += Convert.ToInt32(ex_HexValue);
//2.修正越位问题
if (value > 0xFF) value -= 0xFF;
//3.XOR操作
int CODE = Convert.ToInt32(ENCODEBYTES, 16);
value ^= CODE;
//4.赋值ex_HexChar
ex_HexValue = value;
//5.拼接结果
hexOutput += value.ToString("X2");
}
//6.记得添加首字节,输出
textBox2.Text = b.ToString("X2") + hexOutput;
6.谢谢,难免错误,敬请指正。
------------------------------------------------------------------------
【破解总结】
------------------------------------------------------------------------
【版权声明】
注册机+代码+Dll劫持工具生成的Loader
1.程序大小不对
2.程序有压缩壳算法正确!
请纠正,然后精华之~~
飘云 发表于 2014-9-3 09:45
1.程序大小不对
2.程序有压缩壳算法正确!
多谢飘云大哥指正,帖子内容、附件等相关修改已完成。{:victory:}
tree_fly 发表于 2014-9-3 15:54
多谢飘云大哥指正,帖子内容、附件等相关修改已完成。
少了DLL吧。
补,lpk.dll.
最喜欢看你的文章分析了!
页:
[1]