老文章档案 · 2003 年

SpamKiller2.90的算法分析

破解教程 · 算法分析 · 2003-06-29 · 作者:xuzhenhu 人气: · 出处:嬴政天下整理收藏)

SpamKiller2.90版的算法分析

作者:Batman

0167:00498109 CALL 00404068

0167:0049810E MOV [EBP-0C],EAX

0167:00498111 CMP DWORD PTR [EBP-0C],10 // 比较注册码是否是16位

0167:00498115 JNZ 00498372 // 不是就跳转出错(不能跳)

0167:0049811B MOV EAX,[EBP-04]

0167:0049811E CMP BYTE PTR [EAX+04],2D // 比较注册码第五位是否是“-”

0167:00498122 JNZ 00498372 // 不是就跳转出错(不能跳)

0167:00498128 MOV EAX,[EBP-04]

0167:0049812B CMP BYTE PTR [EAX+09],2D // 比较注册码第十位是否是“-”

0167:0049812F JNZ 00498372 // 不是就跳转出错(不能跳)

0167:00498135 MOV EBX,00000011

0167:0049813A MOV ESI,004EF4DC

0167:0049813F LEA EDX,[EBP-14]

0167:00498142 MOV EAX,[ESI]

0167:00498144 CALL 00487CE4

0167:00498149 MOV EDX,[EBP-14]

0167:0049814C MOV EAX,[EBP-04]

0167:0049814F CALL 00404178 // 比较注册码是否是“003E-9124-7E3E39”(黑名单)

0167:00498154 JZ 00498372 // 是就跳转出错(不能跳)

0167:0049815A ADD ESI,04

0167:0049815D DEC EBX

0167:0049815E JNZ 0049813F // 反复跳转数次

0167:00498160 XOR EDX,EDX

0167:00498162 PUSH EBP

0167:00498163 PUSH 00498368

0167:00498168 PUSH DWORD PTR FS:[EDX]

0167:0049816B MOV FS:[EDX],ESP

0167:0049816E MOV EBX,00000001

0167:00498173 JMP 00498191 // 向下跳转

0167:00498175 MOV EAX,[EBP-04]

0167:00498178 CMP BYTE PTR [EBX+EAX-01],2D

0167:0049817D JNZ 00498190

0167:0049817F LEA EAX,[EBP-04]

0167:00498182 MOV ECX,00000001

0167:00498187 MOV EDX,EBX

0167:00498189 CALL 004042B0 // 这里的CALL去除注册码中的“-”

0167:0049818E JMP 00498191

0167:00498190 INC EBX

0167:00498191 MOV EAX,[EBP-04] // 跳到这里

0167:00498194 CALL 00404068

0167:00498199 CMP EBX,EAX

0167:0049819B JLE 00498175 // 反复跳转数次,以去除注册码中的“-”

0167:0049819D MOV EAX,[EBP-04]

0167:004981A0 CALL 00404068

0167:004981A5 MOV [EBP-0C],EAX

0167:004981A8 CMP DWORD PTR [EBP-0C],0E // 比较去除“-”后的注册码是否是14位

0167:004981AC JZ 004981BB // 是就跳转(要跳)

0167:004981AE XOR EAX,EAX

0167:004981B0 POP EDX

0167:004981B1 POP ECX

0167:004981B2 POP ECX

0167:004981B3 MOV FS:[EAX],EDX

0167:004981B6 JMP 00498372

0167:004981BB XOR ECX,ECX // 跳到这里,ECX清零(即ECX=0)

0167:004981BD MOV EAX,[EBP-0C] // 将注册码的位数(即14)送给EAX(已去除“-”)

0167:004981C0 DEC EAX // EAX=14-1=13

0167:004981C1 TEST EAX,EAX // 测试EAX

0167:004981C3 JLE 004981D8

0167:004981C5 MOV EBX,00000001 // 将01送给EBX(即EBX=01

0167:004981CA MOV EDX,[EBP-04] // 将去除“-”的注册码送给EDX

