标 题:昨天从朋友那里得到一个BCG的CREAKME,这样CREAK对吗?请大家看看。 (4千字)
发信人:赞盛
时 间:2001-10-11 22:32:43
详细信息:
就是那个一开始就说“革命尚未成功”什么的。
工具:Sice 4.05 for win9x
环境:Windows 98 SE
时间:1小时40分钟,好惨。。。。
打开程序,就出来了一个MessageBox,显示没破解成功;按确定,点注册显示同一个MessageBox。
退出程序,呼出Sice下断点Bpx MessageBoxA,重新打开程序,被断。找出以下代码。
0167:0040113B RET 0010
0167:0040113E PUSH 00001000
0167:00401143 PUSH 00402026
0167:00401148 PUSH 004020BF
0167:0040114D PUSH 00
0167:0040114F CALL USER32!MessageBoxA
0167:00401154 LEAVE
0167:00401155 RET 0010
0167:00401158 PUSH 00001000
0167:0040115D PUSH 00402026
//Messagebox的标题"BCG's Official Crackme...(省略)"
0167:00401162 PUSH 00402083
//Messagebox的内容"革命尚未成功....."
0167:00401167 PUSH 00
0167:00401169 CALL USER32!MessageBoxA
//被断处
0167:0040116E LEAVE
0167:0040116F RET 0010
0167:00401172 PUSH 00001000
0167:00401177 PUSH 00402026
0167:0040117C PUSH 00402036
往上看,上面也有一个Messagebox,和下面的标题相同,内容不同。试着把00401162处的PUSH 00402083该为PUSH 004020BF
发现MesssageBox变成了"注册验证成功...."。证明上面的MessageBox为注册成功时才显示的。继续往上看。
0167:00401095 RET 0010
0167:00401098 PUSH 00
0167:0040109A PUSH 004020EF
0167:0040109F PUSH 03
0167:004010A1 PUSH 00
0167:004010A3 PUSH 03
0167:004010A5 PUSH C0000000
0167:004010AA PUSH 004020E5
0167:004010AF CALL KERNEL32!CreateFileA
0167:004010B4 MOV [00402000],EAX
//建立的文件的Handle
0167:004010B9 CMP DWORD PTR [00402000],-01 //文件建立成功时为为文件的Handle,否则是FFFFFFFF(-1)
0167:004010C0 JZ 00401158
//如果文件建立成功就注册不成功,故应该有一文件
0167:004010C6 PUSH 00
在当前目录。文件名在004020E5处。为:[BCG].KEY
0167:004010C8 PUSH 00402107
0167:004010CD PUSH 0A
//读10字节
0167:004010CF PUSH 004020F3
//存放读出的字符的缓冲区1,即字符串1的地址
0167:004010D4 PUSH DWORD PTR [00402000]
0167:004010DA CALL KERNEL32!ReadFile
0167:004010DF TEST EAX,EAX
0167:004010E1 JZ 00401158
//文件读不成功,注册失败
0167:004010E3 PUSH 00
0167:004010E5 PUSH 00402107
0167:004010EA PUSH 0A
//读10字节
0167:004010EC PUSH 004020FD
//存放读出的字符的缓冲区2,即字符串2的地址
0167:004010F1 PUSH DWORD PTR [00402000]
0167:004010F7 CALL KERNEL32!ReadFile
0167:004010FC TEST EAX,EAX
0167:004010FE JZ 00401158
//文件读不成功,注册失败
0167:00401100 PUSH DWORD PTR [00402000]
0167:00401106 CALL KERNEL32!CloseHandle
//关闭Handle
0167:0040110B XOR EAX,EAX
0167:0040110D JMP 00401113
0167:0040110F LEAVE
0167:00401110 RET 0010
0167:00401113 XOR BYTE PTR [EAX+004020F3],58
//运算字符串的代码
0167:0040111A INC EAX
0167:0040111B CMP BYTE PTR [EAX+004020F3],00
0167:00401122 JNZ 00401113
0167:00401124 PUSH 004020F3
//字符串1的地址
0167:00401129 PUSH 004020FD
//字符串2的地址
0167:0040112E CALL KERNEL32!lstrcmp
//比较两字符串
0167:00401133 CMP EAX,00
0167:00401136 JZ 0040113E
//如果相等就注册成功
0167:00401138 JMP 00401158
//否则不成功
0167:0040113A LEAVE
发现有多处校验,然后跳转到00401158,而00401158就是注册不成功时显示的MessageBox。故从后往前推断,看注册成功的条件。
很显然,00401138处的跳转是当两字符串不相等时。004010FE和004010E1处的跳转是当文件读失败时。004010C0处
的跳转是当文件建立成功时,言外之意当前目录应该有一个文件,文件名放在004020E5处。
:d 004020e5
0030:004020E5 5B 42 43 47 5D 2E 4B 65-79 00 80 00 00 00 00 00 [BCG].Key.......
0030:004020F5 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
我就用WINHex在当前目录下建立一名为[BCG].KEY的文件,大小20字节,内容是同一字符(比如D)。
下面是两缓冲区内容
:d 004020f3
0030:004020F3 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
0030:00402103 44 44 44 44 0A 00 00 00-00 04 00 00 00 90 00 00 DDDD............
再次运行程序,中断。按F10逐行执行,观察寄存器内容变化,最后还是注册不成功,问题就在00401113-00401122运算字符串的代码上。
到这里我开始发晕了,这一段费了我至少40分钟。问题就在00402107上,那里存放了第二次读出的字节数(0A)。
最后豁然开朗,其实文件的内容应该就1个字节,ASCII码为58
第一次读10个字节时只读出了1个字节,读出的字节数放在004020FD,为1;第二次读10个字节时什么也没读出来,
就是0,正好把004020FD覆盖,004020FD也成了0,而且读出的字节数为也为0,放在00402107。如下
0030:004020F3 58 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 X...............
0030:00402103 00 00 00 00 00 00 00 00-00 04 00 00 00 90 00 00 ................
0030:00402113 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
004020F3经过XOR运算后为0,现在两个字符串都是空串,比较是自然相等。
拆解完毕。
shengzan@263.net