文章作者: busheler
附件:crackme001.rar
------------------------------------------------
【破文标题】算法分析之CrackMe001By飘云[PYG]
【破文作者】busheler
【作者邮箱】busheler@sohu.com
【作者主页】
【破解工具】PEiDv0.94,LordPEDeluxeV1.4,importrev1.6,W32Dasm10.0,odbg110,QuickUnpackv1.0b3
【破解平台】Windows2000
【软件名称】CrackMe001By飘云[PYG]
【软件大小】250KB
【原版下载】http://www.chinapyg.cn/attachment.php?aid=385
【保护方式】注册码
【软件简介】【[PYG]CrackMe#1】
算法初探--Crackme001By飘云[PYG]
1.去除启动时的延时。
2.分析算法。
3.去除退出时的Nag。
------------------------------------------------------------------------
一、查壳:
PEiDv0.94查壳为FSG2.0->bart/xtOEP为4689c8
由于脱壳水平有限,脱壳未果!
二、找资源:
前面为完全脱壳程序并不影响资源分析。
W32Dasm10.0载入我未脱壳成功文件可以看到以下信息。
:004682A1BA03000000movedx,00000003
:004682A6E821BFF9FFcall004041CC
:004682AB8B45D4moveax,dwordptr[ebp-2C]
:004682AEE859BEF9FFcall0040410C
:004682B38BD8movebx,eax
:004682B58D55C8leaedx,dwordptr[ebp-38]
:004682B88B8614030000moveax,dwordptr[esi+00000314]
:004682BEE8E9BAFCFFcall00433DAC
:004682C38B45C8moveax,dwordptr[ebp-38]
:004682C6E841BEF9FFcall0040410C
:004682CB3BD8cmpebx,eax
:004682CD7427je004682F6
*PossibleStringDataReffromDataObj->"注册失败!"
|
:004682CFA1DCA64600moveax,dwordptr[0046A6DC]
:004682D4E833C0F9FFcall0040430C
:004682D98BD0movedx,eax
:004682DB8D45C4leaeax,dwordptr[ebp-3C]
:004682DEE861BDF9FFcall00404044
:004682E38B55C4movedx,dwordptr[ebp-3C]
:004682E68B8614030000moveax,dwordptr[esi+00000314]
:004682ECE8EBBAFCFFcall00433DDC
:004682F1E9ED000000jmp004683E3
........
:004683818B45E8moveax,dwordptr[ebp-18]
:004683848B55F4movedx,dwordptr[ebp-0C]
:00468387E8CCBEF9FFcall00404258
:0046838C7521jne004683AF
:0046838E8D45E4leaeax,dwordptr[ebp-1C]
:0046839150pusheax
:004683928D55B0leaedx,dwordptr[ebp-50]
:004683958B8614030000moveax,dwordptr[esi+00000314]
:0046839BE80CBAFCFFcall00433DAC
:004683A08B45B0moveax,dwordptr[ebp-50]
:004683A38D541F01leaedx,dwordptr[edi+ebx+01]
:004683A78B4DE0movecx,dwordptr[ebp-20]
:004683AAE8BDBFF9FFcall0040436C
*Referencedbya(U)nconditionalor(C)onditionalJumpatAddress:
|:0046838C(C)
|
:004683AF8B45E4moveax,dwordptr[ebp-1C]
:004683B2E8E9FAF9FFcall00407EA0
:004683B70540E20100addeax,0001E240
:004683BC3B0518BC4600cmpeax,dwordptr[0046BC18]
:004683C2751Fjne004683E3
:004683C46A40push00000040
*PossibleStringDataReffromDataObj->"恭喜"
|
:004683C6A1D4A64600moveax,dwordptr[0046A6D4]
:004683CBE83CBFF9FFcall0040430C
:004683D050pusheax
*PossibleStringDataReffromDataObj->"注册成功!"
|
:004683D1A1D0A64600moveax,dwordptr[0046A6D0]
:004683D6E831BFF9FFcall0040430C
:004683DB50pusheax
:004683DC6A00push00000000
:004683DEE8E5E1F9FFcall004065C8
三、带壳走上漫漫路......
1、跟踪分析:
由odbg110载入带壳程序,F9运行...因为程序已经运行,这是我们应该已经进入主程序领空了。
由前找出相关资源很容易到达这里:
并在004681C0处F2下断点,输入用户名、注册码...“确定”,立即被断下,呵呵!
慢慢看看......
004681C0/.55pushebp
004681C1|.8BECmovebp,esp
004681C3|.B90A000000movecx,0A
004681C8|>6A00/push0
004681CA|.6A00|push0
004681CC|.49|dececx
004681CD|.^75F9\jnzshortCrackMe0.004681C8
004681CF|.53pushebx
004681D0|.56pushesi
004681D1|.57pushedi
004681D2|.8BF0movesi,eax
004681D4|.33C0xoreax,eax
004681D6|.55pushebp
004681D7|.683A844600pushCrackMe0.0046843A
004681DC|.64:FF30pushdwordptrfs:[eax]
004681DF|.64:8920movdwordptrfs:[eax],esp
004681E2|.8D55FCleaedx,dwordptrss:[ebp-4]
004681E5|.8B8610030000moveax,dwordptrds:[esi+310]
004681EB|.E8BCBBFCFFcallCrackMe0.00433DAC
004681F0|.8D55F8leaedx,dwordptrss:[ebp-8]
004681F3|.8B8614030000moveax,dwordptrds:[esi+314]
004681F9|.E8AEBBFCFFcallCrackMe0.00433DAC
004681FE|.33C0xoreax,eax
00468200|.8945F0movdwordptrss:[ebp-10],eax
00468203|.8B45FCmoveax,dwordptrss:[ebp-4]
00468206|.E801BFF9FFcallCrackMe0.0040410C
0046820B|.8BD8movebx,eax
0046820D|.837DFC00cmpdwordptrss:[ebp-4],0;判断用户名是否为0
00468211|.7406jeshortCrackMe0.00468219;非0,跳
00468213|.837DF800cmpdwordptrss:[ebp-8],0;判断注册码是否为0
00468217|.7527jnzshortCrackMe0.00468240;非0,跳
00468219|>A1D8A64600moveax,dwordptrds:[46A6D8];请输入完整信息!
0046821E|.E8E9C0F9FFcallCrackMe0.0040430C
00468223|.8BD0movedx,eax
00468225|.8D45DCleaeax,dwordptrss:[ebp-24]
00468228|.E817BEF9FFcallCrackMe0.00404044
0046822D|.8B55DCmovedx,dwordptrss:[ebp-24]
00468230|.8B8614030000moveax,dwordptrds:[esi+314]
00468236|.E8A1BBFCFFcallCrackMe0.00433DDC
0046823B|.E9A3010000jmpCrackMe0.004683E3
00468240|>8BFBmovedi,ebx
00468242|.85FFtestedi,edi
00468244|.7E37jleshortCrackMe0.0046827D
00468246|.BB01000000movebx,1
0046824B|>8D4DD8/leaecx,dwordptrss:[ebp-28]
0046824E|.8B45FC|moveax,dwordptrss:[ebp-4];用户名入EAX
00468251|.0FB64418FF|movzxeax,byteptrds:[eax+ebx-1]
00468256|.C1E800|shreax,0
00468259|.BA01000000|movedx,1
0046825E|.E815FCF9FF|callCrackMe0.00407E78;求各位用户名ASCAII值
00468263|.8B55D8|movedx,dwordptrss:[ebp-28]
00468266|.8D45F4|leaeax,dwordptrss:[ebp-C]
00468269|.E8A6BEF9FF|callCrackMe0.00404114;把各位用户把ASCAII组成字符串,即为第
二组验证码
0046826E|.8B45FC|moveax,dwordptrss:[ebp-4]
00468271|.0FB64418FF|movzxeax,byteptrds:[eax+ebx-1]
00468276|.0145F0|adddwordptrss:[ebp-10],eax;累加用户名各位ASCII值
00468279|.43|incebx
0046827A|.4F|decedi
0046827B|.^75CE\jnzshortCrackMe0.0046824B
0046827D|>8D55D0leaedx,dwordptrss:[ebp-30]
00468280|.8B45F0moveax,dwordptrss:[ebp-10];前面累加值入eax
00468283|.E8DCFAF9FFcallCrackMe0.00407D64;转累加值为10进制字符串,即为第一组验
证码
00468288|.FF75D0pushdwordptrss:[ebp-30]
0046828B|.FF75F4pushdwordptrss:[ebp-C]
0046828E|.8D55CCleaedx,dwordptrss:[ebp-34]
00468291|.A118BC4600moveax,dwordptrds:[46BC18];第三段验证码?那里来的??????
00468296|.E8C9FAF9FFcallCrackMe0.00407D64;第三段验证码以10进制方式转为字符串
0046829B|.FF75CCpushdwordptrss:[ebp-34]
0046829E|.8D45D4leaeax,dwordptrss:[ebp-2C]
004682A1|.BA03000000movedx,3
004682A6|.E821BFF9FFcallCrackMe0.004041CC;第一、第二、第三组验证码合并
004682AB|.8B45D4moveax,dwordptrss:[ebp-2C]
004682AE|.E859BEF9FFcallCrackMe0.0040410C
004682B3|.8BD8movebx,eax
004682B5|.8D55C8leaedx,dwordptrss:[ebp-38]
004682B8|.8B8614030000moveax,dwordptrds:[esi+314]
004682BE|.E8E9BAFCFFcallCrackMe0.00433DAC
004682C3|.8B45C8moveax,dwordptrss:[ebp-38]
004682C6|.E841BEF9FFcallCrackMe0.0040410C
004682CB|.3BD8cmpebx,eax;输入注册码位数与算出验证码位数是否相
等!
004682CD7427jeshortCrackMe0.004682F6;相等跳去验证,不等。。注册失败!
004682CF|.A1DCA64600moveax,dwordptrds:[46A6DC];"注册失败!"
004682D4|.E833C0F9FFcallCrackMe0.0040430C
004682D9|.8BD0movedx,eax
004682DB|.8D45C4leaeax,dwordptrss:[ebp-3C]
004682DE|.E861BDF9FFcallCrackMe0.00404044
004682E3|.8B55C4movedx,dwordptrss:[ebp-3C]
004682E6|.8B8614030000moveax,dwordptrds:[esi+314]
004682EC|.E8EBBAFCFFcallCrackMe0.00433DDC
004682F1|.E9ED000000jmpCrackMe0.004683E3
004682F6|>8D55C0leaedx,dwordptrss:[ebp-40]
004682F9|.8B45F0moveax,dwordptrss:[ebp-10]
004682FC|.E863FAF9FFcallCrackMe0.00407D64
00468301|.8B45C0moveax,dwordptrss:[ebp-40]
00468304|.E803BEF9FFcallCrackMe0.0040410C
00468309|.8BD8movebx,eax
0046830B|.8B45F4moveax,dwordptrss:[ebp-C]
0046830E|.E8F9BDF9FFcallCrackMe0.0040410C
00468313|.8BF8movedi,eax
00468315|.8D55BCleaedx,dwordptrss:[ebp-44]
00468318|.A118BC4600moveax,dwordptrds:[46BC18]
0046831D|.E842FAF9FFcallCrackMe0.00407D64
00468322|.8B45BCmoveax,dwordptrss:[ebp-44]
00468325|.E8E2BDF9FFcallCrackMe0.0040410C
0046832A|.8945E0movdwordptrss:[ebp-20],eax
0046832D|.8D45ECleaeax,dwordptrss:[ebp-14]
00468330|.50pusheax
00468331|.8D55B8leaedx,dwordptrss:[ebp-48]
00468334|.8B8614030000moveax,dwordptrds:[esi+314]
0046833A|.E86DBAFCFFcallCrackMe0.00433DAC
0046833F|.8B45B8moveax,dwordptrss:[ebp-48]
00468342|.8BCBmovecx,ebx
00468344|.BA01000000movedx,1
00468349|.E81EC0F9FFcallCrackMe0.0040436C
0046834E|.8B45ECmoveax,dwordptrss:[ebp-14]
00468351|.E84AFBF9FFcallCrackMe0.00407EA0
00468356|.83E812subeax,12;输入注册码第一组减去12(十进制18)应等
于第一组验证码
00468359|.3B45F0cmpeax,dwordptrss:[ebp-10]
0046835C0F8481000000jeCrackMe0.004683E3;不等跳出!
00468362|.8D45E8leaeax,dwordptrss:[ebp-18]
00468365|.50pusheax
00468366|.8D55B4leaedx,dwordptrss:[ebp-4C]
00468369|.8B8614030000moveax,dwordptrds:[esi+314]
0046836F|.E838BAFCFFcallCrackMe0.00433DAC
00468374|.8B45B4moveax,dwordptrss:[ebp-4C]
00468377|.8D5301leaedx,dwordptrds:[ebx+1]
0046837A|.8BCFmovecx,edi
0046837C|.E8EBBFF9FFcallCrackMe0.0040436C
00468381|.8B45E8moveax,dwordptrss:[ebp-18];输入第二段注册码入eax
00468384|.8B55F4movedx,dwordptrss:[ebp-C];验证码也就是注册码入edx
00468387|.E8CCBEF9FFcallCrackMe0.00404258;去比较
0046838C7421jeshortCrackMe0.004683AF;不等跳!
0046838E|.8D45E4leaeax,dwordptrss:[ebp-1C]
00468391|.50pusheax
00468392|.8D55B0leaedx,dwordptrss:[ebp-50]
00468395|.8B8614030000moveax,dwordptrds:[esi+314]
0046839B|.E80CBAFCFFcallCrackMe0.00433DAC
004683A0|.8B45B0moveax,dwordptrss:[ebp-50];输入注册码入EAX
004683A3|.8D541F01leaedx,dwordptrds:[edi+ebx+1];注册码位数入EDX
004683A7|.8B4DE0movecx,dwordptrss:[ebp-20]
004683AA|.E8BDBFF9FFcallCrackMe0.0040436C
004683AF|>8B45E4moveax,dwordptrss:[ebp-1C]
004683B2|.E8E9FAF9FFcallCrackMe0.00407EA0
004683B7|.0540E20100addeax,1E240;第三组输入注册码十进制与1E240(123456)
相加
004683BC|.3B0518BC4600cmpeax,dwordptrds:[46BC18];与验证码最后一组对比
004683C2751FjnzshortCrackMe0.004683E3;不等跳!
004683C4|.6A40push40
004683C6|.A1D4A64600moveax,dwordptrds:[46A6D4];"恭喜"
004683CB|.E83CBFF9FFcallCrackMe0.0040430C
004683D0|.50pusheax
004683D1|.A1D0A64600moveax,dwordptrds:[46A6D0];"注册成功!"
004683D6|.E831BFF9FFcallCrackMe0.0040430C
004683DB|.50pusheax;|Text
004683DC|.6A00push0;|hOwner=NULL
004683DE|.E8E5E1F9FFcallCrackMe0.004065C8;\MessageBoxA
----------------------------------
00468291|.A118BC4600moveax,dwordptrds:[46BC18];第三段验证码?那里来的??????
搜索===〉二进制字符===〉HEX+3中输入18BC46,选在“整个区块”很容易找到下面这里,在004685B0处下断点,点注册未被断下,显然这部分代码在程序启动时已经运行过了。
没有办法,带壳我是无法跟踪了,抓出QuickUnpackv1.0b3脱夹克,再odbg110载入,004685B0处下断点,F9运行,果然被立即断下:)
看看.......
004685B0/.55pushebp
004685B1|.8BECmovebp,esp
004685B3|.33C9xorecx,ecx
004685B5|.51pushecx
004685B6|.51pushecx
004685B7|.51pushecx
004685B8|.51pushecx
004685B9|.33C0xoreax,eax
004685BB|.55pushebp
004685BC|.687F864600pushCrackMe0.0046867F
004685C1|.64:FF30pushdwordptrfs:[eax]
004685C4|.64:8920movdwordptrfs:[eax],esp
004685C7|.C70514BC46000A00000>movdwordptrds:[46BC14],0A
004685D1|.E87A10FAFFcallCrackMe0.00409650;取系统年份-月份-日期
004685D6|.83C4F8addesp,-8;/
004685D9|.DD1C24fstpqwordptrss:[esp];|Arg1(8-byte)
004685DC|.9Bwait;|
004685DD|.8D45FCleaeax,dwordptrss:[ebp-4];|
004685E0|.E87F1CFAFFcallCrackMe0.0040A264;\CrackMe0.0040A264
004685E5|.8B55FCmovedx,dwordptrss:[ebp-4];系统时间串入EDX
004685E8|.B810BC4600moveax,CrackMe0.0046BC10
004685ED|.E8AEB8F9FFcallCrackMe0.00403EA0
004685F2|.8D45F8leaeax,dwordptrss:[ebp-8]
004685F5|.50pusheax
004685F6|.B904000000movecx,4
004685FB|.BA01000000movedx,1
00468600|.A110BC4600moveax,dwordptrds:[46BC10]
00468605|.E862BDF9FFcallCrackMe0.0040436C
0046860A|.FF75F8pushdwordptrss:[ebp-8]
0046860D|.8D45F4leaeax,dwordptrss:[ebp-C]
00468610|.50pusheax
00468611|.B902000000movecx,2
00468616|.BA06000000movedx,6
0046861B|.A110BC4600moveax,dwordptrds:[46BC10]
00468620|.E847BDF9FFcallCrackMe0.0040436C
00468625|.FF75F4pushdwordptrss:[ebp-C]
00468628|.8D45F0leaeax,dwordptrss:[ebp-10]
0046862B|.50pusheax
0046862C|.B902000000movecx,2
00468631|.BA09000000movedx,9
00468636|.A110BC4600moveax,dwordptrds:[46BC10]
0046863B|.E82CBDF9FFcallCrackMe0.0040436C
00468640|.FF75F0pushdwordptrss:[ebp-10]
00468643|.B80CBC4600moveax,CrackMe0.0046BC0C
00468648|.BA03000000movedx,3
0046864D|.E87ABBF9FFcallCrackMe0.004041CC
00468652|.A10CBC4600moveax,dwordptrds:[46BC0C]
00468657|.E844F8F9FFcallCrackMe0.00407EA0
0046865C|.C1E003shleax,3;年月日*2^3
0046865F|.A318BC4600movdwordptrds:[46BC18],eax;好久未破软件了,这个命令不记得了,反
正就是把上面的乘积入地址"DS:[46bc18]"
00468664|.33C0xoreax,eax
00468666|.5Apopedx
00468667|.59popecx
00468668|.59popecx
00468669|.64:8910movdwordptrfs:[eax],edx
0046866C|.6886864600pushCrackMe0.00468686
00468671|>8D45F0leaeax,dwordptrss:[ebp-10]
00468674|.BA04000000movedx,4
00468679|.E8F2B7F9FFcallCrackMe0.00403E70
0046867E\.C3retn
瞅瞅callCrackMe0.00409650里的内容:
00409650/$83C4E8addesp,-18
00409653|.8D442408leaeax,dwordptrss:[esp+8]
00409657|.50pusheax;/pLocaltime
00409658|.E883C8FFFFcall;\GetLocalTime
0040965D|.66:8B4C240Emovcx,wordptrss:[esp+E];当前日期入CX
00409662|.66:8B54240Amovdx,wordptrss:[esp+A];当前月份入DX
00409667|.66:8B442408movax,wordptrss:[esp+8];当前年份入AX
0040966C|.E81BFEFFFFcallCrackMe0.0040948C
00409671|.DD1C24fstpqwordptrss:[esp]
00409674|.9Bwait
00409675|.DD0424fldqwordptrss:[esp]
00409678|.83C418addesp,18
0040967B\.C3retn
2、验证码(非注册码)算法分析
验证码应该由三部分组成:
第一部分:用户名各位ASCII值之和;
第二部分:用户名各位ASCAII值组成的字符串;
第三部分:系统年月日为20060113这种形式,乘以2的三次方,即20060113*2^3=160480904。
用户名为:busheler,系统时间是2006年1月13日
其ASCII码为:
busheler
Dec:98117115104101108101114
Hex:62757368656C6572
第一部分:
98+117+115+104+101+108+101+114=858
第二部分:
62757368656C6572
第三部分:
20060113*2^3=160480904
4、注册验证过程大概是这样的:
(1)第一组注册码-18与验证码比较。
(2)第二组是直接对比,主循环每4位、4位进行验证,如果注册码数(肯定是偶数)为非4的倍数,另两组单独验证。
(3)第三组注册码+123456与验证马比较。
5、注册码算法:
用户名:busheler
第一组:858+18=876
第二组:62757368656C6572
第三组:160480904-123456=160357448
由此:
用户名:busheler
注册码:87662757368656C6572160357448
备注:
1、由于我系统时间格式的问题,该CrackMe运行时总弹出这样的对话框:"'2006-2'isnotavalidintegervalue"...,并造成第三个验证码总为0,呵呵。感谢飘云指导,并顺利完成注册码算法分析!:)
2、关于“去除启动时的延时”及“去除退出时的Nag”未分析。