0167:004981CD MOVZX EDX,BYTE PTR [EBX+EDX-01] // 依次注册码字符的十六进制值给EDX

0167:004981D2 ADD ECX,EDX // ECX=ECX+EDX ,将注册码的前13位字符的十六进制值相加,结果存入ECX

0167:004981D4 INC EBX // EBX加1

0167:004981D5 DEC EAX // EAX-1

0167:004981D6 JNZ 004981CA // 不相等则跳(反复跳转13次,也就是将注册码的前13位字符的十六进制值相加,结果存入ECX)

0167:004981D8 MOV EAX,ECX // 将注册码的前13位字符的十六进制值相加的值送给EAX

0167:004981DA MOV ECX,0000000A // ECX=0A

0167:004981DF CDQ

0167:004981E0 IDIV ECX // EAX除以ECX,余数放入DL

0167:004981E2 ADD DL,30 // DL=DL(即余数)+30

0167:004981E5 MOV EAX,[EBP-04]

0167:004981E8 MOV ECX,[EBP-0C]

0167:004981EB CMP DL,[ECX+EAX-01] // 比较DL中的字符与注册码的最后一位是否相等

0167:004981EF JNZ 0049835E // 不相等就跳转出错(不能跳)

0167:004981F5 XOR ECX,ECX //ECX=0

0167:004981F7 MOV EBX,00000001 // EBX=1

0167:004981FC MOV EAX,[EBP-04] // 将去除“-”的注册码送给EAX

0167:004981FF MOVZX EAX,BYTE PTR [EBX+EAX-01] // 依次注册码字符的十六进制值给EAX

0167:00498204 ADD ECX,EAX // ECX=ECX+EAX ,将注册码的前5位字符的十六进制值相加,结果存入ECX

0167:00498206 INC EBX // EBX加1

0167:00498207 CMP EBX,06 // 比较EBX与6是否相等

0167:0049820A JNZ 004981FC // 不相等则跳(反复跳转5次,也就是将注册码的前5位字符的十六进制值相加,结果存入ECX)

0167:0049820C MOV EAX,ECX // 将注册码的前5位字符的十六进制值相加的值送给EAX

0167:0049820E MOV ECX,0000000A // ECX=0A

0167:00498213 CDQ

0167:00498214 IDIV ECX // EAX除以ECX,余数放入DL

0167:00498216 ADD DL,30 // DL=DL(即余数)+30

0167:00498219 MOV EAX,[EBP-04]

0167:0049821C MOV ECX,[EBP-0C]

0167:0049821F CMP DL,[ECX+EAX-02] // 比较DL中的字符与注册码的最后第二位是否相等

0167:00498223 JNZ 0049835E // 不相等就跳转出错(不能跳)

0167:00498229 LEA EAX,[EBP-1C]

0167:0049822C PUSH EAX

0167:0049822D MOV ECX,00000003

0167:00498232 MOV EDX,00000006

0167:00498237 MOV EAX,[EBP-04]

0167:0049823A CALL 00404270

0167:0049823F MOV ECX,[EBP-1C]

0167:00498242 LEA EAX,[EBP-18]

0167:00498245 MOV EDX,004983BC

0167:0049824A CALL 004040B4

0167:0049824F MOV EAX,[EBP-18]

0167:00498252 CALL 00409878 // EAX中的是去掉“-”后注册码的第6、7、8位注册码组成的字符(如注册码是1234,那么EAX=1234)

0167:00498257 MOV EBX,EAX // 将这些字符给EBX

0167:00498259 MOV CX,0012

0167:0049825D MOV DX,000C

0167:00498261 MOV AX,07CC

0167:00498265 CALL 0040A9CC

0167:0049826A CALL 00402B18

0167:0049826F ADD EBX,EAX // EAX=8A59,EBX=去掉“-”后注册码的第6、7、8位注册码组成的字符 + 8A59

0167:00498271 MOV CX,0001

0167:00498275 MOV DX,000A

0167:00498279 MOV AX,07CD

