首页
社区
课程
招聘
[原创]再探 CrackMe001 By飘云[PYG](一)[原创]
发表于: 2008-1-18 08:53 7472

[原创]再探 CrackMe001 By飘云[PYG](一)[原创]

petnt 活跃值
12
2008-1-18 08:53
7472

【文章标题】: 再探 CrackMe001 By飘云[PYG](一)
【文章作者】: petnt
【作者邮箱】: petnt@sohu.com
【软件名称】: CrackMe001 By飘云[PYG]
【下载地址】: 自己搜索下载
【加壳方式】: FSG2.0
【保护方式】: 壳\注册码
【使用工具】: OD\UltraEdit-32\ImportREC.exe
【操作平台】: XpSp2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【前    言】
  这两天分析一个小软受挫(其实是经常的事),不得不再次捧起“PEDIY CrackMe 2007”发奋苦读。有破文跟着就不怕受挫了:)。这个CrackMe的算法分析破文已由busheler大侠2006年1月18日完成(再过3个小时就是2008.01.18了  ,小菜我默默无语两眼泪,耳边响起驼铃声),之所以再次提起它,还得从busheler大侠的破文说起。。。。

  记得那是2002年的第一场雪。。。。。。。。。又要跑。。。我回:

********************************************************************************  
  算法初探--Crackme001 By 飘云[PYG]
  1.去除启动时的延时。
  2.分析算法。
  3.去除退出时的Nag。
  
  备注:
  1、由于我系统时间格式的问题,该CrackMe运行时总弹出这样的对话框:"'2006-2' is not a valid integer value"...,并造成第三个验证码总为0,呵呵。感谢飘云指导,并顺利完成注册码算法分析!:)

  2、关于“去除启动时的延时”及“去除退出时的Nag”未分析。
*********************************************************************************
                                      以上内容引自《算法分析之CrackMe001 By飘云[PYG]》By busheler
  
  busheler提到的bug在我的菜机上也出现了,一是想探个究竟,二是想完成大侠留下的任务,所以有了本破文,算是一篇续吧(只是比2002年来的稍晚了一些)。

【正    文】

  第一幕 脱 壳

  这个程序是带壳的(FSG 2.0 -> bart/xt ),为了锻炼队伍,我们手动解决。

00400154 >  8725 B8574C00   xchg    dword ptr [4C57B8], esp ;;;;;;载入后我们停到这里
0040015A    61              popad
;;;;;;;;;;;此处省略部分代码;;;;;;;;;;;;;
004001B7    56              push    esi
004001B8    8BF7            mov     esi, edi
004001BA    2BF0            sub     esi, eax
004001BC    F3:A4           rep     movs byte ptr es:[edi], byte ptr>
004001BE    5E              pop     esi
004001BF  ^ EB 9F           jmp     short 00400160
004001C1    5E              pop     esi
004001C2    AD              lods    dword ptr [esi]           ;;;;;;;;;;;;;;;;;;;;;;;;
004001C3    97              xchg    eax, edi                                         ;
004001C4    AD              lods    dword ptr [esi]                                  ;
004001C5    50              push    eax                                              ;
004001C6    FF53 10         call    dword ptr [ebx+10]                               ;
004001C9    95              xchg    eax, ebp                                         ;此
004001CA    8B07            mov     eax, dword ptr [edi]                             ;处
004001CC    40              inc     eax                                              ;处
004001CD  ^ 78 F3           js      short 004001C2                                   ;理
004001CF    75 03           jnz     short 004001D4                                   ;输
004001D1    FF63 0C         jmp     dword ptr [ebx+C]         ;;;;;;;;可爱的跳转     ;入
004001D4    50              push    eax                                              ;表
004001D5    55              push    ebp                                              ;
004001D6    FF53 14         call    dword ptr [ebx+14]                               ;
004001D9    AB              stos    dword ptr es:[edi]        ;;;;;;;;IAT的地址      ;
004001DA  ^ EB EE           jmp     short 004001CA            ;;;;;;;;;;;;;;;;;;;;;;;;
004001DC    33C9            xor     ecx, ecx
004001DE    41              inc     ecx
004001DF    FF13            call    dword ptr [ebx]
004001E1    13C9            adc     ecx, ecx
004001E3    FF13            call    dword ptr [ebx]
004001E5  ^ 72 F8           jb      short 004001DF
004001E7    C3              retn                           
004001E8    02D2            add     dl, dl
004001EA    75 05           jnz     short 004001F1
004001EC    8A16            mov     dl, byte ptr [esi]
004001EE    46              inc     esi
004001EF    12D2            adc     dl, dl
004001F1    C3              retn
  
  上面的分析是我一步步跟踪得到的,因为这是个简单的加密壳,所以这些分析结果应该很容易就得出。这里我们关心的只有两处:IAT地址我们将用来修复输入表;可爱的跳转将带我们飞向光明之巅(fly大侠的经典,绝对经典)。先F4到00401D9,记下IAT位置,在F4到可爱的跳转上,F8。

