首页
社区
课程
招聘
[原创]newsearch之 CRACKME2的分析[看雪学院2006金秋读书季]
2006-11-4 13:31 9173

[原创]newsearch之 CRACKME2的分析[看雪学院2006金秋读书季]

2006-11-4 13:31
9173
【文章标题】: newsearch忽悠 CRACKME2的分析
【作    者】: laoqian[FCG]
【邮    箱】: -
【主    页】: www.fcgchina.com
【QQ    号】: -
【软件名称】: newsearch忽悠 CRACKME2
【大    小】: 44k
【下载地址】: http://bbs.pediy.com/attachment.php?s=&attachmentid=3286
【加壳方式】: 无
【保护方式】: 算法
【编写语言】: VC,MFC42
【操作平台】: winxp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
第一次在这个板块发文,呵呵!
【详细过程】
    最近newsearch一直在研究ecc,研究之余不忘了忽悠,忽悠了几个crackme,说是为了学习ecc而作,我们就来看看,首先说明我不懂ecc,而这个crackme只是有些类似想法而已。
  
  闲话少说,od打开crackme,我们搜索字符参考,只有几个看到"%C%c %c%c%c! ",我们过去,然后在望上面看到,下断点。
  
  疑问,为何在这里下断点,各位看官说为何在这里下呢?――因为我跟踪过他的crackme1,其中有出错提示,所以直接找到这里!
  这次就偷懒了,不过如果第一次跟踪,怎么设断点,不是本文的重点,就略过了,见谅!
  下面是分析:
  
  004014A0   push -1
  004014A2   push CrackMe4.00401B80          ;  SE handler installation
  004014A7   mov eax,dword ptr fs:[0]
  004014AD   push eax
  004014AE   mov dword ptr fs:[0],esp
  004014B5   sub esp,6C
  004014B8   push ebx
  004014B9   push ebp
  004014BA   push esi
  004014BB   push edi
  004014BC   mov ebp,ecx
  004014BE   push 1
  004014C0   call <jmp.&MFC42.#6334>
  004014C5   lea ecx,dword ptr ss:[esp+10]
  004014C9   call <jmp.&MFC42.#540>
  004014CE   mov esi,dword ptr ss:[ebp+60]   ;  Esi = 注册码
  004014D1   mov edi,dword ptr ss:[ebp+68]   ;  Edi = 序列号
  004014D4   xor ebx,ebx                     ;  ebx 清零
  004014D6   lea ecx,dword ptr ss:[esp+1C]
  004014DA   push ebx
  004014DB   mov dword ptr ss:[esp+88],ebx   ;  ebx 零
  004014E2   call CrackMe4.00401630
  004014E7   cmp esi,edi                     ;  判断  注册码 序列号 是否相等
  004014E9   mov byte ptr ss:[esp+84],1      ;  置 1
  004014F1   je CrackMe4.004015B2            ;  注册码 序列号相等就玩完!
  004014F7   mov eax,dword ptr ss:[ebp+64]   ;  eax=用户名
  004014FA   cmp eax,edi                     ;  判断  用户名 序列号 是否相等
  004014FC   mov dword ptr ss:[esp+18],eax   ;  eax=用户名
  00401500   je CrackMe4.004015B2            ;  相等就玩完!
  00401506   cmp esi,eax                     ;  判断  用户名 注册码 是否相等
  00401508   je CrackMe4.004015B2            ;  相等就玩完!
  0040150E   cmp esi,64                      ;  判断  注册码 是否小于100
  00401511   jl CrackMe4.004015B2            ;  小于就玩完!
  00401517   cmp edi,64
  0040151A   jl CrackMe4.004015B2
  00401520   cmp eax,64
  00401523   jl CrackMe4.004015B2            ;  同理
  00401529   lea eax,dword ptr ds:[esi+esi*4>;  eax=esi*5,[esi=注册码],传给eax
  0040152C   lea eax,dword ptr ds:[eax+eax*4>;  eax=eax*5,传给eax,注意这里和上面!!!重点
  0040152F   sub edi,eax                     ;  edi=edi-eax=序列号-eax
  00401531   lea eax,dword ptr ds:[edi+edi*4>;  eax=edi*5,传给eax,注意这里和上面!
  00401534   shl eax,1                       ;  逻辑左移1位,eax=eax*2
  00401536   cmp eax,10                      ;  比较eax不能小于10H
  00401539   mov dword ptr ss:[esp+14],eax   ;  eax复制
  0040153D   jl short CrackMe4.004015B2      ;  小于就玩完!
  0040153F   fld qword ptr ds:[402510]       ;  装入ST0 实数2,用上浮点了,嘿嘿,这里就是指数算法的关键
  00401545   fild dword ptr ss:[esp+14]      ;  eax复制的值,装入ST0 整数
  00401549   call <jmp.&MSVCRT._CIpow>       ;  pow(A,B),A的B次方函数
  0040154E   fisub dword ptr ss:[esp+18]     ;  浮点减法,上面的结果减去用户名,存入ST0,看FPU寄存器
  00401552   call <jmp.&MSVCRT._ftol>        ;  取整到eax
  00401557   mov ecx,eax                     ;  ecx=eax
  00401559   cdq                             ;  清零edx,准备除法
  0040155A   idiv esi                        ;  整数除法,eax/esi,商存eax,余数存edx
  0040155C   sub ecx,esi                     ;  Esi=注册码,验证正确应该相等,减法结果ecx=0,重点!有些迷惑后面的小手段!
  0040155E   cmp eax,1                       ;  正确验证,eax应等于1
  00401561   jnz short CrackMe4.0040159F     ;  不等跳就玩完!
  00401563   lea edx,dword ptr ds:[ecx+64]   ;  用上了前面的ecx的值!ecx=0,则edx=64h,d
  00401566   lea eax,dword ptr ds:[ecx+6F]   ;  ecx=0,则eax=6Fh,o
  00401569   push edx                        ;  入栈
  0040156A   push eax                        ;  入栈
  0040156B   lea edx,dword ptr ds:[ecx+47]   ;  ecx=0,则edx=47h,G
  0040156E   lea eax,dword ptr ds:[ecx+79]   ;  ecx=0,则eax=79h, y
  00401571   push edx                        ;  入栈
  00401572   add ecx,4D                      ;  ecx=0,则ecx=4Dh,M
  00401575   push eax                        ;  入栈
  00401576   push ecx                        ;  入栈
  00401577   lea ecx,dword ptr ss:[esp+24]   ;  上面根据入栈顺序,我们出栈顺序得到ACSII码,看到“MyGod”呵呵
  0040157B   push CrackMe4.00403020          ;  ASCII "%C%c %c%c%c! "
  00401580   push ecx                        ;  上面就是我们下断点的依据!
  00401581   call <jmp.&MFC42.#2818>         ;  这里就是动态生成成功提示的地方!
  00401586   mov edx,dword ptr ss:[esp+2C]
  0040158A   add esp,1C
  0040158D   push ebx
  0040158E   push ebx
  0040158F   push edx                        ;  看到edx,就是“My God!”
  00401590   call <jmp.&MFC42.#1200>         ;  成功窗口画面
  00401595   push ebx
  00401596   mov ecx,ebp
  00401598   call <jmp.&MFC42.#6334>
  0040159D   jmp short CrackMe4.004015BB
  0040159F   lea ecx,dword ptr ss:[esp+1C]
  004015A3   call <jmp.&MFC42.#2514>         ;  你被忽悠了!!――一张脸!
  004015A8   push ebx
  004015A9   mov ecx,ebp
  004015AB   call <jmp.&MFC42.#6334>
  004015B0   jmp short CrackMe4.004015BB
  004015B2   lea ecx,dword ptr ss:[esp+1C]
  004015B6   call <jmp.&MFC42.#2514>
  004015BB   lea ecx,dword ptr ss:[esp+1C]
  

  
  可以逆推做注册机了,呵呵我们假设:
  
  Name,用户名
  x,序列号
  y,注册码
  
  我们看
  0040153F   fld qword ptr ds:[402510]       ;  装入ST0 实数2,用上浮点了,嘿嘿,这里就是指数算法的关键
  00401545   fild dword ptr ss:[esp+14]      ;  eax复制的值,装入ST0 整数
  00401549   call <jmp.&MSVCRT._CIpow>       ;  pow(A,B),是的B次方函数,此处FPU看到A=2
  
  此处:2^B是一个关键,那么B是对少,往上看,
  00401529 -00401536中间计算了,我们总结得到B=10(x-25y)
  接下来看到对应关系:
  {2^[10(x-25y)]-Name}/y=1
  
  算法看清了,那么怎么逆向他呢,这个需要数学基础,我没有,只好自己瞎搞了!
  
  我设定:
  Name,用户名
  x,序列号
  y,注册码
  A,我们假设是整数变量,此处为=2,3,4....整数!
  
  把{2^[10(x-25y)]-Name}/y=1简单转化为:
  2^[10(x-25y)]=Name+y
  我设A=X-25Y,带入上式得
  
  2^[A*10]=Name+y
  再来:
  Y=2^[A*10]-Name
  X=25Y+A
  这就是简化后的算法了,A假设是整数变量,此处为=2,3,4....整数!
  
  程序中增加了一些检测用户名、序列号、注册码的判断,无非是避免一些极端情况的出现!
  
  X,Y,Name都是整数必须大于100,而确定A值,而且仅仅是要使Y大于100!可以看出一个用户名,如果不限定A可有无数解!
  本来到此为止了,可是在检验注册机时候,发现,用户名12345678的序列号、注册码的不能注册,奇怪!
  经过再次跟踪发现:
  因为eax等只能存储8位(16进制),lea命令就是传递地址(而不是地址存储数据,相当于复制),如果超出8位,高位就另存(或者说丢弃?),如当[eax*5]大于2^32时候,就去掉高位,只留下后面8位(16进制)参与计算,就是只保留余数!然后再*5,同理舍去高位。就是那个25Y,要在编程时候处理一下,5Y处理高位,再5y处理高位!!!后面也是同理,这个用汇编容易实现,高级语言就麻烦一点。

  这样A=3,4,5...也即能计算出序列号,4.5.6....以此类推!
  
X=25Y+A只是一种特殊情况,因此编写注册机时候,要根据上面作修改

X={5*{5*Y}}+A,其中{5*y}代表以上分析的结果,还是用汇编写注册机算了!

写注册机时候,应该注意到上面eax等寄存器的问题!
  
--------------------------------------------------------------------------------
【总结】
  这个crackme有点意思,据作者说,对于理解ecc有帮助,嘿嘿,等有时间去看看ecc算法!
  
  如果加上hash函数,再把算法复杂一些,这个注册机制就很难逆向!
  
  根据用户名,算法,确定A值,就可以唯一注册码了!

  还有,不是简单把下面ecx=0,就显示成功,而是经过转换,爆破就麻烦一些。
  0040155C   sub ecx,esi                     ;  Esi=注册码,验证正确应该相等,减法结果ecx=0,重点!有些迷惑
  后面的小手段!
  0040155E   cmp eax,1                       ;  正确验证,eax应等于1
  00401561   jnz short CrackMe4.0040159F     ;  不等跳就玩完!
  00401563   lea edx,dword ptr ds:[ecx+64]   ;  用上了前面的ecx的值!ecx=0,则edx=64h,d
  
  爆破点,就是让上面ecx=0 ,00401561这里不跳即可!
  
--------------------------------------------------------------------------------
【版权声明】: 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞7
打赏
分享
最新回复 (7)
雪    币: 332
活跃值: (479)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
laoqian 8 2006-11-4 14:28
2
0
12345 ,25905777,1036231

12345 ,1073433202,1073729479
12345678,765099877,1061396146

2个注册码!方便大家跟踪看看
雪    币: 110
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小剑 2006-11-4 14:50
3
0
完全不懂,只有顶一下的份
雪    币: 323
活跃值: (579)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
springkang[DFCG 11 2006-11-4 16:02
4
0
走召 弓虽 白勺 言兑

十  扌土 一  一
又   寸    卜
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
binbinbin 28 2006-11-4 19:23
5
0
哈哈。说真的。我刚想发的。楼主高手。

学习学习!!
雪    币: 260
活跃值: (81)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
萝卜 1 2006-11-5 22:26
6
0
虽然没有错误提示但是有成功提示
用公式表达:
x1=2^(10*(x2-25*x3))-x3
也是逆推,可以用计算器计算
雪    币: 32406
活跃值: (18805)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2006-11-6 09:55
7
0
欢迎参加[看雪学院2006金秋读书季] 活动,还有10天就结束了。;)
雪    币: 257
活跃值: (369)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
newsearch 9 2006-11-6 10:15
8
0
哈哈,我放的一个CRACKME,居然让laoqian骗了一个精华,看雪该给我记一半的精华
这个CRACKME只是采用了ECC的思路而已或者说模型,并不是真正的ECC。
理论上,ECC已经是可以破译的了,只是需要另外构建一个关系函数,这样就可以代替私钥了,凡是穷举好像都可以这样做。发现需要穷举的算法,其实就是有无穷多组密码适合的算法,只要构建合适的关系代入这个算法中,就可以破解了。
游客
登录 | 注册 方可回帖
返回