0167:0049827D CALL 0040A9CC // 下面要在SoftICE中下“WF”指令打开浮点窗口

0167:00498282 MOV [EBP-20],EBX // 将所得的值送给[EBP-20]

0167:00498285 FILD DWORD PTR [EBP-20] // 将该值的十进制值放入浮点寄存器ST0,这里原ST0中的值35704将移到ST1

0167:00498288 FCOMPP // ST0与ST1中的值相比较

0167:0049828A FSTSW AX

0167:0049828C SAHF

0167:0049828D JBE 0049835E // 小于、等于35704则跳转(不能跳)

0167:00498293 MOV CX,0001

0167:00498297 MOV DX,0001

0167:0049829B MOV AX,07DA

0167:0049829F CALL 0040A9CC

0167:004982A4 MOV [EBP-24],EBX // 将所得的值送给[EBP-20]

0167:004982A7 FILD DWORD PTR [EBP-24] // 将该值的十进制值放入浮点寄存器ST0,这里原ST0中的值40179将移到ST1

0167:004982AA FCOMPP // ST0与ST1中的值相比较

0167:004982AC FSTSW AX

0167:004982AE SAHF

0167:004982AF JAE 0049835E // 大于、等于40179则跳转(不能跳)

0167:004982B5 LEA EAX,[EBP-2C]

0167:004982B8 PUSH EAX

0167:004982B9 MOV ECX,00000004

0167:004982BE MOV EDX,00000009

0167:004982C3 MOV EAX,[EBP-04]

0167:004982C6 CALL 00404270

0167:004982CB MOV ECX,[EBP-2C]

0167:004982CE LEA EAX,[EBP-28]

0167:004982D1 MOV EDX,004983BC

0167:004982D6 CALL 004040B4

0167:004982DB MOV EAX,[EBP-28] // 将去除“-”的注册码的第9,10,11,12位的字符给EAX(如注册码是1234,那么EAX=1234)

0167:004982DE CALL 00409878

0167:004982E3 PUSH EAX

0167:004982E4 MOV EAX,000081FA // EAX=81FA

0167:004982E9 POP EDX // EDX就是注册码的第9,10,11,12位的字符

0167:004982EA SUB EAX,EDX // EAX减去EDX,值放入EAX

0167:004982EC CMP EAX,01 比较EAX是否小于己于1

0167:004982EF JL 0049835E // 小于就跳转(不能跳)

0167:004982F1 CMP EAX,00002710 // 比较EAX是否大于2710

0167:004982F6 JG 0049835E // 大于就跳转(不能跳)

0167:004982F8 LEA EAX,[EBP-34]

0167:004982FB PUSH EAX

0167:004982FC MOV ECX,00000005

0167:00498301 MOV EDX,00000001

0167:00498306 MOV EAX,[EBP-04]

0167:00498309 CALL 00404270

0167:0049830E MOV ECX,[EBP-34] // 将去除“-”的注册码的第1,2,3,4,5位的字符给EAX(如注册码是12345,那么EAX=12345)

0167:00498311 LEA EAX,[EBP-30]

0167:00498314 MOV EDX,004983BC

0167:00498319 CALL 004040B4

0167:0049831E MOV EAX,[EBP-30]

0167:00498321 CALL 00409878

0167:00498326 MOV EBX,EAX // EBX=注册码的第1,2,3,4,5位的字符

0167:00498328 MOV EAX,EBX // EAX=注册码的第1,2,3,4,5位的字符

0167:0049832A MOV ECX,000003E8 // ECX=03E8

0167:0049832F CDQ

0167:00498330 IDIV ECX // EAX除以ECX,商放入EAX

0167:00498332 MOV ECX,EAX // 将商送给ECX

0167:00498334 MOV EAX,EBX // EAX=注册码的第1,2,3,4,5位的字符

0167:00498336 MOV EBX,000003E8 // ECX=03E8

0167:0049833B CDQ

0167:0049833C IDIV EBX // EAX除以EBX,余数放入EDX

0167:0049833E MOV EAX,EDX // 将余数送给EAX