004689C8    55              push    ebp                      ;;;;;;;;传说中的光明之巅
004689C9    8BEC            mov     ebp, esp
004689CB    83C4 F0         add     esp, -10
004689CE    B8 D0874600     mov     eax, 004687D0
004689D3    E8 88D2F9FF     call    00405C60
004689D8    A1 90A94600     mov     eax, dword ptr [46A990]
004689DD    8B00            mov     eax, dword ptr [eax]
004689DF    E8 CCAAFEFF     call    004534B0
004689E4    A1 90A94600     mov     eax, dword ptr [46A990]
004689E9    8B00            mov     eax, dword ptr [eax]
004689EB    BA 288A4600     mov     edx, 00468A28                    ; ASCII "CrackMe 001 By 飘云[PYG]"
004689F0    E8 CBA6FEFF     call    004530C0
004689F5    8B0D 84A74600   mov     ecx, dword ptr [46A784]          ; CrackMe0.0046BC08
004689FB    A1 90A94600     mov     eax, dword ptr [46A990]
00468A00    8B00            mov     eax, dword ptr [eax]
00468A02    8B15 C47E4600   mov     edx, dword ptr [467EC4]          ; CrackMe0.00467F10
00468A08    E8 BBAAFEFF     call    004534C8
00468A0D    A1 90A94600     mov     eax, dword ptr [46A990]
00468A12    8B00            mov     eax, dword ptr [eax]
00468A14    E8 2FABFEFF     call    00453548
00468A19    E8 3EB3F9FF     call    00403D5C

  看到这里我们没有理由再愣着了,dump。先不要关掉OD,赶紧请出ImportREC.exe。Rva填上我们记下的地址(转换RVA),大小我懒得填,默认吧。获取输入表。。。
  
  等着我们的是N多的无效,去我们的记下的地址上看个究竟:

0046C12C  8A 18 93 7C ED 10 92 7C 05 10 92 7C A1 9F 80 7C  ?搢?抾抾€|
0046C13C  14 9B 80 7C 81 9A 80 7C 5D 99 80 7C BD 99 80 7C  泙|仛€|]檧|綑€|
0046C14C  AB 14 81 7C 37 97 80 7C 94 97 80 7C 7B 97 80 7C  ?亅7梹|敆€|{梹|
0046C15C  59 B8 80 7C C7 A0 80 7C AD 9C 80 7C E0 C6 80 7C  Y竴|菭€|瓬€|嗥€|
0046C16C  11 03 81 7C B0 2F 88 7C 05 A4 80 7C EE 1E 80 7C  亅?坾|?€|
0046C17C  EC 2F 88 7C 29 B5 80 7C 57 B3 80 7C 7E D4 80 7C  ?坾)祤|W硛|~詟|
0046C18C  8D 2C 81 7C 66 AA 80 7C 59 35 81 7C D7 EF 80 7C  ?亅f獉|Y5亅罪€|
0046C19C  A2 CA 81 7C 9F 0F 81 7C 8A 2B 86 7C 40 7A 95 7C  ⑹亅?亅?唡@z晐
0046C1AC  E1 EA 81 7C A9 2C 81 7C FF FF FF 7F 46 FA D3 77  彡亅?亅Fw
0046C1BC  98 EC D3 77 0B 05 D5 77 40 EC D3 77 FF FF FF 7F  橃觲誻@煊w
0046C1CC  83 78 DA 77 1B 76 DA 77 F0 6B DA 77 FF FF FF 7F  儀趙v趙餶趙
0046C1DC  50 48 0F 77 9D C9 11 77 59 4B 0F 77 FF FF FF 7F  PHw澤wYKw

  呵呵,原来有很多扎眼的 7FFFFFFF 在这里,把无效的指针和 7FFFFFFF Cut掉,修复我们的Dump文件,修复好后确认入口为:000689C8。程序顺利的运行了。

  第二幕 Fix Bug

  载入dump,F9。程序会异常在系统领空,观察堆栈,找到SEH上面的返回地址,我们从源头找起。

