-
-
CRACKME算法分析(算法练习23)
-
发表于:
2006-4-16 12:10
5412
-
【破文标题】CRACKME分析
【破文作者】逍遥风
【破解工具】OD PEID
【破解平台】WINXP
【原版下载】www.crackmes.de
【破解声明】简单的算法练习,一点心得与大家分享
----------------------------------------------------------------------
1)PDID检查:UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo。简单的壳。轻松脱去。
再次检查:MASM32 / TASM32
2)OD载入程序,用字符串查找很容易找到关键。向上找发现有两处JMP.&USER32.GetDlgItemTe,再第一处下断
来到如下代码。。。
004012BD E8 08010000 CALL <JMP.&USER32.GetDlgItemTe>; 取注册名位数(在这里下断)
004012C2 83F8 00 CMP EAX,0 ; 输入注册名了吗?
004012C5 74 18 JE SHORT upkc2.004012DF ; 没有输入注册名就出现错误提示
004012C7 6A 40 PUSH 40
004012C9 68 38314000 PUSH upkc2.00403138 ; ASCII "1234567"
004012CE 6A 6B PUSH 6B
004012D0 FF75 08 PUSH DWORD PTR SS:[EBP+8]
004012D3 E8 F2000000 CALL <JMP.&USER32.GetDlgItemTe>; 取注册码位数
004012D8 83F8 00 CMP EAX,0 ; 输入注册码了吗?
004012DB 74 02 JE SHORT upkc2.004012DF ; 没有就出现错误提示
004012DD EB 17 JMP SHORT upkc2.004012F6
004012DF 6A 00 PUSH 0
004012E1 68 62344000 PUSH upkc2.00403462 ; key/crackme #2
004012E6 68 00304000 PUSH upkc2.00403000 ; please fill in 1 more char!!
004012EB 6A 00 PUSH 0
004012ED E8 FC000000 CALL <JMP.&USER32.MessageBoxA>
004012F2 C9 LEAVE
004012F3 C2 1000 RETN 10
004012F6 68 38304000 PUSH upkc2.00403038 ; ASCII "lovetc"
004012FB E8 30010000 CALL <JMP.&KERNEL32.lstrlenA> ; 取注册名开始计算
00401300 33F6 XOR ESI,ESI ; ESI清零
00401302 8BC8 MOV ECX,EAX ; 注册名位数放进ECX
00401304 B8 01000000 MOV EAX,1 ; 使EAX=1
00401309 8B15 38304000 MOV EDX,DWORD PTR DS:[403038] ; 倒序取注册名前4位的ASCII码,并放进EDX
0040130F 8A90 37304000 MOV DL,BYTE PTR DS:[EAX+403037>; 按顺序取注册名每一位的ACSII码
00401315 81E2 FF000000 AND EDX,0FF ; 使EDX=注册码每一位的ASII码
0040131B 8BDA MOV EBX,EDX ; 使EBX=EDX
0040131D 0FAFDA IMUL EBX,EDX ; EBX=EBX*EDX(求每一位注册码对应的ASCII码的平方),结果设为A(n)
00401320 03F3 ADD ESI,EBX ; ESI=ESI+EBX,所得的和设为B,B(n+1)=A(n+1)+Dn
00401322 8BDA MOV EBX,EDX ; 使EBX=EDX,注册名每一位的ASCII码
00401324 D1FB SAR EBX,1 ; 注册名每一位的ASCII码除以2的一次方,商设为C
00401326 03F3 ADD ESI,EBX ; B(n)+C(n)
00401328 2BF2 SUB ESI,EDX ; B(n)+C(n)-对应位数注册码的ASCII值,结果设为D(n)
0040132A 40 INC EAX ; 每计算一次EAX+1
0040132B 49 DEC ECX ; 每计算一次ECX-1
0040132C ^ 75 DB JNZ SHORT upkc2.00401309 ; 继续计算
0040132E 56 PUSH ESI ; 储存计算的结果
0040132F 68 38314000 PUSH upkc2.00403138 ; ASCII "1234567"
00401334 E8 4A000000 CALL upkc2.00401383 ; 取输入的假码,转换成对应的16进制数
00401339 5E POP ESI
0040133A 3BC6 CMP EAX,ESI ; 真假注册码比较
0040133C 75 15 JNZ SHORT upkc2.00401353 ; 不相等就跳向失败
0040133E 6A 00 PUSH 0
00401340 68 62344000 PUSH upkc2.00403462 ; key/crackme #2
00401345 68 B8344000 PUSH upkc2.004034B8 ; good job, i wish you the very best
0040134A 6A 00 PUSH 0
0040134C E8 9D000000 CALL <JMP.&USER32.MessageBoxA>
00401351 EB 13 JMP SHORT upkc2.00401366
00401353 6A 00 PUSH 0
00401355 68 62344000 PUSH upkc2.00403462 ; key/crackme #2
0040135A 68 86344000 PUSH upkc2.00403486 ; you have enter a wrong serial, please try again
----------------------------------------------------------------------
算法总结
1)取注册名每一位的ASCII码,并求其乘方。结果设为An。
2)An与上一次计算的结果D(n-1)相加.得到的结果设为Bn
3)注册码每一位的ASCII码除以2,结果设为Cn
4)B(n)+C(n)-对应位数注册码的ASCII值,结果设为Dn
5)最终结果Dn转换成对应的十进制数就是要输入的注册码
注:n为当前字符在注册名中的位置=计算次数=注册名位数,n=1时D(n-1)=D(0)=0
例:
注册名:lovetc
注册码:71039
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课