首先感谢原创作者,在调试过程中学到了很多东西。本人根据作者的思路调试了一下,有了些许改进,总结如下:
一个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,看雪里面可以下载。
谢谢,高手莫要见笑….
本人有自己做的视频,有需要的可以与我联系,免费提供哦!!