004685B0  /.  55               push    ebp
004685B1  |.  8BEC             mov     ebp, esp
004685B3  |.  33C9             xor     ecx, ecx
004685B5  |.  51               push    ecx
004685B6  |.  51               push    ecx
004685B7  |.  51               push    ecx
004685B8  |.  51               push    ecx
004685B9  |.  33C0             xor     eax, eax
004685BB  |.  55               push    ebp
004685BC  |.  68 7F864600      push    0046867F                    ; 安装SEH
004685C1  |.  64:FF30          push    dword ptr fs:[eax]
004685C4  |.  64:8920          mov     dword ptr fs:[eax], esp
004685C7  |.  C705 14BC4600 0A>mov     dword ptr [46BC14], 0A
004685D1  |.  E8 7A10FAFF      call    00409650
004685D6  |.  83C4 F8          add     esp, -8                     ; /
004685D9  |.  DD1C24           fstp    qword ptr [esp]             ; |Arg1 (8 字节)
004685DC  |.  9B               wait                                ; |
004685DD  |.  8D45 FC          lea     eax, dword ptr [ebp-4]      ; |
004685E0  |.  E8 7F1CFAFF      call    0040A264                    ; \dump2.0040A264
004685E5  |.  8B55 FC          mov     edx, dword ptr [ebp-4]      ; 上面获取系统时间 我的为“2008-1-17”
004685E8  |.  B8 10BC4600      mov     eax, 0046BC10
004685ED  |.  E8 AEB8F9FF      call    00403EA0
004685F2  |.  8D45 F8          lea     eax, dword ptr [ebp-8]
004685F5  |.  50               push    eax
004685F6  |.  B9 04000000      mov     ecx, 4
004685FB  |.  BA 01000000      mov     edx, 1
00468600  |.  A1 10BC4600      mov     eax, dword ptr [46BC10]
00468605  |.  E8 62BDF9FF      call    0040436C                    ; 取时间字符串的前4(年)
0046860A  |.  FF75 F8          push    dword ptr [ebp-8]
0046860D  |.  8D45 F4          lea     eax, dword ptr [ebp-C]
00468610  |.  50               push    eax
00468611  |.  B9 02000000      mov     ecx, 2
00468616  |.  BA 06000000      mov     edx, 6
0046861B  |.  A1 10BC4600      mov     eax, dword ptr [46BC10]
00468620  |.  E8 47BDF9FF      call    0040436C                    ; 取第6开始的2位(月)
00468625  |.  FF75 F4          push    dword ptr [ebp-C]
00468628  |.  8D45 F0          lea     eax, dword ptr [ebp-10]
0046862B  |.  50               push    eax
0046862C  |.  B9 02000000      mov     ecx, 2
00468631  |.  BA 09000000      mov     edx, 9
00468636  |.  A1 10BC4600      mov     eax, dword ptr [46BC10]
0046863B  |.  E8 2CBDF9FF      call    0040436C                    ; 取第9开始的2位(日)
00468640  |.  FF75 F0          push    dword ptr [ebp-10]
00468643  |.  B8 0CBC4600      mov     eax, 0046BC0C
00468648  |.  BA 03000000      mov     edx, 3
0046864D  |.  E8 7ABBF9FF      call    004041CC                    ; 合并
00468652  |.  A1 0CBC4600      mov     eax, dword ptr [46BC0C]
00468657  |.  E8 44F8F9FF      call    00407EA0                    ; 字符变数字
0046865C  |.  C1E0 03          shl     eax, 3                      ; 相当于 * 2^3
0046865F  |.  A3 18BC4600      mov     dword ptr [46BC18], eax     ; 保存(此数字将用于注册码的产生)
00468664  |.  33C0             xor     eax, eax
00468666  |.  5A               pop     edx
00468667  |.  59               pop     ecx
00468668  |.  59               pop     ecx
00468669  |.  64:8910          mov     dword ptr fs:[eax], edx
0046866C  |.  68 86864600      push    00468686
00468671  |>  8D45 F0          lea     eax, dword ptr [ebp-10]
00468674  |.  BA 04000000      mov     edx, 4
00468679  |.  E8 F2B7F9FF      call    00403E70
0046867E  \.  C3               retn

  上面的分析可以明显地看到错误产生的过程,由于时间字符串为“2008-1-17”,而不是作者以为的“2008-01-17”(从取字符的过程知道这是作者想要的),在取月和日的时候,程序将取不到预期的数字,使得程序出错。好了,我们去找这个日期字符串产生的源头看看(我跋山涉水啊,翻山越岭啊)。。

