浮點運算:程式碼管理器 (28千字)
Software:VB程式碼管理器
內製一個AddIn的程式碼格式化的程式等
Tools:TRW2000、OllyDbg V1.09、MASM32 V8
Cracker:lq7972[bruceyu13@sina.com]
Notes:學習~,§浮點指令§
這是個VB軟體,大家知道VB的字串用寬字元處理,這裡用上了浮點運算
【尋找註冊演算法】
要把VB的執行庫複製到TRW2000的DLL目錄,以便裝載、攔截
**TRW不顯示浮點堆疊,我沒有用fpu外掛--用OllyDbg~幸好沒殼**
我這裡只裝載了VB6執行庫,斷點不需要字首:“__vbastrcomp”
0167:0049D000 FF1540114000 CALL `MSVBVM60!__vbaStrCmp`
0167:0049D006 8BD8 MOV EBX,EAX
0167:0049D008 8D4DE8 LEA ECX,[EBP-18]
0167:0049D00B F7DB NEG EBX
0167:0049D00D 1BDB SBB EBX,EBX
0167:0049D00F 43 INC EBX
0167:0049D010 F7DB NEG EBX
0167:0049D012 FF1500134000 CALL `MSVBVM60!__vbaFreeStr`
0167:0049D018 8D4DD8 LEA ECX,[EBP-28]
0167:0049D01B FF15FC124000 CALL `MSVBVM60!__vbaFreeObj`
0167:0049D021 663BDF CMP BX,DI ;比較是否輸入了使用者名稱
0167:0049D024 7448 JZ 0049D06E ;跳
;……
;省略N行
0167:0049D062 C7458CB08D4100 MOV DWORD [EBP-74],00418DB0
0167:0049D069 E9DC030000 JMP 0049D44A
0167:0049D06E 8B06 MOV EAX,[ESI] ;在這裡了
0167:0049D070 56 PUSH ESI
0167:0049D071 FF900C030000 CALL NEAR [EAX+030C]
;……
;再省去N行
0167:0049D0DC 53 PUSH EBX
0167:0049D0DD 50 PUSH EAX
0167:0049D0DE FF1598104000 CALL `MSVBVM60!__vbaHresultCheckObj`
0167:0049D0E4 8B55E4 MOV EDX,[EBP-1C] ;使用者名稱
0167:0049D0E7 8B1DB4124000 MOV EBX,[004012B4]
0167:0049D0ED 8D4DE0 LEA ECX,[EBP-20]
0167:0049D0F0 897DE4 MOV [EBP-1C],EDI
0167:0049D0F3 FFD3 CALL EBX ;移動使用者名稱到某個地址
0167:0049D0F5 8B55E8 MOV EDX,[EBP-18] ;假碼
;先執行一下注冊,在到這裡看看:接著就有真碼啦
0167:0049D0F8 8D45E0 LEA EAX,[EBP-20] ;使用者名稱地址
0167:0049D0FB 52 PUSH EDX
0167:0049D0FC 50 PUSH EAX
0167:0049D0FD E88E0E0000 CALL 0049DF90 ;想想,是時候【跟進】了
0167:0049D102 8BD0 MOV EDX,EAX
0167:0049D104 8D4DDC LEA ECX,[EBP-24]
0167:0049D107 FFD3 CALL EBX
0167:0049D109 50 PUSH EAX
0167:0049D10A FF1540114000 CALL `MSVBVM60!__vbaStrCmp`
0167:0049D110 8BF8 MOV EDI,EAX
0167:0049D112 8D4DDC LEA ECX,[EBP-24]
;【跟進】
0167:0049DF90 55 PUSH EBP
0167:0049DF91 8BEC MOV EBP,ESP
0167:0049DF93 83EC18 SUB ESP,BYTE +18
0167:0049DF96 6836454000 PUSH DWORD 00404536
0167:0049DF9B 64A100000000 MOV EAX,[FS:00]
0167:0049DFA1 50 PUSH EAX
0167:0049DFA2 64892500000000 MOV [FS:00],ESP
0167:0049DFA9 B8A0000000 MOV EAX,A0
0167:0049DFAE E87D65F6FF CALL `MSVBVM60!__vbaChkstk`
0167:0049DFB3 53 PUSH EBX
0167:0049DFB4 56 PUSH ESI
0167:0049DFB5 57 PUSH EDI
0167:0049DFB6 8965E8 MOV [EBP-18],ESP
0167:0049DFB9 C745EC60434000 MOV DWORD [EBP-14],00404360 ;**
0167:0049DFC0 C745F000000000 MOV DWORD [EBP-10],00 ;**
0167:0049DFC7 C745F400000000 MOV DWORD [EBP-0C],00 ;**
0167:0049DFCE C745FC01000000 MOV DWORD [EBP-04],01 ;**
0167:0049DFD5 C745FC02000000 MOV DWORD [EBP-04],02 ;**
0167:0049DFDC 6AFF PUSH BYTE -01
0167:0049DFDE FF15D0104000 CALL `MSVBVM60!__vbaOnError`
0167:0049DFE4 C745FC03000000 MOV DWORD [EBP-04],03
;*********************************************************************把你的眼球弄到這兒吧
0167:0049DFEB 8B4508 MOV EAX,[EBP+08] ;使用者名稱地址
0167:0049DFEE 8B08 MOV ECX,[EAX]
0167:0049DFF0 51 PUSH ECX
0167:0049DFF1 6870264100 PUSH DWORD 00412670
0167:0049DFF6 FF1540114000 CALL `MSVBVM60!__vbaStrCmp` ;使用者名稱輸入了嗎?
0167:0049DFFC 85C0 TEST EAX,EAX
0167:0049DFFE 0F8417010000 JZ NEAR 0049E11B ;不要走喔
0167:0049E004 C745FC04000000 MOV DWORD [EBP-04],04
0167:0049E00B 8B5508 MOV EDX,[EBP+08]
0167:0049E00E 8B02 MOV EAX,[EDX]
0167:0049E010 50 PUSH EAX
0167:0049E011 FF153C104000 CALL `MSVBVM60!__vbaLenBstr` ;使用者名稱長度,返回eax
0167:0049E017 8945C8 MOV [EBP-38],EAX
0167:0049E01A C745FC05000000 MOV DWORD [EBP-04],05
0167:0049E021 8B4DC8 MOV ECX,[EBP-38]
0167:0049E024 FF1554114000 CALL `MSVBVM60!__vbaI2I4`
0167:0049E02A 66898578FFFFFF MOV [EBP+FFFFFF78],AX ;使用者名稱長度,要特別注意這些變數
0167:0049E031 66C7857CFFFFFF01+MOV WORD [EBP+FFFFFF7C],01 ;**
0167:0049E03A 66C745D80100 MOV WORD [EBP-28],01 ;**
0167:0049E040 EB15 JMP SHORT 0049E057 ;這裡開始作第一個迴圈
;【演算法過程1】依次從使用者名稱中取字元,對獲得其ASCII碼(10進位制)或異,把它們轉為字元形式連起來;這不是註冊碼!
;///////////////////////////////////////////////////////////////////////////
0167:0049E042 668B4DD8 MOV CX,[EBP-28] ;cx,counter
0167:0049E046 66038D7CFFFFFF ADD CX,[EBP+FFFFFF7C] ;cx=cx+1
0167:0049E04D 0F808B040000 JO NEAR 0049E4DE
0167:0049E053 66894DD8 MOV [EBP-28],CX ;**
0167:0049E057 668B55D8 MOV DX,[EBP-28] ;dx,第一次是1
0167:0049E05B 663B9578FFFFFF CMP DX,[EBP+FFFFFF78] ;同使用者名稱長度比較
0167:0049E062 0F8FB3000000 JG NEAR 0049E11B ;迴圈完了就走
0167:0049E068 C745FC06000000 MOV DWORD [EBP-04],06 ;**
0167:0049E06F C745BC01000000 MOV DWORD [EBP-44],01 ;**
0167:0049E076 C745B402000000 MOV DWORD [EBP-4C],02 ;**
0167:0049E07D 8B4508 MOV EAX,[EBP+08] ;使用者名稱地址
0167:0049E080 89459C MOV [EBP-64],EAX ;**
0167:0049E083 C7459408400000 MOV DWORD [EBP-6C],4008 ;**
0167:0049E08A 8D4DB4 LEA ECX,[EBP-4C]
0167:0049E08D 51 PUSH ECX
0167:0049E08E 0FBF55D8 MOVSX EDX,WORD [EBP-28] ;//
0167:0049E092 52 PUSH EDX
0167:0049E093 8D4594 LEA EAX,[EBP-6C]
0167:0049E096 50 PUSH EAX
0167:0049E097 8D4DA4 LEA ECX,[EBP-5C]
0167:0049E09A 51 PUSH ECX
0167:0049E09B FF1520114000 CALL `MSVBVM60!rtcMidCharVar` ;從使用者名稱中取第i個字元
0167:0049E0A1 8D55A4 LEA EDX,[EBP-5C]
0167:0049E0A4 52 PUSH EDX
0167:0049E0A5 FF1538104000 CALL `MSVBVM60!__vbaStrVarMove` ;把它移到某個地方
0167:0049E0AB 8BD0 MOV EDX,EAX
0167:0049E0AD 8D4DDC LEA ECX,[EBP-24]
0167:0049E0B0 FF15B4124000 CALL `MSVBVM60!__vbaStrMove`
0167:0049E0B6 8D45A4 LEA EAX,[EBP-5C]
0167:0049E0B9 50 PUSH EAX
0167:0049E0BA 8D4DB4 LEA ECX,[EBP-4C]
0167:0049E0BD 51 PUSH ECX
0167:0049E0BE 6A02 PUSH BYTE +02
0167:0049E0C0 FF1548104000 CALL `MSVBVM60!__vbaFreeVarList`
0167:0049E0C6 83C40C ADD ESP,BYTE +0C
0167:0049E0C9 C745FC07000000 MOV DWORD [EBP-04],07
0167:0049E0D0 8B55D4 MOV EDX,[EBP-2C]
0167:0049E0D3 52 PUSH EDX
0167:0049E0D4 8B45DC MOV EAX,[EBP-24]
0167:0049E0D7 50 PUSH EAX
0167:0049E0D8 FF1560104000 CALL `MSVBVM60!rtcAnsiValueBstr` ;取它的ASCII碼(10進位制)
0167:0049E0DE 66350500 XOR AX,05 ;或異
0167:0049E0E2 50 PUSH EAX
0167:0049E0E3 FF150C104000 CALL `MSVBVM60!__vbaStrI2` ;它的ASCII碼轉字元形式
0167:0049E0E9 8BD0 MOV EDX,EAX
0167:0049E0EB 8D4DC4 LEA ECX,[EBP-3C]
0167:0049E0EE FF15B4124000 CALL `MSVBVM60!__vbaStrMove` ;字串移動操作
0167:0049E0F4 50 PUSH EAX
0167:0049E0F5 FF157C104000 CALL `MSVBVM60!__vbaStrCat` ;連線字串,得到串tempString
0167:0049E0FB 8BD0 MOV EDX,EAX
0167:0049E0FD 8D4DD4 LEA ECX,[EBP-2C]
0167:0049E100 FF15B4124000 CALL `MSVBVM60!__vbaStrMove`
0167:0049E106 8D4DC4 LEA ECX,[EBP-3C]
0167:0049E109 FF1500134000 CALL `MSVBVM60!__vbaFreeStr`
0167:0049E10F C745FC08000000 MOV DWORD [EBP-04],08
0167:0049E116 E927FFFFFF JMP 0049E042
;第一個迴圈完
;///////////////////////////////////////////////////////////////////////////
0167:0049E11B C745FC0A000000 MOV DWORD [EBP-04],0A ;**
0167:0049E122 8B4DD4 MOV ECX,[EBP-2C] ;上面的運算結果~tempString地址
0167:0049E125 51 PUSH ECX
0167:0049E126 FF153C104000 CALL `MSVBVM60!__vbaLenBstr` ;tempString的長度
0167:0049E12C 8945C8 MOV [EBP-38],EAX ;**
0167:0049E12F C745FC0B000000 MOV DWORD [EBP-04],0B ;**
0167:0049E136 8B55D4 MOV EDX,[EBP-2C] ;tempString
0167:0049E139 52 PUSH EDX
0167:0049E13A FF153C104000 CALL `MSVBVM60!__vbaLenBstr`
0167:0049E140 898558FFFFFF MOV [EBP+FFFFFF58],EAX ;**,tempString長度
0167:0049E146 DB8558FFFFFF FILD DWORD [EBP+FFFFFF58] ;浮點指令:裝入整數到st(0)
0167:0049E14C DD9D50FFFFFF FSTP QWORD [EBP+FFFFFF50] ;浮點指令:儲存st(0)到變數,並出棧
0167:0049E152 DD8550FFFFFF FLD QWORD [EBP+FFFFFF50] ;浮點指令:裝入實數到st(0)
0167:0049E158 833D00004A0000 CMP DWORD [004A0000],BYTE +00 ;00
0167:0049E15F 7508 JNZ 0049E169
0167:0049E161 DC35E8364000 FDIV QWORD [004036E8] ;浮點指令:除以一個實數,2
0167:0049E167 EB11 JMP SHORT 0049E17A
0167:0049E169 FF35EC364000 PUSH DWORD [004036EC]
0167:0049E16F FF35E8364000 PUSH DWORD [004036E8]
0167:0049E175 E8DA63F6FF CALL `MSVBVM60!_adj_fdiv_m64`
0167:0049E17A DFE0 FNSTSW AX ;儲存狀態字到ax
0167:0049E17C A80D TEST AL,0D
0167:0049E17E 0F8555030000 JNZ NEAR 0049E4D9
0167:0049E184 FF1588124000 CALL `MSVBVM60!__vbaFpI2`
0167:0049E18A 66898570FFFFFF MOV [EBP+FFFFFF70],AX ;**tempString的長度的一半
0167:0049E191 66C78574FFFFFF01+MOV WORD [EBP+FFFFFF74],01 ;**
0167:0049E19A 66C745D80000 MOV WORD [EBP-28],00 ;**[ebp-28]清零了
0167:0049E1A0 EB15 JMP SHORT 0049E1B7 ;這裡開始作第二個迴圈
;【演算法過程2】依次從tempString中取兩位字元,把它們連起來;但??(請讀下去,謝謝)是註冊碼
;///////////////////////////////////////////////////////////////////////////
0167:0049E1A2 668B45D8 MOV AX,[EBP-28]
0167:0049E1A6 66038574FFFFFF ADD AX,[EBP+FFFFFF74]
0167:0049E1AD 0F802B030000 JO NEAR 0049E4DE ;溢位轉移,玩完
0167:0049E1B3 668945D8 MOV [EBP-28],AX
0167:0049E1B7 668B4DD8 MOV CX,[EBP-28] ;從0開始
0167:0049E1BB 663B8D70FFFFFF CMP CX,[EBP+FFFFFF70] ;比較
0167:0049E1C2 0F8FA7020000 JG NEAR 0049E46F ;迴圈結束則跳
0167:0049E1C8 C745FC0C000000 MOV DWORD [EBP-04],0C ;**
0167:0049E1CF 0FBF55D8 MOVSX EDX,WORD [EBP-28] ;//
0167:0049E1D3 85D2 TEST EDX,EDX
0167:0049E1D5 7570 JNZ 0049E247 ;迴圈第一次,則不跳
;不是第一次,則跳
;------------------------------------------------------------------------
0167:0049E1D7 C745FC0D000000 MOV DWORD [EBP-04],0D ;**這個不同
0167:0049E1DE C745BC02000000 MOV DWORD [EBP-44],02 ;**
0167:0049E1E5 C745B402000000 MOV DWORD [EBP-4C],02 ;**
0167:0049E1EC 8D45D4 LEA EAX,[EBP-2C] ;tempString地址
0167:0049E1EF 89459C MOV [EBP-64],EAX
0167:0049E1F2 C7459408400000 MOV DWORD [EBP-6C],4008 ;**
0167:0049E1F9 8D4DB4 LEA ECX,[EBP-4C] ;tempString地址
0167:0049E1FC 51 PUSH ECX
0167:0049E1FD 668B55D8 MOV DX,[EBP-28] ;dx=[EBP-28]中值
0167:0049E201 6683C201 ADD DX,BYTE +01 ;++dx
0167:0049E205 0F80D3020000 JO NEAR 0049E4DE ;溢位轉移
0167:0049E20B 0FBFC2 MOVSX EAX,DX ;eax=dx
0167:0049E20E 50 PUSH EAX
0167:0049E20F 8D4D94 LEA ECX,[EBP-6C]
0167:0049E212 51 PUSH ECX
0167:0049E213 8D55A4 LEA EDX,[EBP-5C]
0167:0049E216 52 PUSH EDX
0167:0049E217 FF1520114000 CALL `MSVBVM60!rtcMidCharVar`
0167:0049E21D 8D45A4 LEA EAX,[EBP-5C]
0167:0049E220 50 PUSH EAX
0167:0049E221 FF1538104000 CALL `MSVBVM60!__vbaStrVarMove` ;從tempStr取頭兩個移到某個位置,返回eax
0167:0049E227 8BD0 MOV EDX,EAX
0167:0049E229 8D4DCC LEA ECX,[EBP-34]
0167:0049E22C FF15B4124000 CALL `MSVBVM60!__vbaStrMove`
0167:0049E232 8D4DA4 LEA ECX,[EBP-5C]
0167:0049E235 51 PUSH ECX
0167:0049E236 8D55B4 LEA EDX,[EBP-4C]
0167:0049E239 52 PUSH EDX
0167:0049E23A 6A02 PUSH BYTE +02
0167:0049E23C FF1548104000 CALL `MSVBVM60!__vbaFreeVarList`
0167:0049E242 83C40C ADD ESP,BYTE +0C
0167:0049E245 EB78 JMP SHORT 0049E2BF ;是迴圈第一次
;------------------------------------------------------------------------
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;不是迴圈第一次,跳在這裡
0167:0049E247 C745FC0F000000 MOV DWORD [EBP-04],0F ;**這個不同
0167:0049E24E C745BC02000000 MOV DWORD [EBP-44],02 ;**
0167:0049E255 C745B402000000 MOV DWORD [EBP-4C],02 ;**
0167:0049E25C 8D45D4 LEA EAX,[EBP-2C] ;tempStr地址
0167:0049E25F 89459C MOV [EBP-64],EAX
0167:0049E262 C7459408400000 MOV DWORD [EBP-6C],4008 ;**
0167:0049E269 8D4DB4 LEA ECX,[EBP-4C]
0167:0049E26C 51 PUSH ECX
0167:0049E26D 668B55D8 MOV DX,[EBP-28]
0167:0049E271 666BD202 IMUL DX,DX,BYTE +02 ;這裡第一次肯定沒有
0167:0049E275 0F8063020000 JO NEAR 0049E4DE
0167:0049E27B 6683C201 ADD DX,BYTE +01
0167:0049E27F 0F8059020000 JO NEAR 0049E4DE
0167:0049E285 0FBFC2 MOVSX EAX,DX
0167:0049E288 50 PUSH EAX
0167:0049E289 8D4D94 LEA ECX,[EBP-6C]
0167:0049E28C 51 PUSH ECX
0167:0049E28D 8D55A4 LEA EDX,[EBP-5C];0
0167:0049E290 52 PUSH EDX
0167:0049E291 FF1520114000 CALL `MSVBVM60!rtcMidCharVar`
0167:0049E297 8D45A4 LEA EAX,[EBP-5C]
0167:0049E29A 50 PUSH EAX
0167:0049E29B FF1538104000 CALL `MSVBVM60!__vbaStrVarMove` ;移動兩個字元
0167:0049E2A1 8BD0 MOV EDX,EAX
0167:0049E2A3 8D4DCC LEA ECX,[EBP-34] ;上兩個字元
0167:0049E2A6 FF15B4124000 CALL `MSVBVM60!__vbaStrMove`
0167:0049E2AC 8D4DA4 LEA ECX,[EBP-5C]
0167:0049E2AF 51 PUSH ECX
0167:0049E2B0 8D55B4 LEA EDX,[EBP-4C];2
0167:0049E2B3 52 PUSH EDX
0167:0049E2B4 6A02 PUSH BYTE +02
0167:0049E2B6 FF1548104000 CALL `MSVBVM60!__vbaFreeVarList`
0167:0049E2BC 83C40C ADD ESP,BYTE +0C
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;這裡就是關鍵,透過浮點數比較,決定如何處理取出的兩個字元:直接轉為字元形式?還是取它們(當其為ASCII碼)對應的字元?
0167:0049E2BF C745FC11000000 MOV DWORD [EBP-04],11 ;**
0167:0049E2C6 8B45CC MOV EAX,[EBP-34] ;從tempString取出的兩個字元
0167:0049E2C9 50 PUSH EAX
0167:0049E2CA FF1528124000 CALL `MSVBVM60!__vbaR8Str` ;這兩個字元轉為數值形式,併入棧
;浮點數入st(0),10
0167:0049E2D0 DC1D00444000 FCOMP QWORD [00404400] ;浮點指令:浮點數比較
{DS段:
004043E8 . 0000000000C05E40 DQ FLOAT 123.0000000000000
004043F0 . 0000000000405840 DQ FLOAT 97.00000000000000
004043F8 . 0000000000805640 DQ FLOAT 90.00000000000000
00404400 . 0000000000005040 DQ FLOAT 64.00000000000000
}
0167:0049E2D6 DFE0 FNSTSW AX ;浮點指令:儲存狀態字的值到ax
0167:0049E2D8 F6C441 TEST AH,41
0167:0049E2DB 740C JZ 0049E2E9 ;☆★
0167:0049E2DD C7854CFFFFFF0100+MOV DWORD [EBP+FFFFFF4C],01 ;**
0167:0049E2E7 EB0A JMP SHORT 0049E2F3 ;☆▲
0167:0049E2E9 C7854CFFFFFF0000+MOV DWORD [EBP+FFFFFF4C],00 ;☆★
;**
;☆▲
0167:0049E2F3 8B4DCC MOV ECX,[EBP-34] ;tempString取出的兩個字元
0167:0049E2F6 51 PUSH ECX
0167:0049E2F7 FF1528124000 CALL `MSVBVM60!__vbaR8Str`
0167:0049E2FD DC1DF8434000 FCOMP QWORD [004043F8]
0167:0049E303 DFE0 FNSTSW AX
0167:0049E305 F6C401 TEST AH,01
0167:0049E308 750C JNZ 0049E316 ;☆■
0167:0049E30A C78548FFFFFF0100+MOV DWORD [EBP+FFFFFF48],01 ;**
0167:0049E314 EB0A JMP SHORT 0049E320 ;☆◆
0167:0049E316 C78548FFFFFF0000+MOV DWORD [EBP+FFFFFF48],00 ;☆■
;**
;☆◆
0167:0049E320 8B55CC MOV EDX,[EBP-34] ;tempString取出的兩個字元
0167:0049E323 52 PUSH EDX
0167:0049E324 FF1528124000 CALL `MSVBVM60!__vbaR8Str`
0167:0049E32A DC1DF0434000 FCOMP QWORD [004043F0]
0167:0049E330 DFE0 FNSTSW AX
0167:0049E332 F6C441 TEST AH,41
0167:0049E335 740C JZ 0049E343 ;☆●
0167:0049E337 C78544FFFFFF0100+MOV DWORD [EBP+FFFFFF44],01 ;**
0167:0049E341 EB0A JMP SHORT 0049E34D ;☆★
0167:0049E343 C78544FFFFFF0000+MOV DWORD [EBP+FFFFFF44],00 ;☆●
;**
;☆★
0167:0049E34D 8B45CC MOV EAX,[EBP-34] ;tempString取出的兩個字元
0167:0049E350 50 PUSH EAX
0167:0049E351 FF1528124000 CALL `MSVBVM60!__vbaR8Str`
0167:0049E357 DC1DE8434000 FCOMP QWORD [004043E8]
0167:0049E35D DFE0 FNSTSW AX
0167:0049E35F F6C401 TEST AH,01
0167:0049E362 750C JNZ 0049E370 ;☆※
0167:0049E364 C78540FFFFFF0100+MOV DWORD [EBP+FFFFFF40],01 ;**
0167:0049E36E EB0A JMP SHORT 0049E37A ;☆◎
0167:0049E370 C78540FFFFFF0000+MOV DWORD [EBP+FFFFFF40],00 ;☆※
;**E
;☆◎
0167:0049E37A 8B8D4CFFFFFF MOV ECX,[EBP+FFFFFF4C] ;??
0167:0049E380 0B8D48FFFFFF OR ECX,[EBP+FFFFFF48] ;??
0167:0049E386 F7D9 NEG ECX ;將運算元按位求反後末位加1
0167:0049E388 1BC9 SBB ECX,ECX ;帶借位減
0167:0049E38A F7D9 NEG ECX
0167:0049E38C 8B9544FFFFFF MOV EDX,[EBP+FFFFFF44]
0167:0049E392 0B9540FFFFFF OR EDX,[EBP+FFFFFF40]
0167:0049E398 F7DA NEG EDX
0167:0049E39A 1BD2 SBB EDX,EDX
0167:0049E39C F7DA NEG EDX
0167:0049E39E 23CA AND ECX,EDX
0167:0049E3A0 85C9 TEST ECX,ECX
0167:0049E3A2 0F859B000000 JNZ NEAR 0049E443
;**************************************************************
;不跳,就把這個字串轉為整數,再取其對應的字元,最後化大寫~終於知道了
0167:0049E3A8 C745FC12000000 MOV DWORD [EBP-04],12
0167:0049E3AF FF1558124000 CALL `MSVBVM60!rtcErrObj`
0167:0049E3B5 8945BC MOV [EBP-44],EAX
0167:0049E3B8 C745B409000000 MOV DWORD [EBP-4C],09
0167:0049E3BF 8D45B4 LEA EAX,[EBP-4C]
0167:0049E3C2 50 PUSH EAX
0167:0049E3C3 FF1508114000 CALL `MSVBVM60!__vbaBoolVarNull`
0167:0049E3C9 66894580 MOV [EBP-80],AX
0167:0049E3CD 8D4DB4 LEA ECX,[EBP-4C]
0167:0049E3D0 FF1530104000 CALL `MSVBVM60!__vbaFreeVar`
0167:0049E3D6 0FBF4D80 MOVSX ECX,WORD [EBP-80]
0167:0049E3DA 85C9 TEST ECX,ECX
0167:0049E3DC 7413 JZ 0049E3F1
0167:0049E3DE C745FC13000000 MOV DWORD [EBP-04],13
0167:0049E3E5 8B55CC MOV EDX,[EBP-34]
0167:0049E3E8 8D4DCC LEA ECX,[EBP-34]
0167:0049E3EB FF1540124000 CALL `MSVBVM60!__vbaStrCopy`
0167:0049E3F1 C745FC15000000 MOV DWORD [EBP-04],15
0167:0049E3F8 8B55CC MOV EDX,[EBP-34] ;操作物件
0167:0049E3FB 52 PUSH EDX
0167:0049E3FC FF1544124000 CALL `MSVBVM60!__vbaI4Str` ;整數取對應字元
0167:0049E402 50 PUSH EAX
0167:0049E403 8D45B4 LEA EAX,[EBP-4C]
0167:0049E406 50 PUSH EAX
0167:0049E407 FF15DC114000 CALL `MSVBVM60!rtcVarBstrFromAnsi`
0167:0049E40D 8D4DB4 LEA ECX,[EBP-4C]
0167:0049E410 51 PUSH ECX
0167:0049E411 8D55A4 LEA EDX,[EBP-5C]
0167:0049E414 52 PUSH EDX
0167:0049E415 FF1538114000 CALL `MSVBVM60!rtcUpperCaseVar` ;大寫
0167:0049E41B 8D45A4 LEA EAX,[EBP-5C]
0167:0049E41E 50 PUSH EAX
0167:0049E41F FF1538104000 CALL `MSVBVM60!__vbaStrVarMove`
0167:0049E425 8BD0 MOV EDX,EAX
0167:0049E427 8D4DCC LEA ECX,[EBP-34]
0167:0049E42A FF15B4124000 CALL `MSVBVM60!__vbaStrMove`
0167:0049E430 8D4DA4 LEA ECX,[EBP-5C]
0167:0049E433 51 PUSH ECX
0167:0049E434 8D55B4 LEA EDX,[EBP-4C]
0167:0049E437 52 PUSH EDX
0167:0049E438 6A02 PUSH BYTE +02
0167:0049E43A FF1548104000 CALL `MSVBVM60!__vbaFreeVarList`
0167:0049E440 83C40C ADD ESP,BYTE +0C
;********************************************************************
0167:0049E443 C745FC17000000 MOV DWORD [EBP-04],17 ;**
0167:0049E44A 8B45D0 MOV EAX,[EBP-30] ;00
0167:0049E44D 50 PUSH EAX
0167:0049E44E 8B4DCC MOV ECX,[EBP-34] ;從tempString取出的或經過計算了的
0167:0049E451 51 PUSH ECX
0167:0049E452 FF157C104000 CALL `MSVBVM60!__vbaStrCat` ;這裡連線的就是註冊碼
0167:0049E458 8BD0 MOV EDX,EAX
0167:0049E45A 8D4DD0 LEA ECX,[EBP-30]
0167:0049E45D FF15B4124000 CALL `MSVBVM60!__vbaStrMove`
0167:0049E463 C745FC18000000 MOV DWORD [EBP-04],18
0167:0049E46A E933FDFFFF JMP 0049E1A2
;第二個迴圈完
;///////////////////////////////////////////////////////////////////////////
【總結】
演算法不難,見上
我希望表達清楚了……
【序號產生器】
;KeyGen.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; The KeyGen by lq7972,with MASM32 V8
; E-mail:bruceyu13@sina.com
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;Include檔案定義
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
include comdlg32.inc
includelib comdlg32.lib
include masm32.inc
includelib masm32.lib
;Equ等值定義
ICO_MAIN equ 1000H
DLG_MAIN equ 1
EditName equ 10
EditSN equ 11
;*************************************************************************************
.data?
hInstance dd ?
szSN db 255 dup (?)
szName db 255 dup (?)
regStr db 255 dup (?)
theString db 8 dup (?)
lenString db 8 dup (?)
.data
szErr db '請輸入使用者名稱!',0
szCaption db '錯誤!',0
.const
Num01 dq 64.00000000000000
Num02 dq 90.00000000000000
Num03 dq 97.00000000000000
Num04 dq 123.0000000000000
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;***************************************************************************************
_testStr proc uses ebx edi esi ebp, @tempStr
local @tempStr00
local @temp01, @temp02, @temp03, @temp04
invoke atodw, @tempStr
mov dword ptr @tempStr00, eax
xor eax, eax
fild @tempStr00
fcomp Num01
fnstsw ax
test ah,41h
jz @F
mov dword ptr @temp01, 01
jmp a10
@@:
mov dword ptr @temp01, 00
a10:
xor eax, eax
fild @tempStr00
fcomp Num02
fnstsw ax
test ah, 1
jnz @F
mov dword ptr @temp02, 01
jmp a20
@@:
mov dword ptr @temp02, 00
a20:
xor eax, eax
fild @tempStr00
fcomp Num03
fnstsw ax
test ah, 41
jz @F
mov dword ptr @temp03, 01
jmp a30
@@:
mov dword ptr @temp03, 00
a30:
xor eax, eax
fild @tempStr00
fcomp Num04
fnstsw ax
test ah, 01
jnz @F
mov dword ptr @temp04, 01
jmp a40
@@:
mov dword ptr @temp04, 00
a40:
mov ecx, dword ptr @temp01
or ecx, @temp02
neg ecx
sbb ecx, ecx
neg ecx
mov edx, dword ptr @temp03
or edx, @temp04
neg edx
sbb edx, edx
neg edx
and ecx, edx
ret
_testStr endp
;***************************************************************************************
;***************************************************************************************
_regCodCalc proc
local @temp[8], @temp00[8], @temp01, @temp02
pushad
invoke lstrlen, addr szName
mov edi, eax
sub esi, esi
xor ebx, ebx
;計算中間字串變數
.while esi < edi
sub edx, edx
mov dl, byte ptr [szName+esi]
xor dx, 5
mov dword ptr @temp01, edx
invoke dwtoa, @temp01, addr @temp02
;MASM32庫函式
mov eax, dword ptr @temp02
mov dword ptr [regStr+ebx], eax
invoke lstrlen, addr regStr
mov ebx, eax
inc esi
.break .if esi > edi
.continue
.endw
;計算註冊碼
invoke lstrlen, addr regStr
inc eax
mov ecx, 2
cdq
idiv ecx
mov dword ptr lenString, eax
mov esi, eax
xor ebx, ebx
xor edi, edi
.while edi < esi
invoke RtlZeroMemory, addr @temp, 8
invoke RtlZeroMemory, addr @temp00, 8
movsx eax, byte ptr [regStr+2*edi]
movsx edx, byte ptr [regStr+2*edi+1]
mov byte ptr @temp, al
mov byte ptr @temp00, dl
invoke lstrcat, addr @temp, addr @temp00
invoke _testStr, addr @temp
;子程式,帶一個引數,返回在ecx中
test ecx, ecx
jnz @F
invoke atodw, addr @temp
;MASM32庫函式
jmp a10
@@:
mov eax, dword ptr @temp
a10:
mov dword ptr [szSN+ebx], eax
invoke lstrlen, addr szSN
mov ebx, eax
inc edi
.break .if edi > esi
.continue
.endw
popad
ret
_regCodCalc endp
;**************************************************************************************
_ProcDlgMain proc uses ebx edi esi ebp, hWnd,wMsg,wParam,lParam
mov eax,wMsg
.if eax==WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax==WM_COMMAND
mov eax,wParam
.if eax == IDOK
invoke RtlZeroMemory,addr szSN,255
invoke GetDlgItemText,hWnd,EditName,offset szName,255
.if eax != NULL
invoke _regCodCalc
invoke SetDlgItemText, hWnd, EditSN, offset szSN
mov eax,FALSE
ret
.else
invoke MessageBox,NULL,offset szErr,offset szCaption,MB_OK
mov eax,FALSE
ret
.endif
.elseif eax == IDCANCEL
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
//KeyGen.rc
#include
#define ICO_MAIN 0x1000
#define DLG_MAIN 1
#define EDITName 10
#define EDITSN 11
ICO_MAIN ICON "01.ico"
DLG_MAIN DIALOG 100,150,250,60
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
CAPTION "豪傑超級解霸3K~英雄版 序號產生器"
FONT 9,"宋體"
{
CONTROL "Name:" ,-1,"Static",SS_LEFT,10,13,40,17
CONTROL "SN:" ,-2,"Static",SS_CENTER,10,40,20,17
CONTROL "" ,10,"Edit",ES_LEFT,30,13,150,10
CONTROL "" ,11,"Edit",ES_LEFT,30,40,150,10
DEFPUSHBUTTON "GENERATE",IDOK,200,11,40,15
PUSHBUTTON "EXIT",IDCANCEL,200,36,41,14
}
#makefile
NAME = KeyGen
OBJS = $(NAME).obj #需要的目標檔案
RES = $(NAME).res #需要的資原始檔
LINK_FLAG = /subsystem:windows #連線選項
ML_FLAG = /c /coff #編譯選項
$(NAME).exe: $(OBJS) $(RES)
Link $(LINK_FLAG) $(OBJS) $(RES)
.asm.obj:
ml $(ML_FLAG) $<
.rc.res:
rc $<
clean:
del *.obj
del *.res
相關文章
- 浮點運算簡介(part I)... (6千字)2002-03-31
- 浮點運算簡介 (轉)2007-08-15
- 計算機中的浮點運算2015-11-30計算機
- javascript浮點數精確計算程式碼2017-03-17JavaScript
- 深入理解浮點數的運算2024-10-18
- JavaScript解決浮點數算數運算精度問題2018-07-03JavaScript
- python中精確的浮點數運算2019-02-16Python
- Python做浮點數(float)運算要小心2018-12-27Python
- 有關 PHP 和 js 浮點運算的坑2017-10-12PHPJS
- 比特幣浮點運算速度64百億億次!2013-12-01比特幣
- 浮點數的加減乘除運算細節2024-08-17
- 浮點數在計算機底層的表示及運算2020-07-07計算機
- 全面總結 JS 中浮點數運算問題2019-10-19JS
- JavaScript 浮點數及運算精度調整總結2015-12-02JavaScript
- 計組之資料運算:9、浮點數的表示2020-09-23
- 【轉】JS浮點數運算Bug的解決辦法2017-03-27JS
- 為什麼php的浮點數運算不準確2017-02-09PHP
- 圖解計算機中的數值範圍和浮點運算2021-01-28圖解計算機
- Java浮點數計算2012-06-14Java
- php 處理 浮點數 精度運算 數字處理等2021-05-12PHP
- 3,javase程式碼實戰-運算子——更加精確的使用浮點數(二)2018-02-24Java
- ARMCC和GCC編譯ARM程式碼的軟浮點和硬浮點問題2017-11-08GC編譯
- 補碼、反碼、浮點數2024-10-16
- 程式碼·--四則運算的主要核心程式碼2015-12-07
- 匹配浮點數的正規表示式程式碼2017-02-25
- Delphi程式碼最佳化(三) 浮點篇 (轉)2007-12-06
- Python浮點數(小數)運算誤差的原因和解決辦法2019-07-09Python
- linux shell 實現 四則運算(整數及浮點) 簡單方法2015-04-26Linux
- Linux Shell 實現四則運算(整數及浮點)簡單方法2015-10-04Linux
- 四則運算之主要程式碼2015-12-19
- js中浮點數計算常用方法2018-11-23JS
- js精確計算浮點數相加2024-06-14JS
- 浮點數線上轉hex計算工具2024-11-09
- 計算機組成原理--浮點數-原碼補碼錶示範圍2020-10-15計算機
- 浮點運算為什麼不準?有人為0.30000000000000004建了個網站2020-04-06網站
- 浮動廣告程式碼2007-09-03
- 程式中算錢不能用浮點型別是個什麼坑?2019-04-26型別
- js處理浮點數計算誤差2018-12-07JS