0167:00498340 DEC ECX // ECX减1

0167:00498341 SUB ECX,45 // ECX减去45

0167:00498344 JB 0049834E // 有进位则跳

0167:00498346 ADD ECX,-0A

0167:00498349 SUB ECX,0C

0167:0049834C JAE 0049835E

0167:0049834E CMP EAX,64 // 比较余数是否小于或等于64

0167:00498351 JLE 0049835A // 是就跳转(可以跳转)

0167:00498353 CMP EAX,000003E7 // 比较余数是否等于03E7

0167:00498358 JNZ 0049835E // 不相等就跳(不能跳)

0167:0049835A MOV BYTE PTR [EBP-05],01 // 这里是关键,前面比较有错误将不经过这行,[EBP-05]=1

0167:0049835E XOR EAX,EAX // EAX=0

0167:00498360 POP EDX

0167:00498361 POP ECX

0167:00498362 POP ECX

0167:00498363 MOV FS:[EAX],EDX

0167:00498366 JMP 00498372 // 这里跳转

0167:00498368 JMP 0040352C

0167:0049836D CALL 00403888

0167:00498372 XOR EAX,EAX // 跳到这里,EAX=0

0167:00498374 POP EDX

0167:00498375 POP ECX

0167:00498376 POP ECX

0167:00498377 MOV FS:[EAX],EDX

0167:0049837A PUSH 004983A9

0167:0049837F LEA EAX,[EBP-34]

0167:00498382 MOV EDX,00000004

0167:00498387 CALL 00403E0C

0167:0049838C LEA EAX,[EBP-1C]

0167:0049838F MOV EDX,00000004

0167:00498394 CALL 00403E0C

0167:00498399 LEA EAX,[EBP-04]

0167:0049839C CALL 00403DE8

0167:004983A1 RET // 按F10一下,跳到下面

0167:004983A2 JMP 004037E0

0167:004983A7 JMP 0049837F

0167:004983A9 MOV AL,[EBP-05] // 跳到这里,AL=[EBP-05],如经过了上面的关键行,那么EAX=1(注册成功),否则EAX=0(注册失败)。

0167:004983AC POP EDI

0167:004983AD POP ESI

0167:004983AE POP EBX

0167:004983AF MOV ESP,EBP

0167:004983B1 POP EBP

0167:004983B2 RET

【算法总结】

1.注册码必须是16位,并且第五、第十位必须是“-”;

2.注册码不能与“003E-9124-7E3E39”相同;

3.去掉“-”后注册码的位数必须是14位,即注册码中除了第5,10位外,不能再出现“-”;

4.将去掉“-”后注册码的前13位字符的十六进制值相加,再除于“0A”后的余数加上30(十六进制)所得的十六进制值相对应的字符就是最后一位注册码;

5.将去掉“-”后注册码的前5位字符的十六进制值相加,再除于“0A”后的余数加上30所得的十六进制值相对应的字符就是最后第二位注册码;

6.去掉“-”后注册码的第6、7、8位注册码组成的字符,加上“8A59”后所得的值的十进制值要大于“35704”,但要小于“40179”;

7.“81FA”减去去掉“-”后注册码的第9、10、11、12位注册码组成的字符的差要大于或等于1,但小于2710;

8.将去掉“-”后注册码的前5位所组成的字符除于“03E8”,商要小于等于“45”,余数要么小于或等于“64”,要么等于“03E7”;

9.注册码与用户名、公司名无关。(出处:嬴政天下整理收藏)

相关文章:

·语音界面2.0算法分析及注册机源码!

·侠客系统修改器1.21破解手记--算法分析

·中文拨号上网计时计费器 V4.12注册算法分析

·ClockWise 3.22e注册码算法分析

·CoolClock V1.02注册算法分析

·Directory Scanner v1.5 注册算法分析

·Disk Chief 1.2 简单注册算法分析

·EffeTech HTTP Sniffer 3.2注册算法分析

·eLib2.01算法分析

·EZ MP3 Recorder 1.15 注册算法分析

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史