屏幕录像专家 V3.0 算法分析
作者:PaulYoung[CCG]
软件下载:http://www.tlxsoft.com/
破解工具:SoftICE
破解时间:2003-4-8
***********************************************************************************************
你一定可以来到这里…… ^_^
:0041B862 8D45F8
lea eax, dword ptr [ebp-08]
:0041B865
E8B68FFEFF call 00404820
:0041B86A 50
push eax
:0041B86B 8D9580FBFFFF
lea edx, dword ptr [ebp+FFFFFB80]
:0041B871 52
push edx
:0041B872
E84D0C0700 call 0048C4C4
:0041B877 83C408
add esp, 00000008
:0041B87A FF4DBC
dec [ebp-44]
:0041B87D 8D45F8
lea eax, dword ptr [ebp-08]
:0041B880
BA02000000 mov edx, 00000002
:0041B885 E886C00700 call 00497910
:0041B88A 8D8D80FBFFFF lea ecx,
dword ptr [ebp+FFFFFB80]
:0041B890 51
push ecx
:0041B891 E85E0C0700
call 0048C4F4
:0041B896 59
pop ecx
:0041B897
89458C mov dword
ptr [ebp-74], eax
:0041B89A C745889CFFFFFF
mov [ebp-78], FFFFFF9C //[ebp-78]=0xFFFFFF9C
:0041B8A1 33C0
xor eax, eax
:0041B8A3 894590
mov dword ptr [ebp-70], eax
:0041B8A6 8B5590
mov edx, dword ptr [ebp-70]
:0041B8A9 3B558C
cmp edx, dword ptr [ebp-74]
:0041B8AC 7D20
jge 0041B8CE
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:0041B8CC(C)
|
:0041B8AE 8B4D90
mov ecx, dword ptr [ebp-70]
:0041B8B1 8A840D80FBFFFF mov al, byte ptr
[ebp+ecx-00000480]
:0041B8B8 884597
mov byte ptr [ebp-69], al
:0041B8BB 33D2
xor edx, edx
:0041B8BD
8A5597 mov dl, byte
ptr [ebp-69]
:0041B8C0 015588
add dword ptr [ebp-78], edx //0xFFFFFF9C 与用户名每个字符累加求和
:0041B8C3 FF4590
inc [ebp-70]
:0041B8C6 8B4D90
mov ecx, dword ptr [ebp-70]
:0041B8C9 3B4D8C
cmp ecx, dword ptr [ebp-74]
:0041B8CC
7CE0 jl 0041B8AE
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B8AC(C)
|
:0041B8CE 8B4588
mov eax, dword ptr [ebp-78]
:0041B8D1 898578F7FFFF
mov dword ptr [ebp+FFFFF778], eax
:0041B8D7
33D2 xor
edx, edx
:0041B8D9 89957CF7FFFF
mov dword ptr [ebp+FFFFF77C], edx
:0041B8DF DFAD78F7FFFF
fild qword ptr [ebp+FFFFF778] //累加和结果送
st(0)
:0041B8E5 DB2D5CBD4100 fld
tbyte ptr [0041BD5C] //st(1)=0.6480041472265422897
:0041B8EB DEC9
fmulp st(1), st(0)
//st(1)=st(0)*st(1)
:0041B8ED D80568BD4100 fadd dword ptr
[0041BD68] //加上1233.99999999999999957
:0041B8F3 E8F84F0700
call 004908F0
//取结果的整数
:0041B8F8 894588
mov dword ptr [ebp-78],
eax
:0041B8FB 8B5588
mov edx, dword ptr [ebp-78]
:0041B8FE 899578F7FFFF
mov dword ptr [ebp+FFFFF778], edx
:0041B904 33C9
xor ecx, ecx
:0041B906 898D7CF7FFFF mov dword ptr
[ebp+FFFFF77C], ecx
:0041B90C DFAD78F7FFFF
fild qword ptr [ebp+FFFFF778]
:0041B912 DC0D6CBD4100
fmul qword ptr [0041BD6C]
//上面的整数*3121.14159259999996697388632872504
:0041B918 E8D34F0700 call
004908F0
//取结果的整数
:0041B91D 894588
mov dword ptr [ebp-78], eax
//保存到[ebp-78]
:0041B920 66C745B02C00
mov [ebp-50], 002C
:0041B926 8D45F4
lea eax, dword ptr [ebp-0C]
:0041B929 E8065EFEFF
call 00401734
:0041B92E 8BD0
mov edx, eax
:0041B930 FF45BC
inc [ebp-44]
:0041B933 8B4D9C
mov ecx, dword ptr [ebp-64]
:0041B936 8B81E4020000
mov eax, dword ptr [ecx+000002E4]
:0041B93C E84B150400
call 0045CE8C
:0041B941 8D45F4
lea eax, dword ptr [ebp-0C]
:0041B944 E8D78EFEFF call
00404820
:0041B949 50
push eax
:0041B94A 8D9580FBFFFF
lea edx, dword ptr [ebp+FFFFFB80]
:0041B950 52
push edx
:0041B951 E86E0B0700 call
0048C4C4
:0041B956 83C408
add esp, 00000008
:0041B959 FF4DBC
dec [ebp-44]
:0041B95C 8D45F4
lea eax, dword ptr [ebp-0C]
:0041B95F BA02000000 mov edx,
00000002
:0041B964 E8A7BF0700
call 00497910
:0041B969 8D8D80FBFFFF
lea ecx, dword ptr [ebp+FFFFFB80]
:0041B96F 51
push ecx
:0041B970 E87F0B0700
call 0048C4F4
:0041B975 59
pop ecx
:0041B976 89458C
mov dword ptr [ebp-74], eax
:0041B979 33C0
xor eax, eax
:0041B97B 894590
mov dword ptr [ebp-70], eax
//[ebp-70]=eax=0
:0041B97E 8B5590
mov edx, dword ptr [ebp-70]
:0041B981
3B558C cmp edx,
dword ptr [ebp-74]
:0041B984 7D46
jge 0041B9CC
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:0041B9CA(C)
|
:0041B986 8B4590
mov eax, dword ptr [ebp-70]
//[ebp-70]依次等于 0,1,2,3...
:0041B989 B903000000
mov ecx, 00000003
:0041B98E 99
cdq
:0041B98F F7F9
idiv ecx
//[ebp-70]/3,商送 al
:0041B991 8B5590
mov edx, dword ptr [ebp-70]
:0041B994 8A8C1580FBFFFF mov cl, byte ptr [ebp+edx-00000480]
//依次取注册码各个字符
:0041B99B 80C1EC
add cl, EC
//字符+0xFFFFFFEC
:0041B99E 8B5590
mov edx, dword ptr [ebp-70]
//[ebp-70]=edx
:0041B9A1 81E201000080
and edx, 80000001 //取奇数位字符则edx=0,取偶数位字符则edx=1
:0041B9A7 7905
jns 0041B9AE
:0041B9A9 4A
dec edx
:0041B9AA 83CAFE
or edx, FFFFFFFE
:0041B9AD
42
inc edx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B9A7(C)
|
:0041B9AE 03D2
add edx, edx
:0041B9B0 8D1492
lea edx, dword ptr [edx+4*edx]
//奇数位字符则dl=0,偶数位字符则 dl=0xA
:0041B9B3 2ACA
sub cl, dl //cl=cl-dl(即计算奇数位字符时-0,计算偶数位字符时-0xA)
:0041B9B5 02C1
add al, cl //al=al+cl(al 就是[ebp-70]/3的商)
:0041B9B7 8B4D90
mov ecx, dword ptr [ebp-70]
:0041B9BA 88840D80FBFFFF mov byte ptr [ebp+ecx-00000480],
al
:0041B9C1 FF4590
inc [ebp-70]
//[ebp-70]递增1
:0041B9C4 8B4590
mov eax, dword ptr [ebp-70]
:0041B9C7 3B458C
cmp eax, dword ptr [ebp-74]
:0041B9CA 7CBA
jl 0041B986 //循环并分别用注册码各个字符计算出一串数值
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B984(C)
|
:0041B9CC 8D8580FBFFFF lea
eax, dword ptr [ebp+FFFFFB80]
:0041B9D2 50
push eax
:0041B9D3 8D9580F7FFFF
lea edx, dword ptr [ebp+FFFFF780]
:0041B9D9
52
push edx
:0041B9DA E8E50A0700
call 0048C4C4
:0041B9DF 83C408
add esp, 00000008
:0041B9E2 66C745B03800
mov [ebp-50], 0038
:0041B9E8 8D9580F7FFFF
lea edx, dword ptr [ebp+FFFFF780]
:0041B9EE 8D45F0
lea eax, dword ptr [ebp-10]
:0041B9F1 E8B2BD0700 call
004977A8
:0041B9F6 8BD0
mov edx, eax
:0041B9F8 FF45BC
inc [ebp-44]
:0041B9FB 8D45FC
lea eax, dword ptr [ebp-04]
:0041B9FE
E83DBF0700 call 00497940
:0041BA03 FF4DBC
dec [ebp-44]
:0041BA06 8D45F0
lea eax, dword ptr [ebp-10]
:0041BA09 BA02000000
mov edx, 00000002
:0041BA0E E8FDBE0700
call 00497910
:0041BA13 8D45FC
lea eax, dword ptr [ebp-04]
:0041BA16 E8F5C00700 call
00497B10 //验证注册码的“合法性”并计算出一个值送 eax ,跟入……
从0041BA16 → 00497B38
→ 00482057,来到……
:0048903C 53
push ebx
:0048903D 56
push esi
:0048903E
57
push edi
:0048903F 89C6
mov esi, eax
:00489041 50
push eax
:00489042 85C0
test eax, eax
:00489044
7473 je 004890B9
:00489046 31C0
xor eax, eax
:00489048 31DB
xor ebx, ebx
:0048904A BFCCCCCC0C
mov edi, 0CCCCCCC
下面是逐个验证注册码各个字符计算出的数值的“合法性”,实际上间接验证了输入注册码的“合法性”。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00489055(C)
|
:0048904F 8A1E
mov bl, byte ptr [esi]
:00489051 46
inc esi
:00489052 80FB20
cmp bl, 20
:00489055 74F8
je 0048904F
:00489057 B500
mov ch, 00
:00489059 80FB2D
cmp bl, 2D
:0048905C
7469 je 004890C7
:0048905E 80FB2B
cmp bl, 2B
:00489061 7466
je 004890C9
:00489063 80FB24
cmp bl, 24
:00489066 7466
je 004890CE
:00489068
80FB78 cmp bl, 78
:0048906B 7461
je 004890CE
:0048906D 80FB58
cmp bl, 58
:00489070 745C
je 004890CE
:00489072 80FB30
cmp bl, 30
:00489075
7513 jne
0048908A
:00489077 8A1E
mov bl, byte ptr [esi]
:00489079 46
inc esi
:0048907A 80FB78
cmp bl, 78
:0048907D
744F je 004890CE
:0048907F 80FB58
cmp bl, 58
:00489082 744A
je 004890CE
:00489084 84DB
test bl, bl
:00489086 7420
je 004890A8
:00489088 EB04
jmp 0048908E
* Referenced by a (U)nconditional or (C)onditional Jump
at Addresses:
|:00489075(C), :004890CC(U)
|
:0048908A 84DB
test bl, bl
:0048908C 7434
je 004890C2
* Referenced by a (U)nconditional or (C)onditional Jump
at Addresses:
|:00489088(U), :004890A6(C)
|
:0048908E 80EB30
sub bl, 30
:00489091
80FB09 cmp bl, 09
//关键,从中我们可以推算出各位注册码的取值范围
:00489094 772C
ja 004890C2 //跳???不要!!!
:00489096 39F8
cmp eax, edi
:00489098 7728
ja 004890C2
:0048909A 8D0480
lea eax, dword ptr [eax+4*eax]
:0048909D 01C0
add eax, eax
:0048909F 01D8
add eax, ebx //每次 "bl-30" 的值组成串再转换成数值
:004890A1
8A1E mov
bl, byte ptr [esi]
:004890A3 46
inc esi
:004890A4 84DB
test bl, bl
:004890A6 75E6
jne 0048908E
计算完毕,回到……
:0041BA1B B97C000000
mov ecx, 0000007C
:0041BA20 99
cdq
:0041BA21 F7F9
idiv ecx
:0041BA23
83C064 add eax,
00000064
:0041BA26 894584
mov dword ptr [ebp-7C], eax
:0041BA29 8B4584
mov eax, dword ptr [ebp-7C] //eax=eax/0x7C+0x64
:0041BA2C 2B4588
sub eax, dword ptr [ebp-78] //eax-用户名计算出的值
:0041BA2F 83F864
cmp eax, 00000064 //等于
0x64 则注册成功
:0041BA32 0F85BC020000
jne 0041BCF4
****************************
实例分析:
以用户名 PaulYoung 为例,
用户名计算:
0xFFFFFF9C+0x50+0x61+0x75+0x6C+0x59+0x6F0x75+0x6E+0x67=0x340=832
832*0.6480041472265422897+1233.99999999999999957结果的整数为1773
1773*3121.14159259999996697388632872504结果的整数为0x547058
注册码计算:
假设某位注册码字符为 S ,则
奇数位计算:S+0xFFFFFFEC+(x/3 的商) (x
依次等于0,1,2,3...)
偶数位计算:S+0xFFFFFFEC-0xA+(x/3 的商)
而从
:0048908E
80EB30 sub bl, 30
:00489091 80FB09
cmp bl, 09
:00489094 772C
ja 004890C2
我们可以看到,奇数位及偶数位注册码取值范围分别是:
奇数位范围:0x30≤S+0xFFFFFFEC+(x/3)≤0x39
偶数位范围:0x30≤S+0xFFFFFFEC-0xA+(x/3)≤0x39
由此我们可以推算出注册码的“合法”取值范围,分别是:
第一位:D,E,F,G,H,I,J,K,L,M
第二位:N,O,P,Q,R,S,T,U,V,W
第三位:D,E,F,G,H,I,J,K,L,M
第四位:M,N,O,P,Q,R,S,T,U,V
第五位:C,D,E,F,G,H,I,J,K,L
第六位:M,N,O,P,Q,R,S,T,U,V
第七位:B,C,D,E,F,G,H,I,J,K
第八位:L,M,N,O,P,Q,R,S,T,U
第九位:B,C,D,E,F,G,H,I,J,K
...
注册码计算出的值假设为 N ,(N/0x7C的商)+0x64-用户名计算出的值=0x64 ,满足条件则注册成功。
用 PaulYoung 计算出的值为 0x547058,则用 0x547058*0x7C 可以算出N=686189216 (DEC)
而686189216中每位数字实际是0048908E中算出的
bl 的值。
因此,我们可以逆推出注册码各个字符,如第一位注册码(假设为S),即
S+0xFFFFFFEC+0/3-0x30=6 ,则
S=0x4A='J'
也可这样理解,如第一位注册码:
0,1,2,3,4,5,6,7,8,9 对应
D,E,F,G,H,I,J,K,L,M
是6则取对应的J,其它同理……
依此类推,算出一个可用的注册码
Name:PaulYoung
Code:JVJNKVDMH
或
Name:CCG
Code:INGVCOBNF
另外,N/0x7C 只用到它的商,不同的 N 值都可以算出同样的商,因此,同一用户名其实可以有很多个可用的注册码。
____________________________________________________________________________________________
很久很久没玩破解了,基于个性的懒惰,分析可能并不全面,如有发现,请跟帖批评指正。希望我粗糙的文笔及蹩脚的表达能力不会令大家望而生厌……
:-)
PaulYoung
属于中国破解组织CCG(CHiNA CrACKiNG GrOUp)
- 标 题:屏幕录像专家 V3.0 算法分析 (13千字)
- 作 者:PaulYoung[CCG]
- 时 间:2003-4-8 21:20:22
- 链 接:http://bbs.pediy.com