好友
阅读权限30
听众
最后登录1970-1-1
|
h_one
发表于 2013-8-20 21:41
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。
好久没有CrackMe了,特别是拿到mfc的程序更是着急。这篇帖子是小菜对MFC程序逆向的总结,感觉挺有用的,希望对大家有用。若果有什么地方分析的不好请提出。在此感谢zenghw大牛写的这系列作品,我的做法跟他讲诉的有所不同。
文章作者:zxcfvasd
软件名称:CRECKME 2.exe
保护方式:serial
加壳方式:无
使用工具:ollyICE
1.拿到该软件运行,可以了解到是以name和serial的方式进程保护的,没有错误提示
2.用Ollyice打开运行,出入name = honecm, serial = 12345678,此时不忙点击确定按钮。接下来点查看菜单--窗口(点右键刷新一下)--单击
这一步目的:设下了这个消息断点,意思就是一松开check键后就中断。如图被断下了
3.点查看菜单--内存--点击如下图那一行--按F2设断。
操作这步原因:
我们刚刚断下的地方,不是程序的领空,是跑到user32的领空了,在最顶的标题上可以了解到,这个我们一定是不关心的,都是一些api函数,我们要了解的是我们的程序的代码。你进到内存窗口后,发现是CRECKME这个属主只有五行,CRECKME就是我们的程序名了,我们要的就是返回到这,区段这里显示四种,因为我们是要分析它的执行代码,所以我们就选.text那一行设断了。那这样我们再点运行程序后,它就是断在CRECKME程序领空了。
4.返回到CreckMe程序领空后,如图
5.在这个窗口任意点击右键,添加全部函数列程的项目。如图:
这一步又是干什么用的?
现在我主要是想分析它运行了哪些主要函数代码,用这个可以跟踪,如运行过了会有红色显示出来,只要是红色显示出来的,那算法的代码一定在这里面了。
6.点运行程序,接下来就可以开始分析了。首先还是找那个范围出来吧。
点查看菜单--run跟踪--选择一行CRECKME--点右键选“统计模块”,
统计结果的每一行的意思是指它运行过的模块,双击每一行,都会跑到返汇编窗口,在每一下块的块首按F2设断,统计窗口共有三行,就设三次。
有关算法就在三个快里了,每个快里实现了一些功能。接下来就可以只看算法了,不会再跑到系统领空了。
重新运行,输入name, serial 点解确定后程序被断在上面那个图那。
这个CRECKME算法很简单的,
00401586 |. E8 CB030000 call <jmp.&MFC71.#6236>
0040158B |. 8D4B 74 lea ecx,dword ptr ds:[ebx+74]
0040158E |. FF15 9C314000 call dword ptr ds:[<&MFC71.#876>] ; 获取name
00401594 |. 8D5424 10 lea edx,dword ptr ss:[esp+10]
004015A2 |. 8A4424 16 mov al,byte ptr ss:[esp+16] ; name[6]
004015A6 |. 84C0 test al,al
004015A8 |. 75 50 jnz short CRECKME_.004015FA
004015AA |. 8A5424 15 mov dl,byte ptr ss:[esp+15] ; dl = name[5]
004015AE |. 84D2 test dl,dl
004015B0 |. 74 48 je short CRECKME_.004015FA
004015B2 |. 8B43 78 mov eax,dword ptr ds:[ebx+78] ; eax = 输入的serial对应16进制
004015B5 |. 3D A0860100 cmp eax,186A0
004015BA |. 7C 3E jl short CRECKME_.004015FA ; if(eax>=0x186A0)
004015BC |. 0FBE7424 12 movsx esi,byte ptr ss:[esp+12] ; 2
004015C1 |. 0FBE4C24 11 movsx ecx,byte ptr ss:[esp+11] ; 1
004015C6 |. 0FBE7C24 14 movsx edi,byte ptr ss:[esp+14] ; 4
004015CB |. 03CE add ecx,esi ; temp = name[2]+name[1]
004015CD |. 0FBE7424 10 movsx esi,byte ptr ss:[esp+10] ; esi = name[0]
004015D2 |. 03CE add ecx,esi ; temp = name[0]+name[1]+name[2]
004015D4 |. 0FBE7424 13 movsx esi,byte ptr ss:[esp+13] ; 3
004015D9 |. 0FBED2 movsx edx,dl ; edx = name[5]
004015DC |. 03F7 add esi,edi ; temp1 = name[3]+name[4];
004015DE |. 03F2 add esi,edx ; temp1 = temp1+name[5]
004015E0 |. 99 cdq
004015E1 |. BF E8030000 mov edi,3E8
004015E6 |. F7FF idiv edi ; eax/0x3E8
004015E8 |. 3BC8 cmp ecx,eax ; 前三位和 与 除数比较
004015EA |. 75 0E jnz short CRECKME_.004015FA
004015EC |. 3BF2 cmp esi,edx ; 余数 = 后三位和
004015EE |. 75 0A jnz short CRECKME_.004015FA
004015F0 |. 8B03 mov eax,dword ptr ds:[ebx]
004015F2 |. 8BCB mov ecx,ebx
这个算法就是输入的name长度6位,serial对应16进制大于等于0x186A0。serial/0x3E8,eax = 商,edx= 余数 如果商等于name前三位&&余数等于后3位和就成功。
int a = 0, b = 0;
if(name[6]!=0x00 || name == 0x00)
return;
if(serial < 0x186A0)
return;
for(int i = 0; i < 3; i++)
{
a += name;
}
for(i = 3; i < 6; i++)
{
b += name;
}
if(a == serial/0x3E8 && b == (serial%0x3E8))
{
success;
}
else
error;
这么CRECKME算法没什么特点,主要是对MFC代码跟踪。
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|