各位大哥,看看我的演算法分析是否正確? (11千字)
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.註冊碼與使用者名稱、公司名無關。
相關文章
- 看執行計劃是否正確2011-10-05
- 演算法分析的正確姿勢2016-05-08演算法
- 請教各位大哥,小弟是一名菜鳥,想對公司下面的專案採取如下的分層方式,各位大哥,看看我的想法對不對2006-10-01
- 各位大哥,banq大哥請進,有關jdon版的安裝2003-11-09
- 請教板橋大哥及各位高手,這個case是否能用Jdon框架2006-02-17框架
- Dijkstra演算法及正確性分析2018-04-11演算法
- 檔案路徑是否正確2024-08-03
- benq,漿糊,以及各位大哥,你們是否用javamail做過收郵件的程式???2003-01-04ENQJavaAI
- LongTree的正確分析理解2005-01-04
- HappyEO演算法分析
(11千字)2015-11-15APP演算法
- 請教banq老師和各位大哥,以下需求應該怎麼分析2010-06-20
- js檢查身份證號是否正確2019-01-21JS
- python 詭異問題求助各位大哥2020-08-11Python
- MySQL如何計算重要的指標,來確定配置是否正確2018-07-02MySql指標
- Fpc大哥crackme的破解。 (4千字)2001-09-22
- 程式設計師正確看程式碼的方式2020-09-25程式設計師
- 看世界盃,漫步ASProtect
----- ASProtect的加密演算法初步分析 (5千字)2002-06-07加密演算法
- 看看一段工廠模式的程式碼是否正確?2002-10-10模式
- 小弟想做個交友的網站,各位大哥給點意見,2006-10-13網站
- 從 Android 靜音看正確的查bug的姿勢?2016-02-23Android
- appium 如何檢測頁面文案是否正確2020-12-03APP
- js判斷時間格式是否正確程式碼2017-03-14JS
- 學演算法的看過來 》》》演算法分析:
<獻給初學者> 之五 (5千字)2002-06-07演算法
- 程式設計師玩連連看的正確姿勢2018-05-30程式設計師
- banq大哥、各位好心的大哥大姐們!求教一個關於Sturts+Spring中ActionForm的問題2007-08-04SpringORM
- 各位大哥,jboss配置資料來源的問題,幫幫忙!2004-03-29
- 小弟請求各位師兄大哥一個面試遇到的問題2007-09-04面試
- 請各位大佬幫忙看看我的 Page Object 模式用的對不對2020-11-27Object模式
- 正確使用Android效能分析工具——TraceView2014-10-28AndroidView
- 飄雪動畫秀3.02註冊演算法分析!
(11千字)2015-11-15動畫演算法
- 各位 PHPer,Serverless 正當時2022-01-20PHPServer
- 各位大哥,幫忙解決一下這個問題2010-12-14
- 演算法題:如何判斷計算的 π 值是否精確?2014-05-12演算法
- PHP判斷電子郵件是否正確的簡單方法介紹2018-12-13PHP
- go的github.com/prometheus如何在單測中校驗值是否正確2024-08-20GoGithubPrometheus
- “5Why分析法”的正確使用姿勢2022-07-18
- 請寫一個函式驗證電子郵件的格式是否正確(要求使用正則)2024-04-11函式
- 加入設計模式後事務遇到的迷惑,還請各位大哥解難2005-03-09設計模式