【文章标题】: 过关 后飞笨鸟之CrackMe
【文章作者】: petnt
【作者邮箱】: petnt@sohu.com
【下载地址】: 自己搜索下载
【编写语言】: 易语言
【使用工具】: OllyIce\UltraEdit-32
【操作平台】: xpsp2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
第一次接触这样的CrackMe,玩起来比较有意思,像打游戏。
第一关 去除NAG
理一下思路:NAG在没有看见主窗口的时候就弹出了,很有可能是在某个窗口或控件初始化的时候加入的代码。如果是我用高级语言编程,我会这样做的。不知道是不是作者也像我一样,试试吧。在窗口的消息处理函数中下断,断下之后,eCode段F2。第一次断下不是我们要找的部分,F9被消息处理断下后再次eCode上F2,程序终于断在了我们关心之处。
0047235F 55 push ebp ; 断在这里
00472360 8BEC mov ebp, esp
00472362 81EC 08000000 sub esp, 8
00472368 68 04000080 push 80000004
0047236D 6A 00 push 0
0047236F 68 CBC04000 push 0040C0CB ; ASCII "NAG"
00472374 68 01030080 push 80000301
00472379 6A 00 push 0
0047237B 68 00000000 push 0
00472380 68 04000080 push 80000004
00472385 6A 00 push 0
00472387 68 CFC04000 push 0040C0CF
0047238C 68 03000000 push 3
00472391 BB 00030000 mov ebx, 300
00472396 E8 82040000 call 0047281D ; 显示NAG窗口
;;;上面这种形式其实就是MessaeBox的e语言版本,熟悉它吧;;;;;;;;
;;;因为下面我们会发现更多。从而发现作者加入的代码都集;;;;;;;;
;;;中在这里,我们无需为下断着急了。 ;;;;;;;;
0047239B 83C4 28 add esp, 28
0047239E 68 00000000 push 0
004723A3 BB C4060000 mov ebx, 6C4
004723A8 E8 70040000 call 0047281D ; 获取机器码 H
004723AD 83C4 04 add esp, 4
004723B0 68 01030080 push 80000301
004723B5 6A 00 push 0
004723B7 50 push eax
004723B8 68 01000000 push 1
004723BD BB 68010000 mov ebx, 168
004723C2 E8 56040000 call 0047281D ; 转换成 D String
004723C7 83C4 10 add esp, 10
004723CA 8945 F8 mov dword ptr [ebp-8], eax
004723CD 6A 00 push 0
004723CF FF75 F8 push dword ptr [ebp-8]
004723D2 6A FF push -1
004723D4 6A 08 push 8
004723D6 68 06000116 push 16010006
004723DB 68 01000152 push 52010001
004723E0 E8 4A040000 call 0047282F ; 将机器码送往编辑框
004723E5 83C4 18 add esp, 18
004723E8 8B5D F8 mov ebx, dword ptr [ebp-8]
004723EB 85DB test ebx, ebx
004723ED 74 09 je short 004723F8
004723EF 53 push ebx
004723F0 E8 2E040000 call 00472823 ; 清理
004723F5 83C4 04 add esp, 4
004723F8 8BE5 mov esp, ebp
004723FA 5D pop ebp
004723FB C3 retn ; 返回
找到了源头,一切都好解决了。我们只需将显示NAG的Call Nop掉,就可以过第一关了。在此我发现了e语言的两个可爱之处:第一,程序里的大部分函数自己并不负责堆栈平衡,在调用完函数之后会有 add esp,XX来平衡堆栈,这使我们基本可以肆无忌惮的Nop掉一个Call;第二,可执行文件各节的RawOffset和VirtualOffset是相同的,我们可以很方便的找到修改之处在文件中的位置。真是和谐社会啊,哈哈。
第二关 Enable Button And Edit
说实话这关费了好几个小时。一开始以为作者会在初始化的时候用代码 Disable/ReadOnly 两个控件,可是我并没有发现。难道我们要改资源?可是e语言的资源好像也并没有按照exe的套路堆放,他好像是把代码和资源都放在了ecode段。从何下手?难道作者想让我们加入补丁代码来实现?问题有点大,应该不会。总不能把控件集成到fnr里吧,更不会。代表控件风格的数据一定会在程序的某处存放着!坚定这个信念,一直走下去。
下断 CreateWindowExA ,我们去看看。几次F9之后,我们看到了我们关心的地方。
0013FA50 100AE119 /CALL 到 CreateWindowExA 来自 krnln.100AE113
0013FA54 00000000 |ExtStyle = 0
0013FA58 100E2B30 |Class = "BUTTON"
0013FA5C 00C43AC0 |WindowName = "Enable Me"
0013FA60 4C012F00 |Style = WS_CHILD|WS_TABSTOP|WS_CLIPSIBLINGS|WS_DISABLED|2F00 就是WS_DISABLED在作怪
0013FA64 00000080 |X = 80 (128.)
0013FA68 000000A2 |Y = A2 (162.)
0013FA6C 00000048 |Width = 48 (72.)
0013FA70 00000018 |Height = 18 (24.)
0013FA74 00860250 |hParent = 00860250 ('笨鸟的第一个Creakme',class='Afx:10000000:b:10011:1900015:0')
0013FA78 00000064 |hMenu = 00000064
0013FA7C 10000000 |hInst = 10000000
0013FA80 00000000 \lParam = NULL
下面的任务就是就是要发现是谁让 4C012F00 中 包含了 8000000h (WS_DISABLED=8000000h)。这个过程是枯燥无味的,我没有更好的捷径去发现是谁动了我的8000000,只是一步一步地向上看,看到函数头还没发现,就向上找到调用这个函数的函数,经过4-5次的翻山越岭,终于看见了一点曙光。
100534F9 E8 126FFDFF call 1002A410 ; 这是个关键函数
100534FE 8B4F 14 mov ecx, dword ptr [edi+14]
10053501 8D4406 04 lea eax, dword ptr [esi+eax+4] ; 留意这一行
10053505 83C4 04 add esp, 4
10053508 8B00 mov eax, dword ptr [eax]
1005350A F6C5 80 test ch, 80
1005350D 898424 8C000000 mov dword ptr [esp+8C], eax
;;;;;;;;;;;;;;;;;;;;;;省略部分内容;;;;;;;;;;;;;;;;;;;;;;;;;;;
10053549 E8 E266FDFF call 10029C30
1005354E F68424 8C000000>test byte ptr [esp+8C], 2
10053556 74 05 je short 1005355D
10053558 BD 00000008 mov ebp, 8000000 ; 原来他躲在这里
1005355D F68424 8C000000>test byte ptr [esp+8C], 4
10053565 74 06 je short 1005356D
决定要不要加上这个8000000h,权力在上面的eax,eax的来源是内存中的一块数据,我们跟过去看看。
001BDF5C 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 ...............
001BDF6C 07 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 .............. ;注意这一行的7
001BDF7C 39 24 47 00 00 00 00 00 00 00 00 00 00 00 00 00 9$G.............
001BDF8C 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ...............
001BDF9C 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ..............
001BDFAC 09 00 00 00 45 6E 61 62 6C 65 20 4D 65 F2 00 00 ....Enable Me?.
001BDFBC 00 1D 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ..............
001BDFCC 00 00 00 00 00 00 00 00 00 B3 AC BC B6 C1 B4 BD .........超级链
001BDFDC D3 BF F2 31 00 00 00 00 00 00 00 00 00 00 E8 00 涌?..........?
看到这里能不让我们产生联想吗?虽然我不能确定,但我要试试,Alt+ M 到ecode段瞧一瞧。
0046D9E0 04 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 .............. ;注意这一行的 7
0046D9F0 00 00 00 00 00 01 00 00 00 00 00 00 00 DA 00 00 ............?.
0046DA00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0046DA10 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 ..............
0046DA20 00 01 00 00 00 00 00 00 00 00 00 00 00 09 00 00 ...............
0046DA30 00 45 6E 61 62 6C 65 20 4D 65 F2 00 00 00 1D 00 .Enable Me?...
0046DA40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
0046DA50 00 00 00 00 00 00 B3 AC BC B6 C1 B4 BD D3 BF F2 ......超级链接框
标注的数字7就是上面的eax的值,将可执行文件这个位置上的7改成5,保存运行看看。怎么样?欣喜吧!!
同样的道理,我们会发现导致Edit ReadOnly的地方:
004712B0 00 00 FF FF FF 00 01 00 00 00 00 00 00 00 00 00 ............
004712C0 00 00 00 00 00 00 00 00 00 00 01 00 00 00 2A 00 .............*. ; 注意这一行的 01
004712D0 00 00 00 00 00 00 00 00 00 00 00 00 64 00 00 00 ............d...
004712E0 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 ................
004712F0 CA B9 CE D2 BF C9 CA E4 C8 EB A3 A1 00 00 00 00 使我可输入!....
将01改成00,保存文件,第二关通过。 第三关 揭秘算法
第一关我们已经发现了用户代码的集结地,我们应该能顺利的找到判断注册码的关键过程。
0047253A 55 push ebp
0047253B 8BEC mov ebp, esp
0047253D 81EC 28000000 sub esp, 28
00472543 C745 F8 0000000>mov dword ptr [ebp-8], 0
0047254A C745 FC 0000000>mov dword ptr [ebp-4], 0
00472551 C745 F0 0000000>mov dword ptr [ebp-10], 0
00472558 C745 F4 0000000>mov dword ptr [ebp-C], 0
0047255F C745 E8 0000000>mov dword ptr [ebp-18], 0
00472566 C745 EC 0000000>mov dword ptr [ebp-14], 0
0047256D 6A FF push -1
0047256F 6A 08 push 8
00472571 68 07000116 push 16010007
00472576 68 01000152 push 52010001
0047257B E8 A9020000 call 00472829 ; 获取注册码
00472580 83C4 10 add esp, 10
00472583 8945 E4 mov dword ptr [ebp-1C], eax
00472586 68 59C14000 push 0040C159
0047258B FF75 E4 push dword ptr [ebp-1C]
0047258E E8 E3FEFFFF call 00472476 ;
00472593 83C4 08 add esp, 8
00472596 83F8 00 cmp eax, 0
00472599 B8 00000000 mov eax, 0
0047259E 0F94C0 sete al
004725A1 8945 E0 mov dword ptr [ebp-20], eax
004725A4 8B5D E4 mov ebx, dword ptr [ebp-1C]
004725A7 85DB test ebx, ebx
004725A9 74 09 je short 004725B4
004725AB 53 push ebx
004725AC E8 72020000 call 00472823
004725B1 83C4 04 add esp, 4
004725B4 837D E0 00 cmp dword ptr [ebp-20], 0 ; 比较注册码是否为空
004725B8 0F84 3B000000 je 004725F9
004725BE 68 04000080 push 80000004
004725C3 6A 00 push 0
004725C5 68 5AC14000 push 0040C15A
004725CA 68 01030080 push 80000301
004725CF 6A 00 push 0
004725D1 68 00000000 push 0
004725D6 68 04000080 push 80000004
004725DB 6A 00 push 0
004725DD 68 5FC14000 push 0040C15F
004725E2 68 03000000 push 3
004725E7 BB 00030000 mov ebx, 300
004725EC E8 2C020000 call 0047281D ; 提示 请输入注册码
004725F1 83C4 28 add esp, 28
004725F4 E9 D0010000 jmp 004727C9
004725F9 6A FF push -1
004725FB 6A 08 push 8
004725FD 68 06000116 push 16010006
00472602 68 01000152 push 52010001
00472607 E8 1D020000 call 00472829 ; 获取机器码
0047260C 83C4 10 add esp, 10
0047260F 8945 E4 mov dword ptr [ebp-1C], eax
00472612 68 04000080 push 80000004
00472617 6A 00 push 0
00472619 8B45 E4 mov eax, dword ptr [ebp-1C]
0047261C 85C0 test eax, eax
0047261E 75 05 jnz short 00472625
00472620 B8 59C14000 mov eax, 0040C159
00472625 50 push eax
00472626 68 01000000 push 1
0047262B BB 64010000 mov ebx, 164
00472630 E8 E8010000 call 0047281D ; 将注册码转换成浮点数并保存
00472635 83C4 10 add esp, 10
00472638 8945 DC mov dword ptr [ebp-24], eax
0047263B 8955 E0 mov dword ptr [ebp-20], edx
0047263E 8B5D E4 mov ebx, dword ptr [ebp-1C]
00472641 85DB test ebx, ebx
00472643 74 09 je short 0047264E
00472645 53 push ebx
00472646 E8 D8010000 call 00472823
0047264B 83C4 04 add esp, 4
0047264E DD45 DC fld qword ptr [ebp-24]
00472651 E8 BDFEFFFF call 00472513 ; 转换成64位十六进制
00472656 8945 F8 mov dword ptr [ebp-8], eax
00472659 8955 FC mov dword ptr [ebp-4], edx
0047265C 68 01030080 push 80000301
00472661 6A 00 push 0
00472663 68 40E20100 push 1E240
00472668 68 01030080 push 80000301
0047266D 6A 00 push 0
0047266F FF75 F8 push dword ptr [ebp-8]
00472672 68 02000000 push 2
00472677 BB CC000000 mov ebx, 0CC
0047267C E8 9C010000 call 0047281D ; Xor 1E240
00472681 83C4 1C add esp, 1C
00472684 99 cdq
00472685 8945 F0 mov dword ptr [ebp-10], eax
00472688 8955 F4 mov dword ptr [ebp-C], edx
0047268B 816D F0 F3220D0>sub dword ptr [ebp-10], 0D22F3 ; -0d22f3
00472692 835D F4 00 sbb dword ptr [ebp-C], 0
00472696 8145 F0 CF07000>add dword ptr [ebp-10], 7CF ; +7cf
0047269D 8355 F4 00 adc dword ptr [ebp-C], 0
004726A1 DF6D F0 fild qword ptr [ebp-10]
004726A4 DD5D E0 fstp qword ptr [ebp-20]
004726A7 DD45 E0 fld qword ptr [ebp-20]
004726AA DC0D 6CC14000 fmul qword ptr [40C16C] ; *2005
004726B0 DD5D D8 fstp qword ptr [ebp-28]
004726B3 DD45 D8 fld qword ptr [ebp-28]
004726B6 E8 58FEFFFF call 00472513
004726BB 8945 F0 mov dword ptr [ebp-10], eax
004726BE 8955 F4 mov dword ptr [ebp-C], edx
004726C1 DF6D F0 fild qword ptr [ebp-10]
004726C4 DD5D E0 fstp qword ptr [ebp-20]
004726C7 DD45 E0 fld qword ptr [ebp-20]
004726CA DC35 74C14000 fdiv qword ptr [40C174] ; /5
004726D0 DD5D D8 fstp qword ptr [ebp-28]
004726D3 DD45 D8 fld qword ptr [ebp-28]
004726D6 E8 38FEFFFF call 00472513
004726DB 8945 F0 mov dword ptr [ebp-10], eax
004726DE 8955 F4 mov dword ptr [ebp-C], edx
004726E1 6A FF push -1
004726E3 6A 08 push 8
004726E5 68 07000116 push 16010007
004726EA 68 01000152 push 52010001
004726EF E8 35010000 call 00472829 ; 获取注册码
004726F4 83C4 10 add esp, 10
004726F7 8945 E4 mov dword ptr [ebp-1C], eax
004726FA 68 04000080 push 80000004
004726FF 6A 00 push 0
00472701 8B45 E4 mov eax, dword ptr [ebp-1C]
00472704 85C0 test eax, eax
00472706 75 05 jnz short 0047270D
00472708 B8 59C14000 mov eax, 0040C159
0047270D 50 push eax
0047270E 68 01000000 push 1
00472713 BB 64010000 mov ebx, 164
00472718 E8 00010000 call 0047281D
0047271D 83C4 10 add esp, 10
00472720 8945 DC mov dword ptr [ebp-24], eax
00472723 8955 E0 mov dword ptr [ebp-20], edx
00472726 8B5D E4 mov ebx, dword ptr [ebp-1C]
00472729 85DB test ebx, ebx
0047272B 74 09 je short 00472736
0047272D 53 push ebx
0047272E E8 F0000000 call 00472823
00472733 83C4 04 add esp, 4
00472736 DD45 DC fld qword ptr [ebp-24]
00472739 E8 D5FDFFFF call 00472513 ; 转成64位16进制数
0047273E 8945 E8 mov dword ptr [ebp-18], eax
00472741 8955 EC mov dword ptr [ebp-14], edx
00472744 8B55 EC mov edx, dword ptr [ebp-14]
00472747 8B45 E8 mov eax, dword ptr [ebp-18]
0047274A 3945 F0 cmp dword ptr [ebp-10], eax ; 比较低32位
0047274D 75 03 jnz short 00472752
0047274F 3955 F4 cmp dword ptr [ebp-C], edx ; 比较高32位
00472752 0F85 3B000000 jnz 00472793
00472758 68 04000080 push 80000004
0047275D 6A 00 push 0
0047275F 68 7CC14000 push 0040C17C
00472764 68 01030080 push 80000301
00472769 6A 00 push 0
0047276B 68 00000000 push 0
00472770 68 04000080 push 80000004
00472775 6A 00 push 0
00472777 68 81C14000 push 0040C181
0047277C 68 03000000 push 3
00472781 BB 00030000 mov ebx, 300
00472786 E8 92000000 call 0047281D ; 注册成功
0047278B 83C4 28 add esp, 28
0047278E E9 36000000 jmp 004727C9
00472793 68 04000080 push 80000004
00472798 6A 00 push 0
0047279A 68 5AC14000 push 0040C15A
0047279F 68 01030080 push 80000301
004727A4 6A 00 push 0
004727A6 68 00000000 push 0
004727AB 68 04000080 push 80000004
004727B0 6A 00 push 0
004727B2 68 8AC14000 push 0040C18A
004727B7 68 03000000 push 3
004727BC BB 00030000 mov ebx, 300
004727C1 E8 57000000 call 0047281D ; 注册失败
004727C6 83C4 28 add esp, 28
004727C9 8BE5 mov esp, ebp
004727CB 5D pop ebp
004727CC C3 retn
呵呵,算法过程并不复杂。虽然程序看起来很长,但大部分都在push。哈哈,e语言又一大特点。算法如下:
注册码=(机器码 Xor 1E240H - 0d22f3H + 7CFH)*2005/5
这里用的是双精度浮点数运算,高级语言写注册机应该很简单。
机器码产生过程就不过多讲了,跟下程序就明白了。如果还不明白,请参照我的另一篇破文“KeyGen 阳小子emvⅠ”,难道E语言总是这样产生机器码?反正在我的机器上,这两个CrackMe产生的机器码相同。哈哈,省了我不少功夫。
由于此CrackMe程序过大,附件中将不附源CrackMe,请在论坛搜索下载。 如有分析不当之处,敬请指正。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年01月07日 22:44:55
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: