正常的检测点的解释及注册码的反推 (4千字)
:0046F6A7 0FB638 movzx edi, byte ptr [eax] ; eax->用户名:0046F6AA 0FAFFE imul edi, esi
:0046F6AD 03CF add ecx, edi
:0046F6AF 46 inc esi
:0046F6B0 40 inc eax
:0046F6B1 4A dec edx
:0046F6B2 75F3 jne 0046F6A7
; 上面这段代码将用户名进行累加:第1字符*1+第2字符*2+第3字符*3+......并存入ECX中。
:0046F6B4 8BC1 mov eax, ecx
:0046F6B6 B9E8030000 mov ecx, 000003E8 ====> 除以1000
:0046F6BB 99 cdq
:0046F6BC F7F9 idiv ecx
:0046F6BE 8955C8 mov dword ptr [ebp-38], edx ====> 余数存放此处
此时在SoftICE下用WF命令打开浮点寄存器
:0046F6C1 DB45C8 fild dword ptr [ebp-38] ====> ST0=余数值
:0046F6C4 DB2D44FF4600 fld tbyte ptr [0046FF44] ====> ST0=1E-3 ST1=余数值
:0046F6CA DEC9 fmulp st(1), st(0) ====> 将余数乘以1E-3
:0046F6CC D80550FF4600 fadd dword ptr [0046FF50] ====> 结果+1
:0046F6D2 DD5DF0 fstp qword ptr [ebp-10] ====> 存放到[ebp-10]处
:0046F6D5 9B wait
:0046F6D6 A13C1A4900 mov eax, dword ptr [00491A3C] ====> eax=BuildID
:0046F6DB 35010C0000 xor eax, 00000C01 ====> eax=序列号除以10000的余数
:0046F6E0 8945C8 mov dword ptr [ebp-38], eax ====> 存于此处
:0046F6E3 DB45C8 fild dword ptr [ebp-38] ====> ST0=余数值
:0046F6E6 DB2D54FF4600 fld tbyte ptr [0046FF54] ====> ST0=1E-4 ST1=余数值
:0046F6EC DEC9 fmulp st(1), st(0) ====> 余数乘以1E-4
:0046F6EE DD5DE8 fstp qword ptr [ebp-18] ====> 结果保存在[ebp-18]
:0046F6F1 9B wait
:0046F6F2 DD45E8 fld qword ptr [ebp-18] ====> ST0=[ebp-18],即注册码的余数除以10000(或乘以1E-4)
:0046F6F5 E8CE31F9FF call 004028C8 ====> 余数的COS值
:0046F6FA DD45F0 fld qword ptr [ebp-10] ====> ST0=由用户名生成的余数的计算值
:0046F6FD DC4DE8 fmul qword ptr [ebp-18] ====> 乘以[ebp-18]
:0046F700 DEE9 fsubp st(1), st(0) ====> 余数的COS值-刚才的乘积值
:0046F702 DD5DF8 fstp qword ptr [ebp-08] ====> 结果保存在[ebp-8]
:0046F705 9B wait
:0046F706 DD45F8 fld qword ptr [ebp-08]
:0046F709 D9E1 fabs
:0046F70B DB2D44FF4600 fld tbyte ptr [0046FF44] ====> ST0=1E-3,ST1=[ebp-8]
:0046F711 DED9 fcompp ====> ST0与ST1比较
:0046F713 DFE0 fstsw ax
:0046F715 9E sahf
:0046F716 7607 jbe 0046F71F ====> 小于等于则转
; 这里就是关键的检测点,不跳即可成功注册!
:0046F718 C605D8C2470001 mov byte ptr [0047C2D8], 01 ; 即将内存[0047C2D8]处置为1
; 上面这段代码有许多浮点运行指令,看不懂。哪位看得懂的,给解释一下。
:0046F71F B201 mov dl, 01
:0046F721 A1342C4400 mov eax, dword ptr [00442C34]
:0046F726 E8813EFDFF call 004435AC
:0046F72B A3580B4900 mov dword ptr [00490B58], eax
:0046F730 6A08 push 00000008
:0046F732 B9E0010000 mov ecx, 000001E0
:0046F737 BA80020000 mov edx, 00000280
:0046F73C A1580B4900 mov eax, dword ptr [00490B58]
:0046F741 E8D64DFDFF call 0044451C
:0046F746 B201 mov dl, 01
说明:0046F716 jbe 0046F71F处即为关键检测点,不跳即可成功注册。
从上面可以看出,比较的过程如下:
将用户名进行累加:第1字符*1+第2字符*2+第3字符*3+,结果除以1000,取余数,再除以1000,再加上1
序列号/10000的余数再除以10000的COS值-序列号的余数/10000*由用户名生成的余数的计算值的绝对值小于1E-3
下面开始反推:
如果用户名为robot,则执行到46F6B4时ecx=0x676,余数为28E(即654),654/1000+1=1.654
设序列号的余数值为x,则x*1.654=cos(x),则x=0.5236,0.5236*10000=5236,5236 mod 51=102
因此,注册码为:1025236
重新整理:用户名:robot 注册码:1025236,注册后运行程序,已经变为注册版了,破解成功
注:上面的方程求解是用MathCad求出的
