首页
社区
课程
招聘
[原创]一个crackme的分析
发表于: 2009-10-9 20:42 6614

[原创]一个crackme的分析

2009-10-9 20:42
6614

这个CM很好玩儿。花了几天时间终于破解了(实在是太笨了,所以花了几天。。。),觉得有必要将整个过程写下来与大家分享。语文没有学好,也没什么幽默感,所以文章不怎么好,希望大家不要笑话。有什么不当的地方还请各位多多指教。
OK,开始正文。

PEID分析,没有加壳,VC 6编写,有附加数据4个字节。另外,如果用PEID的插件KANAL分析,还会得知程序中使用了CRC32算法。

OD载入,不使用任何插件,首先运行一次,发现程序退出了。怀疑有反调试。使用插件隐藏一下OD,F9运行,这下可以了,程序没有退出。

随便输入用户名和KEY,点击OK按钮,发现会弹出出错提示。那我们就下MessageBoxA断点试试。命令行输入bp MessageBoxA,好,断下来了。单步执行,直到返回程序领空00401606。
 

取消MessageBoxA断点,然后向上翻,找到代码最开始处00401440,下INT3断点。OK,再次F9运行,发现程序又退出了。(。。郁闷啊。。)多次试验后,发现:只要(在程序的代码段)下INT3断点,程序就会退出。联想到《加密与解密 第三版》上关于INT3断点的介绍,猜测程序对代码段有自校验,于是取消所有INT3断点,改下硬件断点。OK!这次可以了。高兴啊。。。。
 
上图显示的就是注册算法部分的代码。注册算法如下(大家自己跟踪一下看看):

  字节数组a[0...8] = {0x4b, 0x45, 0x59, 0x2d, 0x4b, 0x41, 0x4e, 0x4f, 0x4e}
  ESI = 累加用户名各个字节
  EDI = 累加 {  [ (a[i] * ESI) mod 26 + 'a' ]  xor  0xaa } , i=0...8
  KEY必须是9个字节,其各个字节与0xaa异或后的累加值 == EDI, 则注册成功。

算法就是这样。很简单的。注册机如下:


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 88
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
支持兄弟一下
2009-10-9 22:41
0
雪    币: 291
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主的OD色彩漂亮
2009-10-9 22:43
0
雪    币: 347
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
看了LZ的文章,立马开动自己也尝试了一下,OD载入CM,F9果然程序直接退出了,但是直接选项插件里的HIDEOD貌似也不行,必须是如下图:


下面还没分析,单纯看这个OD的选项,喔觉得CM的作者可能调用了IsDebuggerPresent亦或者用内联汇编实现了一个类似反调试工具的函数,猜测,继续分析再验证
喔是小菜,所以为了避免别的小菜不知道,在这里提一下
上传的附件:
2009-10-11 16:01
0
雪    币: 440
活跃值: (87)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
5
程序就是调用API---IsDebuggerPresent来检测调试器的。
调用地址00401761.

关于这一点,附件里的CPP文件的注释里面有说明。
2009-10-11 16:24
0
雪    币: 347
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
终于跟着LZ实践了一遍
我想从这个例子中可以学到比较有价值的2点
1 对于笨鸟可以利用调试器巧妙绕过反调试技术
2 也可以具体分析其中的反调试技术,反反调试它:)
2009-10-11 17:57
0
雪    币: 126
活跃值: (37)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
7
首先感谢原创作者,在调试过程中学到了很多东西。本人根据作者的思路调试了一下,有了些许改进,总结如下:                        
                                  一个CM的分析 CRC校验、反调试
                                                浪淘沙-407668055
标 题: 【原创】一个crackme的分析
作 者: asdfslw
时 间: 2009-10-09,20:42
链 接: http://bbs.pediy.com/showthread.php?t=99200
1、运行程序,看下程序运行情况
2、 PEID分析,Microsoft Visual C++ 6.0 [Overlay]  CRC32算法
3、OD载入,不使用任何插件,首先运行一次,发现程序退出了。
4.、随便输入用户名和KEY,点击OK按钮,发现会弹出出错提示。
5.、查找程序段:
(1)下MessageBoxA断点命令行输入bp MessageBoxA,好,断下来了。单步执行,直到返回程序领空00401606。
   (2)暂停查看堆栈调用法
