📄 lesson14061.htm
字号:
; 004020F3内就是N0P3X.KEY读出数据
<br>
:00401113 XOR BYTE PTR [EAX+004020F3],43
; 43h和N0P3X.KEY中读出的数据XOR <br>
:0040111A INC EAX
; EAX+1 <br>
:0040111B CMP BYTE PTR [EAX+004020F3],00
; 判断N0P3X.KEY中是否有内容 <br>
:00401122 JNZ 00401113
; <br>
:00401124 PUSH 004020F3
; PUSH刚才XOR的数据
<br>
:00401129 PUSH 004020FD
; PUSH要用来比较的数据,实际全是0
<br>
:0040112E CALL KERNEL32!lstrcmp
; 比较它们 <br>
:00401133 CMP EAX,00
; EAX=0则比较相等,注册成功
<br>
:00401136 JZ 0040113E
; <br>
:00401138 JMP 00401158
; 否则Unregistered
<br>
<br>
3) 我们分析上面代码后,得知N0P3X.KEY中的字符要和43H XOR结果为0,即可注册成功。43H的ASCII码是C.所以N0P3X.KEY内容是任意个数的:CCCCCCCCCC
</table>
</div>
<div id="KB4Parent" class="parent"> <span class="p9"><a href="#" onClick="expandIt('KB4'); return false">
4、习题四 答案</a></span></div>
<div id="KB4Child" class="child"> <span class="p9"> </span>
<table width="100%" cellspacing="0" align="center">
<tr bgcolor="#EFEFEF">
<td>
<blockquote><span class="p9">Mikl0的破解教程 <br>
目标:Kwazy_W's PacMe <br>
工具:SoftICE <br>
<br>
首先运行这个程序,正好看看这个程序在做什么.你会看到这样一个单词:UNREGISTERED!而且你有能改动它.下面还有两个按钮EXIT和CHECK.当你点击CHECK时,并没有什么事发生.至少你没有看到任何变化.所以应该知道它并不是通过name/serial来进行注册的.它一定是keyfile来保护的.在SOFTICE下试着设断CREATEFILEA.点击CHECK,SOFTICE会马上中断.然后直接键入
D EDX 来看看它想打开什么文件.你会看到数据窗口显示KwazyWeb.bit .按F11返回调用它的CALL. <br>
<br>
你会到这里: <br>
<br>
:004016D9 E81C010000
Call 004017FA <==你从这里出来 <br>
:004016DE 83F8FF
cmp eax, -01 <br>
:004016E1 7464
je 00401747 <br>
:004016E3 A344344000
mov dword ptr [00403444], eax <br>
:004016E8 6A00
push 00000000 <br>
:004016EA 6848344000
push 00403448 <br>
:004016EF 6A01
push 00000001 <br>
:004016F1 68FA344000
push 004034FA <br>
:004016F6 FF3544344000 push
dword ptr [00403444] <br>
:004016FC E811010000
Call Kernel32! ReadFile <br>
<br>
CALL的后面,EAX与-01比较,来确定这个文件是否存在.如果这个文件不存在就会跳走.所以,我们离开SOFTICE建立KwazyWeb.bit文件,然后再返回来,发现到JUMP语句时,显时NO
JUMP,这就证明我们的第一步已经成功了! <br>
<br>
后面有一个READFILE的CALL. push 00000001 这句是读入的几个字节 .
push dword ptr [00403444] 这句是贮存读入字节的缓冲区地址. <br>
<br>
来看看下面的代码: <br>
:00401701 0FB605FA344000 movzx eax,
byte ptr [004034FA] ;将读出的这个字节放入EAX <br>
:00401708 85C0
test eax, eax
;测试是否有内容 <br>
:0040170A 743B
je 00401747
;如果没有就跳 <br>
:0040170C 6A00
push 00000000
<br>
:0040170E 6848344000
push 00403448 <br>
:00401713 50
push eax <br>
:00401714 6888324000
push 00403288 <br>
:00401719 FF3544344000 push
dword ptr [00403444] <br>
:0040171F E8EE000000
Call Kernel32! ReadFile <br>
:00401724 E8D7F8FFFF
Call 00401000 <br>
<br>
这儿的程序使用了READFILE.但是现在这个读入的字节数是由第一次读入的字节值所决定的.然后存入403288(我第一个字节是'M',所以它将读入4DH个字节).
<br>
又调用READFILE.下面有一个CALL,那就追进去: <br>
<br>
:00401000 33C0
xor eax, eax <br>
:00401002 33D2
xor edx, edx <br>
:00401004 33C9
xor ecx, ecx <br>
:00401006 8A0DFA344000 mov
cl, byte ptr [004034FA] ;将第一次读出首字节读入CL <br>
:0040100C BE88324000
mov esi, 00403288 ;将第二次读出字节的地址读入ESI
<br>
:00401011 AC
lodsb
;将ESI的字节读入AL <br>
:00401012 03D0
add edx, eax
;再加上EDX <br>
:00401014 E2FB
loop 00401011
;这里的循环次数是由首字节的值决定的 <br>
:00401016 8815FB344000 mov
byte ptr [004034FB], dl ;把DL存起来 <br>
:0040101C C3
ret <br>
<br>
这就是根据它首字节的值进行的计算.然后将DL存起来以后使用.然后返回调用处. <br>
到这: <br>
<br>
:00401729 6A00
push 00000000 <br>
:0040172B 6848344000
push 00403448 <br>
:00401730 6A12
push 00000012 ;读下面的12(18)个字节 <br>
:00401732 68E8344000
push 004034E8 ;存在这儿 <br>
:00401737 FF3544344000 push
dword ptr [00403444] <br>
:0040173D E8D0000000
Call Kernel32! ReadFile ;开始读 <br>
:00401742 E882F9FFFF
Call 004010C9 ;一个可疑的CALL <br>
:00401747 FF3544344000 push
dword ptr [00403444] <br>
:0040174D E8A2000000
Call Kernel32! CloseHandle ;关闭文件 <br>
<br>
<br>
又一次调用READFILE.然后就读入下面的18个字节.读完后就关闭文件.所以401742处的CALL就很可疑. <br>
那么,我们就来看看: <br>
<br>
:004010C9 55
push ebp <br>
:004010CA 8BEC
mov ebp, esp <br>
:004010CC 83C4FC
add esp, FFFFFFFC <br>
:004010CF 6865334000
push 00403365 ;一个字符串 <br>
:004010D4 68BC314000
push 004031BC ;又一个字符串 <br>
:004010D9 E83A070000
Call Kernel32! lstrcpy ;复制它 <br>
:004010DE C70584314000CC314000 mov dword ptr [00403184],
004031CC ;存入 403184 <br>
:004010E8 E830FFFFFF
call 0040101D
;又一个CALL? <br>
<br>
键入 D 403365 和 D 4031BC 来看看这个字符串. 两个一样的字符串.但是它的下面有一些字符(UNREGISTERED!
Cracked by: )在字符串后你会看到一个字符'C'. <br>
这是另外一个CALL.按F8追进来: <br>
:0040101D 8A15FB344000 mov
dl, byte ptr [004034FB] ;现在重新读入DL <br>
:00401023 B912000000
mov ecx, 00000012 ;ecx是个计数器为12H(18)
<br>
:00401028 B8E8344000
mov eax, 004034E8 ;将12H读入EAX <br>
:0040102D 3010
xor byte ptr [eax], dl ;每个字节与DL做异或
<br>
:0040102F 40
inc eax
;EAX=EAX+1 <br>
:00401030 E2FB
loop 0040102D
;循环18次 <br>
:00401032 C3
ret <br>
<br>
DL中的值是与文件中的首字节为依据的.ECX是计数器(18次).EAX是读取18个字节的偏移量.所以,12H个字节每个都与DL做异或.
<br>
<br>
:004010ED C645FE00
mov [ebp-02], 00 ;ebp-02 =
0 <br>
:004010F1 33C0
xor eax, eax
;清零 <br>
:004010F3 33C9
xor ecx, ecx
;清零 <br>
:004010F5 C645FF08 主循环开始处->mov [ebp-01], 08
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -