首页
社区
课程
招聘
[原创][破]CrackMe.cyberbob.VC.3
发表于: 2007-1-19 16:20 5407

[原创][破]CrackMe.cyberbob.VC.3

2007-1-19 16:20
5407

【文章标题】: [破]CrackMe.cyberbob.VC.3
【文章作者】: HappyTown
【作者主页】: www.pediy.com
【软件名称】: ppg_crackme
【软件大小】: 75.5KB(zip)
【下载地址】: 附件内
【加壳方式】: ASPack
【保护方式】: 灰色按钮,Math knowledge
【使用工具】: OD,IDA,BigCalc
【操作平台】: WinXP
【软件介绍】: 一个很有意思的CrackMe
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  1. 用PEiD的插件居然未脱掉ASPack的壳,害我手动脱之,而后却不用修复IAT即可直接运行;
  2. PEiD得知CRC32、Miracl、RC2、Tiger、SHA1 inside,呵呵,我喜欢;
  3. IDA分析,居然只是识别出了mirkill函数,很是扫兴,只好手动定位;
  4. 运行程序,Name、Company和OK按钮不可用,直接用eXeScope修改其属性;
  
  我在程序中手动定位找到了RC2和Tiger,但在注册的验证算法中却没有用到,难道有暗桩?
  直接查找出错信息,我们把断点下在405B75处。
  输入试炼码:
  happy
  pediy
  11111111-22222222-33333333
  为了下面解释方便,我们把sn分为3部分:sn_1-sn_2-sn_3
  
  00405B66   >push    0040EBA0                        ; /lParam = 40EBA0
  00405B6B   >push    0FF                             ; |wParam = FF
  00405B70   >push    0D                              ; |Message = WM_GETTEXT
  00405B72   >push    66                              ; |ControlID = 66 (102.)
  00405B74   >push    edi                             ; |hWnd
  00405B75   >call    [<&user32.SendDlgItemMessageA>] ; \SendDlgItemMessageA
  00405B7B   >test    eax, eax
  00405B7D   >mov     [40EDCC], eax
  00405B82   >je      00405C6E
  00405B88   >xor     esi, esi
  00405B8A   >xor     edx, edx
  00405B8C   >test    eax, eax
  00405B8E   >mov     [40EE48], esi
  00405B94   >mov     [40EE44], edx
  00405B9A   >jbe     00405C6E
  00405BA0   >mov     cl, [edx+40EBA0]
  00405BA6   >cmp     cl, 30                          ;  //sn只接受1~9,A~F
  00405BA9   >jb      short 00405BB0
  00405BAB   >cmp     cl, 39
  00405BAE   >jbe     short 00405BC0
  00405BB0   >cmp     cl, 41
  00405BB3   >jb      short 00405BBA
  00405BB5   >cmp     cl, 46
  00405BB8   >jbe     short 00405BC0
  00405BBA   >cmp     cl, 2D                          ;  '-'
  00405BBD   >jnz     short 00405C20                  ;  \\
  00405BBF   >inc     esi
  00405BC0   >inc     edx
  00405BC1   >cmp     edx, eax
  00405BC3   >jb      short 00405BA0
  00405BC5   >cmp     esi, 2                          ;  所以sn应该有2个'-'
  00405BC8   >mov     [40EE44], edx
  00405BCE   >mov     [40EE48], esi
  00405BD4   >jnz     00405C6E
  00405BDA   >push    8
  00405BDC   >push    0040EB10
  00405BE1   >call    00403F71
  00405BE6   >push    0040EDA8
  00405BEB   >push    0040EB10
  00405BF0   >push    0040EBA0
  00405BF5   >call    00408230
  00405BFA   >add     esp, 14
  00405BFD   >mov     [40EDCC], eax
  00405C02   >test    eax, eax
  00405C04   >jnz     short 00405C33
  00405C06   >push    40                              ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
  00405C08   >push    <Caption>                       ; |Title = "The PowerPuff Girls"
  00405C0D   >push    <Text>                          ; |Text = "Registration code is incorrect"
  00405C12   >push    edi                             ; |hOwner
  00405C13   >call    [<&user32.MessageBoxA>]         ; \MessageBoxA
  
  跟进405BF5的call:
  
  00408230  />sub     esp, 18
  00408233  |>push    ebx
  00408234  |>push    ebp
  00408235  |>push    esi
  00408236  |>push    edi
  00408237  |>push    0
  00408239  |>push    0C8                             ;  200
  0040823E  |>call    <mirsys>
  00408243  |>push    0
  00408245  |>mov     dword ptr [eax+238], 10         ;  mip->IOBASE = 16
  0040824F  |>call    <mirvar>
  00408254  |>push    0
  00408256  |>mov     [esp+24], eax
  0040825A  |>call    <mirvar>
  0040825F  |>push    0
  00408261  |>mov     [esp+24], eax
  00408265  |>call    <mirvar>
  0040826A  |>push    0
  0040826C  |>mov     [esp+30], eax
  00408270  |>call    <mirvar>
  00408275  |>push    0
  00408277  |>mov     ebx, eax
  00408279  |>call    <mirvar>
  0040827E  |>push    0
  00408280  |>mov     ebp, eax
  00408282  |>call    <mirvar>
  00408287  |>push    0
  00408289  |>mov     [esp+40], eax
  0040828D  |>call    <mirvar>
  00408292  |>push    0
  00408294  |>mov     [esp+48], eax
  00408298  |>call    <mirvar>
  0040829D  |>mov     edi, [esp+58]
  004082A1  |>mov     [esp+4C], eax
  004082A5  |>mov     eax, [esp+54]                   ;  sn
  004082A9  |>mov     ecx, edi
  004082AB  |>add     esp, 28
  004082AE  |>xor     esi, esi
  004082B0  |>sub     ecx, eax
  004082B2  |>/mov     dl, [eax]
  004082B4  |>|cmp     dl, 2D
  004082B7  |>|je      short 004082C3
  004082B9  |>|mov     [ecx+eax], dl
  004082BC  |>|inc     esi
  004082BD  |>|inc     eax
  004082BE  |>|cmp     esi, 18                        ;  24:在伽罗瓦域p内运算,因为p也只有22个字符长,所以,sn_1/sn_2长度必小于24
  004082C1  |>\jl      short 004082B2
  004082C3  |>cmp     esi, 18
  004082C6  |>jnz     short 004082D3
  004082C8  |>mov     edi, [esp+10]
  004082CC  |>xor     esi, esi
  004082CE  |>jmp     004083AC
  004082D3  |>push    edi                             ;  sn_1
  004082D4  |>push    ebp
  004082D5  |>call    <cinstr>
  004082DA  |>push    8                               ;  8个DWORD
  004082DC  |>push    edi                             ;  sn_1
  004082DD  |>call    00403F71
  004082E2  |>add     esp, 10
  004082E5  |>inc     esi
  004082E6  |>xor     eax, eax
  004082E8  |>/mov     ecx, [esp+2C]
  004082EC  |>|mov     cl, [esi+ecx]
  004082EF  |>|cmp     cl, 2D
  004082F2  |>|je      short 004082FE
  004082F4  |>|mov     [eax+edi], cl
  004082F7  |>|inc     eax
  004082F8  |>|inc     esi
  004082F9  |>|cmp     eax, 18
  004082FC  |>\jl      short 004082E8
  004082FE  |>cmp     eax, 18
  00408301  |>jnz     short 0040830E
  00408303  |>mov     edi, [esp+10]
  00408307  |>xor     esi, esi
  00408309  |>jmp     004083AC
  0040830E  |>mov     edx, [esp+1C]
  00408312  |>push    edi                             ;  sn_2
  00408313  |>push    edx
  00408314  |>inc     esi
  00408315  |>call    <cinstr>
  0040831A  |>push    8
  0040831C  |>push    edi                             ;  sn_2
  0040831D  |>call    00403F71
  00408322  |>mov     edi, [esp+20]
  00408326  |>push    004033D4                        ;  ASCII "2B5CF397E91B4376A51DA3"
  0040832B  |>push    edi                             ;  p
  0040832C  |>call    <cinstr>
  00408331  |>push    004033D0                        ;  3
  00408336  |>push    ebx
  00408337  |>call    <cinstr>
  0040833C  |>mov     eax, [esp+38]
  00408340  |>push    004033B8                        ;  ASCII "C1CE280BD21C8D573609D"
  00408345  |>push    eax                             ;  y
  00408346  |>call    <cinstr>
  0040834B  |>mov     ecx, [esp+3C]
  0040834F  |>mov     edx, [esp+5C]
  00408353  |>push    ecx
  00408354  |>push    edx                             ;  zero
  00408355  |>push    18
  00408357  |>call    <bytes_to_big>
  0040835C  |>push    ebp                             ;  sn_1
  0040835D  |>push    ebx                             ;  3
  0040835E  |>call    <compare>
  00408363  |>add     esp, 3C
  00408366  |>test    eax, eax
  00408368  |>jnz     short 0040836C
  0040836A  |>xor     esi, esi
  0040836C  |>mov     eax, [esp+24]
  00408370  |>mov     ecx, [esp+14]
  00408374  |>push    eax
  00408375  |>push    edi                             ;  p
  00408376  |>push    ecx                             ;  It's always zero.
  00408377  |>push    ebx                             ;  3
  00408378  |>call    <powmod>                        ;  c=1
  0040837D  |>mov     edx, [esp+30]
  00408381  |>mov     eax, [esp+2C]
  00408385  |>mov     ecx, [esp+28]
  00408389  |>push    edx                             ;  d
  0040838A  |>push    edi                             ;  p
  0040838B  |>push    eax                             ;  sn_2
  0040838C  |>push    ebp                             ;  sn_1
  0040838D  |>push    ebp                             ;  sn_1
  0040838E  |>push    ecx                             ;  y
  0040838F  |>call    <powmod2>                       ;  d = (y^sn_1) * (sn_1^sn_2) (mod p)
  00408394  |>mov     edx, [esp+4C]
  00408398  |>mov     eax, [esp+48]
  0040839C  |>push    edx                             ;  c=1
  0040839D  |>push    eax                             ;  d
  0040839E  |>call    <compare>
  004083A3  |>add     esp, 30
  004083A6  |>test    eax, eax
  004083A8  |>je      short 004083AC
  
  整理一下上面的思路,则须有下式成立:
      1 = (y^sn_1) * (sn_1^sn_2) (mod p)                (*)
  是不是有点像ElGamal数字签名算法的左端?呵呵,我费了九牛二虎之力也没有凑出来;怎么办?把等式转换成:
      sn_1^sn_2 = (y^sn_1)^(-1) (mod p)
  然后给定一个sn_1,来计算离散对数求得sn_2,因为p并不大,所以应该不难找出几组来,但我用指数法也没有找出来一组;到底该怎么办?
  
  换个思路,既然等式(*)左边等于1,那么能不能用费尔玛小定理尝试一下?若直接令sn_1 = y,那么,等式变成:
      1 = y^(y + sn_2) (mod p)
  即,只需有y + sn_2 = Φ(p) = p - 1 =〉sn_2 = p - 1 - y。
  这是一组固定的sn_1和sn_2,可轻松计算得到:C1CE280BD21C8D573609D-1F4011172BF97AA131BD05-sn_3
  输入,通过上面的compare验证。
  
  再多想一下,若令sn_1 = y^k (k = 2,3...),只要满足等式y^k + k*sn_2 = Φ(p)即可,可是单y^2就已经比Φ(p)大很多了。根据模运算的性质,我们只要
      y^k + k*sn_2 = m*Φ(p)
  也可以。此时,求出sn_2来应不成问题。但计算量估计会很大。
  
  好了,这一步就讨论这么多,看下面的sn_3:
  
  00405C19   >pop     edi
  00405C1A   >xor     eax, eax
  00405C1C   >pop     esi
  00405C1D   >retn    10
  00405C20   >mov     [40EE48], esi
  00405C26   >pop     edi
  00405C27   >mov     [40EE44], edx
  00405C2D   >xor     eax, eax
  00405C2F   >pop     esi
  00405C30   >retn    10
  00405C33   >mov     ecx, [4030A0]                   ;  ppg_crac.0040EB70
  00405C39   >mov     edx, [40309C]                   ;  <ppg_crac.String>
  00405C3F   >push    0040EB10
  00405C44   >push    ecx
  00405C45   >mov     ecx, [403098]                   ;  ppg_crac.0040EBA0
  00405C4B   >push    edx
  00405C4C   >add     ecx, eax
  00405C4E   >push    ecx                             ;  sn_3
  00405C4F   >call    00408410
  00405C54   >add     esp, 10
  00405C57   >test    eax, eax
  00405C59   >push    40                              ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
  00405C5B   >push    <Caption>                       ; |Title = "The PowerPuff Girls"
  00405C60   >je      short 00405C75                  ; |
  00405C62   >push    <aWhatYouLikeFor>               ; |Text = "What you like for christmas?"
  00405C67   >push    edi                             ; |hOwner
  00405C68   >call    [<&user32.MessageBoxA>]         ; \MessageBoxA
  00405C6E   >pop     edi                             ;  Default case of switch 00405B41
  00405C6F   >xor     eax, eax
  00405C71   >pop     esi
  00405C72   >retn    10
  00405C75   >push    <aCongratulation>               ; |Text = "Congratulations, Good work!"
  00405C7A   >push    edi                             ; |hOwner
  00405C7B   >call    [<&user32.MessageBoxA>]         ; \MessageBoxA
  
  跟进405C4F瞧瞧去:
  00408410  />sub     esp, 14
  00408413  |>push    ebx
  00408414  |>push    ebp
  00408415  |>push    esi
  00408416  |>push    edi
  00408417  |>push    0
  00408419  |>push    0C8
  0040841E  |>call    <mirsys>
  00408423  |>push    0
  00408425  |>mov     dword ptr [eax+238], 10
  0040842F  |>call    <mirvar>
  00408434  |>push    0
  00408436  |>mov     ebx, eax
  00408438  |>call    <mirvar>
  0040843D  |>push    0
  0040843F  |>mov     [esp+30], eax
  00408443  |>call    <mirvar>
  00408448  |>push    0
  0040844A  |>mov     [esp+28], eax
  0040844E  |>call    <mirvar>
  00408453  |>push    0
  00408455  |>mov     [esp+30], eax
  00408459  |>call    <mirvar>
  0040845E  |>push    0
  00408460  |>mov     ebp, eax
  00408462  |>call    <mirvar>
  00408467  |>push    0
  00408469  |>mov     [esp+44], eax
  0040846D  |>call    <mirvar>
  00408472  |>mov     [esp+3C], eax
  00408476  |>mov     eax, [esp+4C]
  0040847A  |>push    eax
  0040847B  |>push    ebp
  0040847C  |>call    <cinstr>
  00408481  |>push    0040EE60
  00408486  |>call    <SHA1_Init>
  0040848B  |>mov     edx, [esp+60]
  0040848F  |>or      ecx, FFFFFFFF
  00408492  |>mov     edi, edx
  00408494  |>xor     eax, eax
  00408496  |>repne   scas byte ptr es:[edi]
  00408498  |>not     ecx
  0040849A  |>dec     ecx
  0040849B  |>push    ecx
  0040849C  |>push    edx
  0040849D  |>push    0040EE60
  004084A2  |>call    <SHA1_Update>
  004084A7  |>mov     esi, [esp+70]
  004084AB  |>push    0040EE60
  004084B0  |>push    esi
  004084B1  |>call    <SHA1_Final>
  004084B6  |>add     esp, 44
  004084B9  |>push    ebx
  004084BA  |>push    esi                             ;  SHA1(0)
  004084BB  |>push    14                              ;  20
  004084BD  |>call    <bytes_to_big>
  004084C2  |>push    8
  004084C4  |>push    esi
  004084C5  |>call    00403F71
  004084CA  |>add     esp, 14
  004084CD  |>mov     edi, 2
  004084D2  |>/mov     ecx, [esp+10]
  004084D6  |>|push    ecx
  004084D7  |>|push    ebx                            ;  SHA1(0)
  004084D8  |>|call    <nxprime>
  004084DD  |>|add     esp, 8
  004084E0  |>|dec     edi
  004084E1  |>\jnz     short 004084D2
  004084E3  |>push    0040EE60
  004084E8  |>call    <SHA1_Init>
  004084ED  |>mov     edx, [esp+30]
  004084F1  |>or      ecx, FFFFFFFF
  004084F4  |>mov     edi, edx
  004084F6  |>xor     eax, eax
  004084F8  |>repne   scas byte ptr es:[edi]
  004084FA  |>not     ecx
  004084FC  |>dec     ecx
  004084FD  |>push    ecx
  004084FE  |>push    edx                             ;  0
  004084FF  |>push    0040EE60
  00408504  |>call    <SHA1_Update>
  00408509  |>push    0040EE60
  0040850E  |>push    esi
  0040850F  |>call    <SHA1_Final>                    ;  SHA1(0)
  00408514  |>mov     edi, [esp+34]
  00408518  |>push    edi
  00408519  |>push    esi
  0040851A  |>push    14
  0040851C  |>call    <bytes_to_big>
  00408521  |>push    8
  00408523  |>push    esi
  00408524  |>call    00403F71
  00408529  |>mov     esi, 3
  0040852E  |>add     esp, 2C
  00408531  |>mov     [esp+28], esi
  00408535  |>/mov     edx, [esp+14]
  00408539  |>|push    edx                            ;  n
  0040853A  |>|push    edi                            ;  SHA1(0)
  0040853B  |>|call    <nxprime>
  00408540  |>|add     esp, 8
  00408543  |>|dec     esi
  00408544  |>\jnz     short 00408535
  00408546  |>mov     esi, [esp+20]
  0040854A  |>mov     eax, [esp+10]
  0040854E  |>push    esi
  0040854F  |>push    eax                             ;  n
  00408550  |>push    1                               ;  1
  00408552  |>push    ebp                             ;  sn_3
  00408553  |>call    <power>                         ;  sn_3
  00408558  |>mov     ecx, [esp+28]
  0040855C  |>mov     edx, [esp+24]
  00408560  |>push    ecx
  00408561  |>push    edx                             ;  n
  00408562  |>push    1                               ;  1
  00408564  |>push    ebp                             ;  sn_3
  00408565  |>call    <power>                         ;  sn_3
  0040856A  |>push    ebx                             ;  SHA(0)
  0040856B  |>push    esi                             ;  sn_3
  0040856C  |>call    <compare>
  00408571  |>add     esp, 28
  00408574  |>test    eax, eax
  00408576  |>jnz     short 0040858E
  00408578  |>mov     eax, [esp+18]
  0040857C  |>push    edi
  0040857D  |>push    eax
  0040857E  |>call    <compare>
  00408583  |>add     esp, 8
  00408586  |>test    eax, eax
  00408588  |>jnz     short 0040858E
  
  40856C处可以看到sn_3和SHA1(NULL)比较,而SHA1(NULL)为一常数,所以sn_3 = SHA1(NULL)。因此,目前唯一可用的注册码就是:
  
      C1CE280BD21C8D573609D-1F4011172BF97AA131BD05-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
  
  大家是不是觉得这个CrackMe怪怪地?反正我就是这样的感觉。我重新跟踪了一下未脱壳的源程序,发现与脱掉的验证算法没有任何不同之处。同时,用上面的注册码验证通过。
  也许,程序作者就是想和大家开个圣诞节的玩笑把。反正No Tiger,No RC2。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年01月19日 5:59:00


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 1969
活跃值: (46)
能力值: (RANK:550 )
在线值:
发帖
回帖
粉丝
2
厉害,看着头大,学习。
2007-1-19 19:06
0
雪    币: 214
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
数学很好呀,收藏学习,
2007-1-19 20:16
0
游客
登录 | 注册 方可回帖
返回
//