-
-
[旧帖]
[原创]CM破解手记与疑问[邀请码已发]
0.00雪花
-
发表于:
2009-12-21 19:58
1844
-
[旧帖] [原创]CM破解手记与疑问[邀请码已发]
0.00雪花
找了个练习的CM小程序
自己破解着玩
应该算是最简单的那种了
爆破实在是没什么意思,
但在我阅读这个CM程序计算序列号的代码时
我可是有点懵了……
倒不是多难,是我实在觉得这个序列号的算法有问题……
先是追踪USER32.GetDlgItemTextA函数
在该函数前下断
跑程序,然后随便输入一个序列号
停在之前下断的函数前,Alt+F9回到之前的程序领空
开始单步走程序,很快就会看到程序调用一个函数,这便是计算序列号的函数:
以下是计算代码……
问题就出来了:
0040134A PUSH EBP ;保护现场
0040134B MOV EBP,ESP
0040134D SUB ESP,68
00401350 PUSH DWORD PTR SS:[EBP+8] ;将用户名压入堆栈
00401353 CALL <JMP.&CRTDLL.atof> ;将用户名转换为双精度浮点数
00401358 FST QWORD PTR SS:[EBP-18]
0040135B SUB ESP,8
0040135E FSTP QWORD PTR SS:[ESP]
00401361 CALL <JMP.&CRTDLL.floor> ;将浮点数小数位向下舍去(记为s1)
00401366 FSTP QWORD PTR SS:[EBP-8]
00401369 PUSH DWORD PTR SS:[EBP+C] ;将注册码压入堆栈
0040136C CALL <JMP.&CRTDLL.atof> ;将注册码转换为双精度浮点数
00401371 FST QWORD PTR SS:[EBP-28]
00401374 SUB ESP,8
00401377 FSTP QWORD PTR SS:[ESP]
0040137A CALL <JMP.&CRTDLL.floor> ;将浮点数小数位向下舍去(记为s2)
0040137F ADD ESP,18
00401382 FST QWORD PTR SS:[EBP-10]
00401385 FMUL QWORD PTR SS:[EBP-8] ;sm=s1*s2
00401388 FLDZ ;ST(0)置零
0040138A FCOMPP ;检查相乘结果是否为零
0040138C FSTSW AX
0040138E SAHF
0040138F JNZ SHORT zebrone.00401398 ;不为零则跳转(此处不跳则失败)
00401391 XOR EAX,EAX
00401393 JMP zebrone.0040142E
00401398 FLD QWORD PTR SS:[EBP-8] ;装入s1
0040139B FCOMP QWORD PTR SS:[EBP-10] ;与s2对比
0040139E FSTSW AX
004013A0 SAHF
004013A1 JNZ SHORT zebrone.004013AA ;不等则跳(此处不跳则失败)
004013A3 XOR EAX,EAX
004013A5 JMP zebrone.0040142E
004013AA FLD QWORD PTR SS:[EBP-8] ;装入s1
004013AD FSTP QWORD PTR SS:[EBP-38] ;存储s1并出栈
004013B0 FLD1 ;ST(0)装入1
004013B2 FST QWORD PTR SS:[EBP-40] ;存储1
004013B5 FCOMP QWORD PTR SS:[EBP-38] ;对比1与s1(1-s1)
004013B8 FSTSW AX
004013BA SAHF
004013BB JA SHORT zebrone.004013EA ;高于则跳(此处跳转则失败)
004013BD FILD QWORD PTR DS:[403038] ;装入10000000000
004013C3 FST QWORD PTR SS:[EBP-48] ;存储10000000000
004013C6 FCOMP QWORD PTR SS:[EBP-38] ;对比10000000000与s1
004013C9 FSTSW AX
004013CB SAHF
004013CC JB SHORT zebrone.004013EA ;低于则跳(此处跳转则失败)
004013CE FLD QWORD PTR SS:[EBP-10] ;装入s2
004013D1 FSTP QWORD PTR SS:[EBP-50]
004013D4 FLD QWORD PTR SS:[EBP-40]
004013D7 FCOMP QWORD PTR SS:[EBP-50] ;对比1与s2
004013DA FSTSW AX
004013DC SAHF
004013DD JA SHORT zebrone.004013EA ;高于则跳(此处跳转则失败)
004013DF FLD QWORD PTR SS:[EBP-48]
004013E2 FCOMP QWORD PTR SS:[EBP-50] ;对比10000000000与s2
004013E5 FSTSW AX
004013E7 SAHF
004013E8 JNB SHORT zebrone.004013EE ;不低于则跳(此处不跳则失败)
004013EA XOR EAX,EAX
004013EC JMP SHORT zebrone.0040142E
004013EE FLD QWORD PTR SS:[EBP-8] ;装入s1
004013F1 FSIN ;k1=sin(s1)
004013F3 FSTP QWORD PTR SS:[EBP-58] ;存储k1
004013F6 FLD QWORD PTR SS:[EBP-10] ;装入s2
004013F9 FSIN ;k2=sin(s2)
004013FB FSTP QWORD PTR SS:[EBP-60] ;存储k2
004013FE FLD QWORD PTR SS:[EBP-58] ;装入k1
00401401 FMUL QWORD PTR SS:[EBP-60] ;km=k1*k2
00401404 FILD QWORD PTR DS:[403030] ;装入1.0e+16
0040140A FMULP ST(1),ST ;km*1.0e+16
0040140C SUB ESP,8
0040140F FSTP QWORD PTR SS:[ESP] ;结果存入12F99C
00401412 CALL <JMP.&CRTDLL.floor> ;小数位向下舍去记为k
00401417 ADD ESP,8
0040141A FSTP QWORD PTR SS:[EBP-68] ;存储k
0040141D FLDZ ;装入0
0040141F FCOMP QWORD PTR SS:[EBP-68] ;对比0与k
00401422 FSTSW AX
00401424 SAHF
00401425 JNZ SHORT zebrone.0040142C ;不等则跳(此处跳转则失败)
00401427 XOR EAX,EAX ;EAX清零
00401429 INC EAX ;EAX自加1
0040142A JMP SHORT zebrone.0040142E
0040142C XOR EAX,EAX ;EAX清零
0040142E LEAVE
0040142F RETN
原来的困惑所在,atof函数算一个。一直以为atof函数是将每个字符的ASCII值累加转换成双精度浮点型是,后来才算明白,其意义其实是将字符串以双精度浮点形式读出。那也就是说如果字符串本身是字母,那结果一定是0.0……
弄明白这个,结合OllyDBG的FPU查看器,很多问题就能迎刃而解了。从上面的注释,我想大家也很容易可以推断出序列号的计算方法了:
将用户名以双精度浮点形式读出,将小数位舍去,记为s1.序列号以同样的方法处理记为s2,那么,验证该用户名与序列号相符的条件为:
1)s1!=s2
2)s1*s2!=0
3)1<=s1<=1.0e+10
4)1<=s2<=1.0e+10
按照上述条件验证s1与s2后,再进行运算:sin(s1)*sin(s2)*1.0e+16.结果的小数位舍去,记为k.若k=0,则认为用户名与序列号相符,验证成功!其实也就是说:s1或s2中任意一个数的正弦函数为0,则成功。
但有个问题……现在有两种可能:一是我的分析有误,二是这个CM程序的作者在耍我!s1与s2均为经过舍去小数位处理过的,也就是说虽然是以双精度浮点形式存储,但实质上他们都可以算作是整数……那么,有没有一个不为0的整数的正弦值为0?没有!也就是说……如果我的分析没有出错,那么这个程序只能爆破,根本就没有正确的序列号……
如果有大牛能耐着性子看完我这个帖子……
希望能帮忙分析一下,是怎么回事……
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法