本帖最后由 xiangshen 于 2011-12-7 15:47 编辑
非常入门的一个CrackMe和大家分享 [文章标题]:非常入门的一个CrackMe和大家分享 [文章作者]:willjhw [软件名称]:CrackMe1.exe [加壳方式]:无壳 [编写语言]:MicrosoftVisual C++ 6.0 [操作系统]:windows xp sp3 [软件介绍]:很久以前参加学校比赛的逆向第一题。 [作者声明]:这个是非常入门级的CrackMe,整理文件的时候翻出来和大家分享,自己也总结下,大牛可绕过。 --------------------------------------------------------------------------------------------------------------------------------- [前言]: 移动硬盘被感染了那个所谓的白蚁病毒,好烦啊,只有整理软件些,尽力挽回我的软件,发现几年前参加比赛的一个CrackMe,当初不懂逆向,看着也没有办法,现在可以很好的分析了,所以同很多像我当初那样的朋友分享下,大家共同进步,加油。 [详细过程]:
首先是查壳啦,如下图
没有壳,小喜一下,由PEID可以看出是用VC写的控制台程序,运行程序随便输入一个数字,如图: 发现了关键字Try again~,于是打开OD,搜索字符串,如图: 这个就是关键地方啦,我们就在最上面下一个断点,F9跑起来。 00401000 /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:[esp+0x4]
00401014 |. 50 push eax
00401015 |. E8 46010000 call CrackMe1.00401160
0040101A |. 8D4C24 08 lea ecx,dword ptr ss:[esp+0x8]
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:[esp+0x1C]
0040107D |. 57 push edi
0040107E |. 894C24 10 mov dword ptr ss:[esp+0x10],ecx
00401082 |. 884424 18 mov byte ptr ss:[esp+0x18],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:[0x40707C]
00401093 |. F2:AE repne scas byte ptr es:[edi] ; 计算用户输入的字符串长度
00401095 |. F7D1 not ecx
00401097 |. 49 dec ecx
00401098 |. 895424 14 mov dword ptr ss:[esp+0x14],edx
0040109C |. 8BD1 mov edx,ecx
0040109E |. 8D7C24 0C lea edi,dword ptr ss:[esp+0xC]
004010A2 |. 83C9 FF or ecx,0xFFFFFFFF
004010A5 |. F2:AE repne scas byte ptr es:[edi]
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:[edx+esi]
004010C3 |. |8BFE |mov edi,esi
004010C5 |. |34 05 |xor al,0x5
004010C7 |. |83C9 FF |or ecx,0xFFFFFFFF
004010CA |. |880432 |mov byte ptr ds:[edx+esi],al
004010CD |. |33C0 |xor eax,eax
004010CF |. |42 |inc edx
004010D0 |. |F2:AE |repne scas byte ptr es:[edi]
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:[esp+edx+0xC]
004010EF |. |8D7C24 0C |lea edi,dword ptr ss:[esp+0xC]
004010F3 |. |04 F8 |add al,0xF8
004010F5 |. |83C9 FF |or ecx,0xFFFFFFFF
004010F8 |. |884414 0C |mov byte ptr ss:[esp+edx+0xC],al
004010FC |. |33C0 |xor eax,eax
004010FE |. |42 |inc edx
004010FF |. |F2:AE |repne scas byte ptr es:[edi]
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:[esp+edx+0xC]
00401124 |. |8D4414 0C |lea eax,dword ptr ss:[esp+edx+0xC]
00401128 |. |8A0C06 |mov cl,byte ptr ds:[esi+eax]
0040112B |. |3ACB |cmp cl,bl
0040112D |. |75 1F |jnz XCrackMe1.0040114E
0040112F |. |8D7C24 0C |lea edi,dword ptr ss:[esp+0xC]
00401133 |. |83C9 FF |or ecx,0xFFFFFFFF
00401136 |. |33C0 |xor eax,eax
00401138 |. |42 |inc edx
00401139 |. |F2:AE |repne scas byte ptr es:[edi]
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[13] = "Fw1fnH6/Mdfn";
int i = 0;
while (str[i] != '\0')
{
str[i] = str[i] ^ 0x5;
i++;
}
printf ("这就是你需要的东西:%s",str);
printf ("\n");
}
好啦,分析玩收工,送上key:Cr4ckM3*Hack。如果有什么没有分析到位的地方还请大家多多指出。
希望以后和大家多多交流,奋斗中的小菜。 |