6、向上翻,找到代码最开始处00401440,下INT3断点。OK,再次F9运行,发现程序退出了。这是因为程序对代码段有自校验,于是取消所有INT3断点,改下硬件断点。OK!
说明:Int 3 断点会修改代码,为 00CC,导致程序校验值的变化
7、

004015A4   .  85C0          test eax,eax            ;  不让它跳试试
004015A6      74 1A         je short CrackMe.004015C2                
;  je 跳过下面的jmp 关键跳转,改了就会程序终止,有自校验
004015A8   .  33FF          xor edi,edi      ;  比较典型的关键跳转
004015A6     /74 1A         je short CrackMe.004015C2                ;  je 跳过下

直接NOP掉这条指令即可爆破了
这篇文章的作者说把它改为 jmp 是错误的,这可能是因为作者虽然找到了CRC校验的位置,但没有去除自校验,所以无法验证的缘故。
我们保存了两处修改,但保存的程序打开就关闭,所以它可能还有一个校验位置,启动时进行校验
8、单从破解的角度来说,写到这里就算结束了。但是从学习的角度来说,并没有完。因为我们还不知道程序是如何实现反调试功能的。所以我们还要继续分析自校验的位置。
由于是MFC程序,所以可以使用mfcspy来找消息映射。
message map=004032F8(CrackMe.exe+0032F8)
msg map entries at 00403300(CrackMe.exe+003300)
OnMsg:WM_PAINT(000f),func=00401370(CrackMe.exe+001370)
OnMsg:WM_QUERYDRAGICON(0037),func=00401430(CrackMe.exe+001430)
OnCommand: notifycode=0000 id=03e8,func=00401440(CrackMe.exe+001440)
OnMsg:WM_TIMER(0113),func=00401A10(CrackMe.exe+001A10)  时间周期 循环函数 对应偏移地址00401A10 我们去看看
OnMsg:WM_CLOSE(0010),func=00401350(CrackMe.exe+001350)
发现程序响应了WM_TIMER消息。OD中Ctrl+G来到00401A10处,发现程序call 00401A40两次,跟进去发现这个函数读取了文件的附加数据(4个字节数据,即为CRC32值),并且计算了内存中的代码段的CRC32值,然后比较两者,不同则退出。。。。

终于发现自校验的地方了。
00401A10   .  56            push esi               ;  timer 的函数体
00401A11   .  8BF1          mov esi,ecx
00401A13   .  E8 28000000   call CrackMe.00401A40
00401A18   .  85C0          test eax,eax
00401A1A      75 07         jnz short CrackMe.00401A23  ;  退出哦 跳过了下面的退出位置, 
00401A1C   .  50            push eax                改它为jmp就可以了; /ExitCode
00401A1D   .  FF15 00324000 call dword ptr ds:[<&USER32.PostQuitMess>; \PostQuitMessage
00401A23   >  8BCE          mov ecx,esi
00401A25   .  E8 16000000   call CrackMe.00401A40
00401A2A   .  8BCE          mov ecx,esi
00401A2C   .  E8 CF020000   call <jmp.&MFC42.#2379>
00401A31   .  5E            pop esi
00401A32   .  C2 0400       retn 4

我们发现了程序的自校验位置,程序未做修改的话就跳过退出代码,否则执行退出代码。
改为JMP,让它一直跳即可。
改完以后,保存的程序打开时一闪而过,说明程序启动时还有校验,刚才找了一会也没找到再哪里,开两个OD法不太好找,我们找下试试。用刚才保存的来做,里面有我下好的断点
我发现在这个位置
73D46B9B   /74 62           je short MFC42.73D46BFF
出现了不同,改动过的会跳过去,而不改的不会跳
事实上,这里就是那个位置了,改改标志位不让它跳程序就能跑起来,是吧!!

我们试图修改代码,结果它就终止了,不过由于这里是系统领空,所以也不能保存。注意,如果你非要改了试试的话,千万别把系统的DLL给覆盖了,否则后果自负哦。
我们再改一下那个CRC函数试试,不可以,启动时并不用这个函数.

暂时我还不能找到,如果您能找到这个重启自校验的位置,请告诉我哈。
本人邮箱:tangjiutao@gmail.com

在这里,我觉得对VC消息处理函数的寻找是主要学习的内容,就是用这个工具mfcspy.exe,看雪里面可以下载。

谢谢,高手莫要见笑….
本人有自己做的视频,有需要的可以与我联系,免费提供哦!!
2009-11-18 16:44
0
游客
登录 | 注册 方可回帖
返回
//