Soundnailsd的破解教程(三) (7千字)
Soundnailsd的破解教程(三)④ 现在是我们要追近0167:00457FDB CALL 00457004时候了。
代码如下:
(略过与算码无关的代码).
: :
: :
: :
0167:00457047 MOV EBX,EAX
0167:00457049 FILD QWORD [EBP+08] ----> 这是一个装入整数指令.将EBP+08处存放的值
(这个值就是上一篇所说的那个EAX循环左移以后,
再与 A4529D37 进行异或,结果在EAX中的值),
装入协处理器堆栈寄存器st(0).
0167:0045704C FSTP TWORD [EBP-20] ----->这是存储和弹出实数的指令.将st(0)中的浮点数
复制到EBP-20所指的地方,再进行一次出栈操作.
0167:0045704F WAIT
0167:00457050 CMP DWORD [EBP+0C],BYTE +00
0167:00457054 JNZ 00457062
0167:00457056 CMP DWORD [EBP+08],BYTE +00
0167:0045705A JNC NEAR 004570EE
0167:00457060 JMP SHORT 00457068
0167:00457062 JNL NEAR 004570EE
0167:00457068 FLD TWORD [0047F0C8] ---->装入0047F0C8处所指的实数
0167:0045706E FADD DWORD [0045713C] ---->加法
0167:00457074 FMUL DWORD [00457140] ---->乘法
0167:0045707A FLD TWORD [EBP-20] ---->装入EBP-20所指的实数
0167:0045707D FADDP ST1 ---->加法并弹出
0167:0045707F FSTP TWORD [EBP-20]
0167:00457082 WAIT
0167:00457083 JMP SHORT 004570EE
0167:00457085 MOV AX,[EBP-18] ----->将浮点数的阶码部分和符号位送AX
0167:00457089 PUSH EAX
0167:0045708A PUSH DWORD [EBP-1C]----->将浮点数的32-63位入栈
0167:0045708D PUSH DWORD [EBP-20]----->将浮点数的0-31位入栈
0167:00457090 MOV [EBP-28],EBX ----->字符串长度1B送ebp-28所指处
0167:00457093 FILD DWORD [EBP-28]
0167:00457096 ADD ESP,BYTE -0C
0167:00457099 FSTP TWORD [ESP] ---->0000001B的浮点形式.
0167:0045709C WAIT
0167:0045709D CALL 00456FA4 ---->运算,计算出下面EAX的浮点形式
0167:004570A2 FSTP TWORD [EBP-10]
0167:004570A5 WAIT
0167:004570A6 FLD TWORD [EBP-10]
0167:004570A9 CALL 00402A08 ----->决定eax的值.后面将介绍到
0167:004570AE ADD EAX,BYTE +01
0167:004570B1 ADC EDX,BYTE +00
0167:004570B4 MOV EDX,[EBP-04] ----->EBP-04出存放的是指向"M65DCBEL2NZPT8RW34HXK71Y9AF"
的指针.
0167:004570B7 MOV DL,[EDX+EAX-01] ---->将EDX+EAX-01指向的字符送DL,这就是注册码的其中一位,
可以看出是由EAX来定位注册码的.是从后到前来定位的,
即先定位最后一位注册码,再定位到数第二位注册码.......
0167:004570BB LEA EAX,[EBP-2C]
0167:004570BE CALL 00403D34
0167:004570C3 MOV EDX,[EBP-2C]
0167:004570C6 LEA EAX,[EBP-24]
0167:004570C9 MOV ECX,[EBP-24]
0167:004570CC CALL 00403E58
0167:004570D1 MOV [EBP-28],EBX ----->字符串长度1B送ebp-28所指处
0167:004570D4 FILD DWORD [EBP-28]------> 装入整数0000001B
0167:004570D7 FLD TWORD [EBP-20]------>装入EBP-20所指的实数.
0167:004570DA FDIVRP ST1 ----->反向除法,并弹出
0167:004570DC CALL 00402A14
0167:004570E1 MOV [EBP-34],EAX
0167:004570E4 MOV [EBP-30],EDX
0167:004570E7 FILD QWORD [EBP-34] ---->装入整数,除法的商.
0167:004570EA FSTP TWORD [EBP-20] ---->存储除法的商的浮点形式到EBP-20所指处,再进行一次出栈操作.
0167:004570ED WAIT
0167:004570EE FLD TWORD [EBP-20] ---->装入EBP-20所指处的实数
0167:004570F1 FCOMP DWORD [00457144]-->比较并弹出
0167:004570F7 FNSTSW AX ------>将状态寄存器的值复制到AX
0167:004570F9 SAHF ------>将AH寄存器的第7,6,4,2,0位分别送入到
SF,ZF,AF,PF,CF
0167:004570FA JNZ 00457085 ---->ZF=0则循环
0167:004570FC MOV EAX,ESI
: :
: :
: :(略过一部分)
: :
上面这一段的大体流程是这样的(只说重点的),
这一步0167:00457085 MOV AX,[EBP-18] ,将浮点数的阶码部分和符号位送AX,第一次的浮点数就是那个
上一篇所说的那个EAX循环左移以后,再与 A4529D37 进行异或,结果在EAX中的值的浮点形式.
接下来的0167:0045708A PUSH DWORD [EBP-1C] 和 0167:0045708D PUSH DWORD [EBP-20]是分别将
浮点数的32-63位入栈 和 将浮点数的0-31位入栈.
接下来是经过0167:0045709D CALL 00456FA4这个call,在这个CALL里,浮点数与字符串长度0000001B的
浮点形式进行一系列运算,最终得到一个值,这个值就是后面的EAX的浮点形式.(代码见后)
再下来经过0167:004570A9 CALL 00402A08,这个CALL将上面得到的那个值,以整数存放到当前堆栈指针
所指处,然后将此整数弹到EAX中. (代码见后)
继续往下,EAX+1, 再往下 ,0167:004570B7 MOV DL,[EDX+EAX-01] 这一步通过EAX的值来定位注册码的
取值.
再往下,有一个反向除法,商就是另一次循环的初始的浮点数. 对了,要注意操作数的宽度.
循环 ,直到ZF=1
流程就是这样的了.下面是0167:0045709D CALL 00456FA4和0167:004570A9 CALL 00402A08代码.
0167:0045709D CALL 00456FA4
代码如下:
0167:00456FA4 PUSH EBP
0167:00456FA5 MOV EBP,ESP
0167:00456FA7 ADD ESP,BYTE -20
0167:00456FAA FLD TWORD [EBP+14]------->装入EBP-14所指的实数.
0167:00456FAD FLD TWORD [EBP+08]------->装入EBP+08所指的实数.0000001B的浮点形式.
0167:00456FB0 FDIVP ST1,ST0 --------->除法并弹出
0167:00456FB2 CALL 004029F0
0167:00456FB7 FLD TWORD [EBP+08]------->装入EBP-08所指的实数
0167:00456FBA FMULP ST1 --------->乘法并弹出
0167:00456FBC FLD TWORD [EBP+14]
0167:00456FBF FSUBRP ST1 --------->反向减法并弹出
0167:00456FC1 FSTP TWORD [EBP-20] ------>存储实数到ebp-20所指处,再进行一次出栈操作
0167:00456FC4 WAIT
0167:00456FC5 FLD TWORD [EBP-20]
0167:00456FC8 FCOMP DWORD [00456FFC] ---->比较并弹出
0167:00456FCE FNSTSW AX ----->将状态寄存器的值复制到AX
0167:00456FD0 SAHF ------>将AH寄存器的第7,6,4,2,0位分别送入到
SF,ZF,AF,PF,CF
0167:00456FD1 JNC 00456FDF
0167:00456FD3 FLD TWORD [EBP-20]
0167:00456FD6 FLD TWORD [EBP+08]
0167:00456FD9 FADDP ST1 ------->加法并弹出.
0167:00456FDB FSTP TWORD [EBP-20] -->存储实数到EBP-20所指处.再进行一次出栈操作
0167:00456FDE WAIT
0167:00456FDF MOV EAX,[EBP-20] ──┐
0167:00456FE2 MOV [EBP-10],EAX │
0167:00456FE5 MOV EAX,[EBP-1C] │
0167:00456FE8 MOV [EBP-0C],EAX │-->这一段将ebp-20所指的实数复制到ebp-10所指处.
0167:00456FEB MOV AX,[EBP-18] │
0167:00456FEF MOV [EBP-08],AX ──┘
0167:00456FF3 FLD TWORD [EBP-10] ---->装入EBP-10所指的实数.
0167:00456FF6 MOV ESP,EBP
0167:00456FF8 POP EBP
0167:00456FF9 RET 18
0167:004570A9 CALL 00402A08
代码如下:
0167:00402A08 SUB ESP,BYTE +08
0167:00402A0B FISTP QWORD [ESP] ---->存储整数.再进行一次出栈操作.
0167:00402A0E WAIT
0167:00402A0F POP EAX ------>将整数弹到EAX.
0167:00402A10 POP EDX
0167:00402A11 RET
好了,就写到这里吧 .
破解勇[CCG]
