首页
社区
课程
招聘
[原创]bundy's keygenme #1分析
发表于: 2007-12-17 11:45 6490

[原创]bundy's keygenme #1分析

2007-12-17 11:45
6490

【文章标题】: bundy's keygenme #1分析
【文章作者】: HappyTown
【软件名称】: bundy's keygenme #1
【下载地址】: 附件内
【加壳方式】: 无
【保护方式】: math
【编写语言】: VC6
【使用工具】: OD
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  希望你先自己动手分析一下,否则,可能阅之亦是无味。
  
  00401260  /$>push    esi
  00401261  |.>mov     esi, dword ptr [esp+8]
  00401265  |.>push    10                          ;  0x10
  00401267  |.>push    100                         ;  0x100
  0040126C  |.>mov     dword ptr [40D84C], esi
  00401272  |.>call    <mirsys>
  00401277  |.>mov     dword ptr [40D580], eax
  0040127C  |.>push    0
  0040127E  |.>mov     dword ptr [eax+238], 10     ;  mip->IOBASE = 16
  00401288  |.>call    <mirvar>
  0040128D  |.>push    0
  ...
  004012C9  |.>push    0
  004012CB  |.>mov     dword ptr [40D594], eax
  004012D0  |.>call    <mirvar>
  004012D5  |.>push    0
  004012D7  |.>mov     dword ptr [40D578], eax
  004012DC  |.>call    <mirvar>
  004012E1  |.>push    1
  004012E3  |.>mov     dword ptr [40D57C], eax
  004012E8  |.>call    <mirvar>                    ;  a
  004012ED  |.>mov     dword ptr [40D584], eax
  004012F2  |.>mov     eax, dword ptr [40D574]
  004012F7  |.>push    0040C144                    ;  ASCII "8FD312A230FE4096F59566AAC6D6229FBBCAA08B23835F78A77B7DF4C9FA723A15E5FB6D5B555670313B2AE346402217FEF2C60896460804999516B1502AEF51"
  004012FC  |.>push    eax                         ;  b
  004012FD  |.>call    <cinstr>
  00401302  |.>mov     ecx, dword ptr [40D58C]
  00401308  |.>push    0040C138                    ;  ASCII "9F0A32E3"
  0040130D  |.>push    ecx                         ;  c
  0040130E  |.>call    <cinstr>
  00401313  |.>mov     edx, dword ptr [40D590]
  00401319  |.>push    0040C12C                    ;  ASCII "9F2F8283"
  0040131E  |.>push    edx                         ;  d
  0040131F  |.>call    <cinstr>
  ...
  
  我们输入:
  name: happy
  serial: 87654321-22222222
  
  0040110E   .>push    ecx
  0040110F   .>push    0040D598                    ;  ASCII "happy"
  00401114   .>push    ebp
  00401115   .>call    <bytes_to_big>
  0040111A   .>mov     edx, dword ptr [40D578]
  00401120   .>push    0040D5D8                    ;  ASCII "61BA19A2"
  00401125   .>push    edx                         ;  sn_1
  00401126   .>call    <cinstr>
  0040112B   .>mov     ecx, dword ptr [40D594]
  00401131   .>lea     eax, dword ptr [esi+40D5D9]
  00401137   .>push    eax                         ;  "22222222"
  00401138   .>push    ecx                         ;  sn_2
  00401139   .>call    <cinstr>
  0040113E   .>mov     eax, dword ptr [40D578]
  00401143   .>mov     edx, dword ptr [40D58C]
  00401149   .>push    eax                         ;  sn_1
  0040114A   .>push    eax                         ;  sn_1
  0040114B   .>push    edx                         ;  c:9F0A32E3
  0040114C   .>call    <multiply>                  ;  sn_1 = c * sn_1 = 541D498FF430F843
  00401151   .>mov     eax, dword ptr [40D588]
  00401156   .>mov     ecx, dword ptr [40D574]
  0040115C   .>mov     edx, dword ptr [40D578]
  00401162   .>push    eax                         ;  e
  00401163   .>mov     eax, dword ptr [40D570]
  00401168   .>push    ecx                         ;  b: 8FD312A2...502AEF51
  00401169   .>push    edx                         ;  sn_1: 541D498FF430F843
  0040116A   .>push    eax                         ;  name: 68 61 70 70 79
  0040116B   .>call    <powmod>                    ;  e = (name ^ sn_1) mod b = 60B4B812...EFCD381A
  00401170   .>mov     ecx, dword ptr [40D57C]
  00401176   .>mov     edx, dword ptr [40D590]
  0040117C   .>mov     eax, dword ptr [40D578]
  00401181   .>push    ecx                         ;  f
  00401182   .>push    edx                         ;  d: 9F2F8283
  00401183   .>push    eax                         ;  sn_1: 541D498FF430F843
  00401184   .>call    <divide>                    ;  f = sn_1 mod d = 5F2BF255
  00401189   .>mov     ecx, dword ptr [40D584]
  0040118F   .>mov     edx, dword ptr [40D578]
  00401195   .>add     esp, 44
  00401198   .>push    ecx                         ;  a: 1
  00401199   .>push    edx                         ;  f: 5F 2B F2 55
  0040119A   .>call    <compare>
  0040119F   .>add     esp, 8
  004011A2   .>test    eax, eax
  004011A4   .>jnz     004010A8
  
  我们看一下上段代码的意思:
      1> sn_1 = c * sn_1
      2> e = (name ^ sn_1) mod b
      3> f = sn_1 mod d
      4> f ?= 1
  
  整理如下:
      A) e = (name ^ (c * sn_1)) mod b
      B) 1 ?= (c*sn_1) mod d
  
  如果 f != 1 ,那么,跳向错误。显然,我们先得通过B)这一步判断才能继续前行。
  
  1 ?= (c*sn_1) mod d 不就是告诉我们 sn_1 是 c 模 d 的乘法逆元嘛,呵呵。
  计算得: sn_1 = c^(-1) mod d = 61BA19A2。
  
  我们重新输入:
  name: happy
  serial: 61BA19A2-22222222
  
  0040110E   .>push    ecx
  0040110F   .>push    0040D598                    ;  ASCII "happy"
  00401114   .>push    ebp
  00401115   .>call    <bytes_to_big>
  0040111A   .>mov     edx, dword ptr [40D578]
  00401120   .>push    0040D5D8                    ;  ASCII "61BA19A2"
  00401125   .>push    edx                         ;  sn_1
  00401126   .>call    <cinstr>
  0040112B   .>mov     ecx, dword ptr [40D594]
  00401131   .>lea     eax, dword ptr [esi+40D5D9]
  00401137   .>push    eax                         ;  "22222222"
  00401138   .>push    ecx                         ;  sn_2
  00401139   .>call    <cinstr>
  0040113E   .>mov     eax, dword ptr [40D578]
  00401143   .>mov     edx, dword ptr [40D58C]
  00401149   .>push    eax                         ;  sn_1
  0040114A   .>push    eax                         ;  sn_1
  0040114B   .>push    edx                         ;  c:9F0A32E3
  0040114C   .>call    <multiply>                  ;  sn_1 = c * sn_1 = 3CB67A9D9F5A5EA6
  00401151   .>mov     eax, dword ptr [40D588]
  00401156   .>mov     ecx, dword ptr [40D574]
  0040115C   .>mov     edx, dword ptr [40D578]
  00401162   .>push    eax                         ;  e
  00401163   .>mov     eax, dword ptr [40D570]
  00401168   .>push    ecx                         ;  b: 8FD312A2...502AEF51
  00401169   .>push    edx                         ;  sn_1: 3CB67A9D9F5A5EA6
  0040116A   .>push    eax                         ;  name: 68 61 70 70 79
  0040116B   .>call    <powmod>                    ;  e = (name ^ sn_1) mod b = 3088B09D...7E9E5949
  00401170   .>mov     ecx, dword ptr [40D57C]
  00401176   .>mov     edx, dword ptr [40D590]
  0040117C   .>mov     eax, dword ptr [40D578]
  00401181   .>push    ecx                         ;  g
  00401182   .>push    edx                         ;  d: 9F2F8283
  00401183   .>push    eax                         ;  sn_1: 3CB67A9D9F5A5EA6
  00401184   .>call    <divide>                    ;  f = sn_1 mod d = 1; g = sn_1 / d = 61A331B7
  00401189   .>mov     ecx, dword ptr [40D584]
  0040118F   .>mov     edx, dword ptr [40D578]
  00401195   .>add     esp, 44
  00401198   .>push    ecx                         ;  a: 1
  00401199   .>push    edx                         ;  f: 1
  0040119A   .>call    <compare>
  0040119F   .>add     esp, 8
  004011A2   .>test    eax, eax
  004011A4   .>jnz     004010A8
  004011AA   .>mov     eax, dword ptr [40D578]
  004011AF   .>mov     ecx, dword ptr [40D574]
  004011B5   .>mov     edx, dword ptr [40D57C]
  004011BB   .>push    eax                         ;  h
  004011BC   .>push    ecx                         ;  b: 8FD312A2...502AEF51
  004011BD   .>mov     ecx, dword ptr [40D594]
  004011C3   .>push    edx                         ;  g: 61A331B7
  004011C4   .>mov     edx, dword ptr [40D588]
  004011CA   .>push    ecx                         ;  sn_2: 22222222
  004011CB   .>push    eax                         ;  1
  004011CC   .>push    edx                         ;  e = 3088B09D...7E9E5949
  004011CD   .>call    <powmod2>                   ;  h = (e ^ 1) * (sn_2 ^ g) mod b = 83633937...59B6B217
  004011D2   .>mov     eax, dword ptr [40D570]
  004011D7   .>mov     ecx, dword ptr [40D578]
  004011DD   .>push    eax                         ;  name
  004011DE   .>push    ecx                         ;  h
  004011DF   .>call    <compare>                   ;  h ?= name
  
  整理一下,我们需要:
      ((name ^ 3CB67A9D9F5A5EA6) * (sn_2 ^ g)) mod b = name
  那么,得:
      (sn_2 ^ g) mod b = (name * ((name ^ 3CB67A9D9F5A5EA6)^(-1))) mod b
  显然这是一个RSA的问题,分解b,求得g对应的私钥即可轻松算出sn_2。
  Wow,b是512位。显然我们在有生之年分解不了它。
  但作者说: There is a solution! 看来我们得另找其它方法了。
  
  从新整理一下验证的思路:
      1> (c * sn_1) mod d = 1
      2> ((name ^ (c * sn_1)) * (sn_2 ^ ((c * sn_1)/d))) mod b = name
  在2>中,(c * sn_1) 和 (c * sn_1)/d之间是什么关系?
  聪明的你可能已经猜出来了。我们换个方式来表达这种关系:
      c * sn_1 = k*d + 1
  也就是说 (c * sn_1)/d = k,那么2>转化为:
      ((name ^ (k*d + 1)) * (sn_2 ^ k)) mod b = name
  我们令 sn_2 = name ^ x,那么则应该有:
      ((name ^ (k*d + 1) * (name ^(x*k)) mod b = name
  即:
      (name ^ (k*d + x*k + 1)) mod b = name
  也就是说,需:
      (name ^ (k*d + x*k)) mod b = 1
  令 x = -d 则可满足上式的要求。此时:
      sn_2 = name ^ (-d) mod b = (name ^ d) ^ (-1) mod b
  也就是说,sn_2 为 (name ^ d) 模 b 的乘法逆元。
  
  好了,问题已经得到了解决。给出一组可用的注册码:
  name: happy
  serial: 61BA19A2-1128D238DD8B63219451910D20BED9324CD9541859B1755D441AAB7E37F7C89FAB57D96BF8699580748555C585058FD32233579EDB845521776D0B900A8A26F0
  
  注册机及其源代码在附件中一并给出。
  事实上,前面那个RSA的思路自身就很有问题,3CB67A9D9F5A5EA6 虽然在本程序中是个固定的数,但因为它是偶数,所以,它既不可能是私钥也不可能是公钥,这是RSA算法自身所要求的,因此,就算b是128位,那种做法也是不能求得sn_2的。
  
--------------------------------------------------------------------------------
【经验总结】
  在06年的时候就为这个程序伤过不少脑筋,今日终得其解。
  呜呼,美哉,美哉。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年12月17日 4:10:52


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
要顶,要顶!
顶起来慢慢学!
2007-12-17 13:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
难得见的着ht大侠的文章啊
收藏之。。。。
2007-12-17 15:24
0
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
4
顶,收藏先!
2007-12-17 20:47
0
雪    币: 246
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
5
RSA的算法,感谢楼主,先收藏了
2007-12-21 15:56
0
游客
登录 | 注册 方可回帖
返回
//