非常入门的一个CrackMe和大家分享
本帖最后由 xiangshen 于 2011-12-7 15:47 编辑非常入门的一个CrackMe和大家分享[文章标题]:非常入门的一个CrackMe和大家分享[文章作者]:willjhw[作者邮箱]:466684954@qq.com[软件名称]:CrackMe1.exe [加壳方式]:无壳[编写语言]:MicrosoftVisual C++ 6.0[使用工具]:吾爱破解OD,PEID ,VC6[操作系统]:windows xp sp3[软件介绍]:很久以前参加学校比赛的逆向第一题。[作者声明]:这个是非常入门级的CrackMe,整理文件的时候翻出来和大家分享,自己也总结下,大牛可绕过。---------------------------------------------------------------------------------------------------------------------------------[前言]:移动硬盘被感染了那个所谓的白蚁病毒,好烦啊,只有整理软件些,尽力挽回我的软件,发现几年前参加比赛的一个CrackMe,当初不懂逆向,看着也没有办法,现在可以很好的分析了,所以同很多像我当初那样的朋友分享下,大家共同进步,加油。[详细过程]:
首先是查壳啦,如下图
没有壳,小喜一下,由PEID可以看出是用VC写的控制台程序,运行程序随便输入一个数字,如图:
发现了关键字Try again~,于是打开OD,搜索字符串,如图:
这个就是关键地方啦,我们就在最上面下一个断点,F9跑起来。
00401000/[ DISCUZ_CODE_18 ]nbsp; 81EC D0070000 sub esp,0x7D0
00401006|.68 58704000 push CrackMe1.00407058 ;Please input the Key-Code:
0040100B|.E8 9A010000 call CrackMe1.004011AA
00401010|.8D4424 04 lea eax,dword ptr ss:
00401014|.50 push eax
00401015|.E8 46010000 call CrackMe1.00401160
0040101A|.8D4C24 08 lea ecx,dword ptr ss:
0040101E|.51 push ecx
0040101F|.E8 3C000000 call CrackMe1.00401060
00401024|.83C4 0C add esp,0xC
00401027|.85C0 test eax,eax
00401029|.74 16 je XCrackMe1.00401041
0040102B|.68 3C704000 push CrackMe1.0040703C ;The Key is your input ^^\n
00401030|.E8 75010000 call CrackMe1.004011AA
00401035|.83C4 04 add esp,0x4
00401038|.33C0 xor eax,eax
0040103A|.81C4 D0070000 add esp,0x7D0
00401040|.C3 retn
00401041|>68 30704000 push CrackMe1.00407030 ;Try again~\n
00401046|.E8 5F010000 call CrackMe1.004011AA
0040104B|.83C4 04 add esp,0x4
0040104E|.33C0 xor eax,eax
00401050|.81C4 D0070000 add esp,0x7D0
00401056\.C3 retn
关键的call就是40101F,我们输入key:0123456789跟进这个关键call。
00401078|.56 push esi
00401079|.8B7424 1C mov esi,dword ptr ss:
0040107D|.57 push edi
0040107E|.894C24 10 mov dword ptr ss:,ecx
00401082|.884424 18 mov byte ptr ss:,al
00401086|.8BFE mov edi,esi
00401088|.83C9 FF or ecx,0xFFFFFFFF
0040108B|.33C0 xor eax,eax
0040108D|.8B15 7C704000 mov edx,dword ptr ds:
00401093|.F2:AE repne scas byte ptr es: ;计算用户输入的字符串长度
00401095|.F7D1 not ecx
00401097|.49 dec ecx
00401098|.895424 14 mov dword ptr ss:,edx
0040109C|.8BD1 mov edx,ecx
0040109E|.8D7C24 0C lea edi,dword ptr ss:
004010A2|.83C9 FF or ecx,0xFFFFFFFF
004010A5|.F2:AE repne scas byte ptr es:
004010A7|.F7D1 not ecx
004010A9|.49 dec ecx
004010AA|.3BD1 cmp edx,ecx ;不等于c就跳向结束
004010AC|.0F85 9C000000 jnz CrackMe1.0040114E
上面就是计算用户输入的key然后比较长度是否等于0xC不等于就跳向结束错误了,改变标志位,让它不跳。
004010C0|> /8A0432 /mov al,byte ptr ds:
004010C3|. |8BFE |mov edi,esi
004010C5|. |34 05 |xor al,0x5
004010C7|. |83C9 FF |or ecx,0xFFFFFFFF
004010CA|. |880432 |mov byte ptr ds:,al
004010CD|. |33C0 |xor eax,eax
004010CF|. |42 |inc edx
004010D0|. |F2:AE |repne scas byte ptr es:
004010D2|. |F7D1 |not ecx
004010D4|. |49 |dec ecx
004010D5|. |3BD1 |cmp edx,ecx
004010D7|.^\72 E7 \jb XCrackMe1.004010C0
将用户输入的数据进行循环计算,计算方法就是将每位异或0X5。
这里的堆栈存放着软件的要比较的正确key的初始化值。
004010EB|> /8A4414 0C /mov al,byte ptr ss:
004010EF|. |8D7C24 0C |lea edi,dword ptr ss:
004010F3|. |04 F8 |add al,0xF8
004010F5|. |83C9 FF |or ecx,0xFFFFFFFF
004010F8|. |884414 0C |mov byte ptr ss:,al
004010FC|. |33C0 |xor eax,eax
004010FE|. |42 |inc edx
004010FF|. |F2:AE |repne scas byte ptr es:
00401101|. |F7D1 |not ecx
00401103|. |49 |dec ecx
00401104|. |3BD1 |cmp edx,ecx
00401106|.^\72 E3 \jb XCrackMe1.004010EB
这里对正确key的初始化值做了操作,操作是对每个值加上了0xF8,然后得到的值是Fw1fnH6/Mdfn,最后循环对着两个字符串做对比,只要有不同就跳向错误,下面就是比较反汇编代码:
00401120|> /8A5C14 0C /mov bl,byte ptr ss:
00401124|. |8D4414 0C |lea eax,dword ptr ss:
00401128|. |8A0C06 |mov cl,byte ptr ds:
0040112B|. |3ACB |cmp cl,bl
0040112D|. |75 1F |jnz XCrackMe1.0040114E
0040112F|. |8D7C24 0C |lea edi,dword ptr ss:
00401133|. |83C9 FF |or ecx,0xFFFFFFFF
00401136|. |33C0 |xor eax,eax
00401138|. |42 |inc edx
00401139|. |F2:AE |repne scas byte ptr es:
0040113B|. |F7D1 |not ecx
0040113D|. |49 |dec ecx
0040113E|. |3BD1 |cmp edx,ecx
00401140|.^\72 DE \jb XCrackMe1.00401120
好啦,分析得差不多啦,那就让我们整理下思路吧,然后把正确的key找出来。
用户输入一个字符串,程序先判断是否等于0xc,不等于就直接跳向错误,等于就继续,将用户输入的字符串每位依次异或0x5,然后将软件预定义的字符串每次加0xf8。好啦,下面写一个程序算出正确的key吧。
#include <stdio.h>
int main (void)
{
char str = "Fw1fnH6/Mdfn";
int i = 0;
while (str != '\0')
{
str = str ^ 0x5;
i++;
}
printf ("这就是你需要的东西:%s",str);
printf ("\n");
}
好啦,分析玩收工,送上key:Cr4ckM3*Hack。如果有什么没有分析到位的地方还请大家多多指出。
希望以后和大家多多交流,奋斗中的小菜{:301_987:}。文件在这里: 分析的不错,感谢 值得学习支持楼主! 恩 学习了 最近正学分析啊开始感觉很苦逼啊 回复 billy74 的帖子
只是兴趣吧,我想学来调试自己的软件,还有想去分析病毒:loveliness: 回复 lxj520dyn 的帖子
谢谢啊:loveliness: 完全不懂阿 试试看下 回复 汪洋 的帖子
这个不能再简单了:loveliness: 不错 哈哈