CrackMe1.0的破解
Wrote By
NYDoll
自从研究CCG的CrackMe之后 便开始对CrackMe这个东西很感兴趣,所以自己也想作出一个来,所以上网下载了一些,回来
研究想借鉴一下经验,我们来看看这个CrackMe,比较典型BC编写的,有它特定的结构,试试你就知道了,比较适合初学者破解,即使你写不出注册机,找出注册吗是应该一点问题都没有的,然后慢慢就可以看懂算法,到时候写注册机的容易了。^_^
罗嗦了好多,我们还是回来看看程序:
我用的断点是BPX HMEMCPY,算得上是一个万能断点了,一般的程序用这个断点都可以拦下来。
来到这里,我们开始步步观察算法:
* Reference To: USER32.GetDlgItem, Ord:0000h
|
:004010B6 E8E79B0000 Call 0040ACA2
:004010BB 8BF0
mov esi, eax
:004010BD 8D8548FFFFFF lea eax, dword
ptr [ebp+FFFFFF48]
:004010C3 50
push eax //用户名入栈
:004010C4 E867050000 call 00401630
:004010C9 59
pop ecx
:004010CA 8945D8
mov dword ptr [ebp-28], eax //将用户名压入地址[EBP-28]
:004010CD 8D95E4FEFFFF lea edx, dword
ptr [ebp+FFFFFEE4]
:004010D3 52
push edx //注册码入栈
:004010D4 E857050000 call 00401630
:004010D9 59
pop ecx
:004010DA 68EAB04000 push 0040B0EA
:004010DF E84C050000 call 00401630
:004010E4 59
pop ecx
:004010E5 680EB14000 push 0040B10E
:004010EA E841050000 call 00401630
:004010EF 59
pop ecx
:004010F0 837DD803 cmp
dword ptr [ebp-28], 00000003 //对比用户名位数是否小于3
:004010F4 7E7B
jle 00401171 //小于或者等于则跳转到:00401171
:004010F6 90
nop
:004010F7 90
nop
:004010F8 90
nop
:004010F9 90
nop
:004010FA 33C9
xor ecx, ecx //ECX寄存器清零
:004010FC 33D2
xor edx, edx //EDX寄存器清零
:004010FE 33DB
xor ebx, ebx //EBX寄存器清零
:00401100 33C0
xor eax, eax //EAX寄存器清零
:00401102 837DD832 cmp
dword ptr [ebp-28], 00000032 //对比用户名位数是否小于50
:00401106 7D69
jge 00401171 //大于或者等于则跳转到:00401171
:00401108 90
nop
:00401109 90
nop
:0040110A 90
nop
:0040110B 90
nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040111C(C)
|
:0040110C 0FBE840D48FFFFFF movsx eax, byte ptr [ebp+ecx-000000B8]
//依次取用户名的每一位放入EAX
:00401114 41
inc ecx //ECX寄存器加一
:00401115 33C1
xor eax, ecx //将EAX和ECX寄存器的值进行异或运算后放入EAX寄存器
:00401117 03D8
add ebx, eax //EBX存放每次循环后EAX值的累加结果
:00401119 3B4DD8
cmp ecx, dword ptr [ebp-28] //检测用户名的字符是否取完
:0040111C 75EE
jne 0040110C //取完则跳出循环
:0040111E 6BC006
imul eax, 00000006 //将用户名最后一位字符与ECX寄存器的值异或后的结果乘以6,然后将结果保存到EAX中。
:00401121 C1E307
shl ebx, 07 //EBX寄存器的值逻辑左移7,结果存放到EDX寄存器中
:00401124 03C3
add eax, ebx //将EAX寄存器和EBX寄存器中的值相加。
:00401126 8945C8
mov dword ptr [ebp-38], eax //将结果压入地址[EBP-38]中
:00401129 FF75C8
push [ebp-38] //压入结果
* Possible StringData Ref from Data Obj ->"%lX"
|
:0040112C 6838B44000 push 0040B438
//---\
:00401131 8D8D80FEFFFF lea ecx, dword
ptr [ebp+FFFFFE80] // \
:00401137 51
push ecx
// \
:00401138 E8873D0000 call 00404EC4
//
\
:0040113D 83C40C
add esp, 0000000C //
> 将上面的计算结果转换成16进制,它的十六进制值就是真正的注册码。
:00401140 8D8580FEFFFF lea eax, dword
ptr [ebp+FFFFFE80] // /
:00401146 50
push eax
// /
:00401147 8D95E4FEFFFF lea edx, dword
ptr [ebp+FFFFFEE4] // /
:0040114D 52
push edx
//---/
* Reference To: KERNEL32.lstrcmpA, Ord:0000h
|
:0040114E E8339C0000 Call 0040AD86
//对比真假注册码
:00401153 85C0
test eax, eax
:00401155 750D
jne 00401164 //若对比失败,则跳转。
* Possible StringData Ref from Data Obj ->"恭喜您! 如果您能编写出这个CrackMe的KeyGen, "
->"请写一个教程给我 ;).
" //注册成功信息!
->"
"
|
:00401157 683CB44000 push 0040B43C
:0040115C 56
push esi
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040115D E8289B0000 Call 0040AC8A
:00401162 EB18
jmp 0040117C
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401155(C)
|
* Possible StringData Ref from Data Obj ->"这个注册码是无效的!! 请再试一遍... "
->": <尚未注册>
" //注册失败信息!
|
:00401164 6890B44000 push 0040B490
:00401169 56
push esi
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:0040116A E81B9B0000 Call 0040AC8A
:0040116F EB0B
jmp 0040117C
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004010F4(C), :00401106(C)
|
* Possible StringData Ref from Data Obj ->"用户名必须为 4个字符以上 50个字符一下 "
->"!!
" //注册名或者注册码位数不符时的提示信息
|
:00401171 68C9B44000 push 0040B4C9
:00401176 56
push esi
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:00401177 E80E9B0000 Call 0040AC8A
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00401162(U), :0040116F(U)
|
:0040117C 5F
pop edi
:0040117D 5E
pop esi
:0040117E 5B
pop ebx
:0040117F 8BE5
mov esp, ebp
:00401181 5D
pop ebp
:00401182 C3
ret
//接下来我们来总结一下算法,举例如用户名为NYDoll,CrackMe依次取出用户名的每一位字符,转换成十进制,然后
//与当前字符的位数进行异或运算,然后将每次异或运算后的值累加到EBX寄存器中,NYDoll的累加结果为559,然后
//将累加结果逻辑左移7位,将其结果保存到EBX中。我的结果为71552
//将注册名的最后一位与注册名的位数进行异或运算,其值乘以6,然后将结果保存到EAX寄存器中,即l与6进行异或运算
//然后再乘以6,结果为636。
//将71552与636的和72188的16进制值119FC入栈,即119FC为NYDoll相对应的注册码。
- 标 题:第二个CrackMe的破解 (6千字)
- 作 者:NYDoll
- 时 间:2001-8-17 16:39:21
- 链 接:http://bbs.pediy.com