0040ABA4      68 00010000            push    100
0040ABA9      8D8D 00FFFFFF          lea     ecx, dword ptr [ebp-100]
0040ABAF      51                     push    ecx
0040ABB0      52                     push    edx
0040ABB1      50                     push    eax
0040ABB2      E8 31B3FFFF            call    <jmp.&kernel32.GetLocaleInfoA> ;;;;;哈哈,他藏在这里
0040ABB7      85C0                   test    eax, eax
0040ABB9      7E 12                  jle     short 0040ABCD
0040ABBB      8BC8                   mov     ecx, eax
0040ABBD      49                     dec     ecx
0040ABBE      8D95 00FFFFFF          lea     edx, dword ptr [ebp-100]
0040ABC4      8BC3                   mov     eax, ebx
0040ABC6      E8 7193FFFF            call    00403F3C
0040ABCB      EB 09                  jmp     short 0040ABD6

  原来程序在获得系统的日期格式,我的短日期格式为yyyy-M-D。应该是这里的问题,我们做下实验。

  区域语言选项 -> 区域选项 -> 自定义区域选项-> 日期:短格式日期  yyyy-M-D 改为 yyyy-MM-DD。再运行程序,呵呵,没有错误了。

  我的短日期格式设置中有四个选项,呵呵,程序会出错的几率还是很大的。只有yyyy-M-D(日期和月份必须大于等于10),yyyy-MM-DD时程序才能正确运行。

  不让风险存在就是让他永远为yyyy-MM-DD。还用函数获取什么,我们给他固定吧:
  
  先找个地方放好(我选这里) 0040C3D0  00 00 79 79 79 79 2D 4D 4D 2D 44 44 00 00 00 00  ..yyyy-MM-DD....
  
  再来改程序:

0040ABA4      B8 0B000000            mov     eax, 0B                          ; eax为字符串长度,我们也固定
0040ABA9      EB 0C                  jmp     short 0040ABB7                   ; 直接跳过
0040ABAB      00FF                   add     bh, bh
0040ABAD      FFFF                   ???                                      ; 未知命令
0040ABAF      51                     push    ecx
0040ABB0      52                     push    edx
0040ABB1      50                     push    eax
0040ABB2      E8 31B3FFFF            call    <jmp.&kernel32.GetLocaleInfoA>
0040ABB7  |.  85C0                   test    eax, eax                         ; 跳到这里
0040ABB9  |.  7E 12                  jle     short 0040ABCD
0040ABBB  |.  8BC8                   mov     ecx, eax
0040ABBD  |.  49                     dec     ecx
0040ABBE      BA D2C34000            mov     edx, 0040C3D2                    ; ASCII "yyyy-MM-DD"
0040ABC3      90                     nop                                      ; 把我们设计好的值给edx
0040ABC4  |.  8BC3                   mov     eax, ebx
0040ABC6  |.  E8 7193FFFF            call    00403F3C
0040ABCB  |.  EB 09                  jmp     short 0040ABD6

  保存,运行,OK了。当然我们这样做也有风险,就是如果程序加载的基址不是00400000就会出错了,但这种风险因该小得多了吧:)。

  好了,时间不早了,就写到这里吧,写的太长也容易让大家看得睡着了。第三幕 Kill Timer ,第四幕 Remove NAG 就明天再写吧。

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!(未完,待续)

                                                       2008年01月17日 23:32:10


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
原来还有这样的技巧啊
学习  petnt的文章总能学到东西
2008-1-18 18:49
0
雪    币: 740
活跃值: (952)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
3
高顶炸药包.
2008-1-18 19:23
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
4
谢谢二位捧场,第二部分努力完成中。。。。
2008-1-18 20:24
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
2008.01.18了  ,小菜我默默无语两眼泪,耳边响起驼铃声),之所以再次提起它,还得从busheler大侠的破文说起。。。。

  记得那是2002年的第一场雪。。。。。。。。。又要跑。。。我回:
拐卖了 拐了 拐了
2008-2-25 01:17
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
软件破解群35780346  
从事专业软件逆向 软解破解 精通汇编,精通静态 动态的调试工具,
供大家交流学习。
打一下 公告
2008-2-25 01:20
0
雪    币: 134
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
不错不错,学习了,建议把我楼上的T了。
2008-2-25 09:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
什么时候看petnt大侠的破文都能有所收获.

支持下文!! 期待!
2008-3-8 03:47
0
雪    币: 203
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
petnt大侠看来是漏掉此帖了,提醒他一下:)
2008-3-11 00:06
0
雪    币: 246
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
10
看petnt大侠的破文有收获.
2008-3-11 09:15
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
11
2008-3-11 21:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
7FFFFFFF 这个地方不太好理解 是改成00000000吗   程序会异常在系统领空,观察堆栈,找到SEH上面的返回地址  思路相当强 下面的修改系统时间就超出理解范围了。。。
2008-6-17 10:36
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
一起学习了。。。
2008-6-19 22:19
0
游客
登录 | 注册 方可回帖
返回
//