【文章标题】: 批量缩略图工具 V2.0 注册算法
【文章作者】: drcool
【作者邮箱】: drui118@163.com
【作者主页】: 无
【生产日期】: 20070128
【软件名称】: Batchpic V2.0
【保护方式】: 机器码+注册码,运算方法类RSA的模幂运算
【编写语言】: Delphi 7
【使用工具】: OD
【作者声明】: 本文仅供研究学习,本人对因这篇文章而导致的一切后果,不承担任何法律责任。本文中的不足之处请各位多多指教
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
--------------------------------------------------------------------------------
【详细过程】
无壳,以C盘序列号C4EE-B130为例子来说明算法。首先程序通过GetVolumeInformation来得到硬盘序列号:C4EEB130,转换为10进制为:3303977264. 然后进行倒序变换为4627793033.
004A81CA  |. E8 7DC2F5FF    CALL BatchPic.0040444C                   ;  求长度 
004A81CF  |. 8BD8           MOV EBX,EAX
004A81D1  |. 8D45 F4        LEA EAX,DWORD PTR SS:[EBP-C]
004A81D4  |. 50             PUSH EAX
004A81D5  |. 8BD3           MOV EDX,EBX
004A81D7  |. 83EA 03        SUB EDX,3
004A81DA  |. B9 04000000    MOV ECX,4
004A81DF  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A81E2  |. E8 C5C4F5FF    CALL BatchPic.004046AC
004A81E7  |. 8B45 F4        MOV EAX,DWORD PTR SS:[EBP-C]
004A81EA  |. E8 BD06F6FF    CALL BatchPic.004088AC
004A81EF  |. B9 4BC70700    MOV ECX,7C74B
004A81F4  |. BA 27200000    MOV EDX,2027
004A81F9  |. E8 D6F5FFFF    CALL BatchPic.004A77D4                   ;  核心函数(1)
004A81FE  |. 52             PUSH EDX                                 ; /Arg2
004A81FF  |. 50             PUSH EAX                                 ; |Arg1
004A8200  |. 8D45 F8        LEA EAX,DWORD PTR SS:[EBP-8]             ; |
004A8203  |. E8 5406F6FF    CALL BatchPic.0040885C                   ; \BatchPic.0040885C
004A8208  |. 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
004A820B  |. 50             PUSH EAX
004A820C  |. 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
004A820F  |. 50             PUSH EAX
004A8210  |. 8BD3           MOV EDX,EBX
004A8212  |. 83EA 07        SUB EDX,7
004A8215  |. B9 04000000    MOV ECX,4
004A821A  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A821D  |. E8 8AC4F5FF    CALL BatchPic.004046AC
004A8222  |. 8B55 F0        MOV EDX,DWORD PTR SS:[EBP-10]
004A8225  |. 8BC6           MOV EAX,ESI
004A8227  |. 59             POP ECX
004A8228  |. E8 6BC2F5FF    CALL BatchPic.00404498
004A822D  |. 33C0           XOR EAX,EAX
004A822F  |. 5A             POP EDX
004A8230  |. 59             POP ECX
004A8231  |. 59             POP ECX
004A8232  |. 64:8910        MOV DWORD PTR FS:[EAX],EDX
004A8235  |. 68 4F824A00    PUSH BatchPic.004A824F
004A823A  |> 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
004A823D  |. BA 04000000    MOV EDX,4
004A8242  |. E8 69BFF5FF    CALL BatchPic.004041B0
004A8247  \. C3             RETN
关于核心函数(1),我们后面会专门提到的。
核心函数(1)的入口参数是 4627793033 的后4位 3033,出来变成了367396。
再在前面接上4627793033 的第3到6位,即2779。这样机器码就出来了:
2779367396.下面我们来说说验证过程:
注册码必须是8位,否则就直接有出错对话框了。
004A64FC  /. 55             PUSH EBP
004A64FD  |. 8BEC           MOV EBP,ESP
004A64FF  |. 33C9           XOR ECX,ECX
004A6501  |. 51             PUSH ECX
004A6502  |. 51             PUSH ECX
004A6503  |. 51             PUSH ECX
004A6504  |. 51             PUSH ECX
004A6505  |. 51             PUSH ECX
004A6506  |. 51             PUSH ECX
004A6507  |. 51             PUSH ECX
004A6508  |. 51             PUSH ECX
004A6509  |. 53             PUSH EBX
004A650A  |. 56             PUSH ESI
004A650B  |. 8BD8           MOV EBX,EAX
004A650D  |. 33C0           XOR EAX,EAX
004A650F  |. 55             PUSH EBP
004A6510  |. 68 B6664A00    PUSH BatchPic.004A66B6
004A6515  |. 64:FF30        PUSH DWORD PTR FS:[EAX]
004A6518  |. 64:8920        MOV DWORD PTR FS:[EAX],ESP
004A651B  |. 8D55 FC        LEA EDX,DWORD PTR SS:[EBP-4]
004A651E  |. 8B83 28030000  MOV EAX,DWORD PTR DS:[EBX+328]
004A6524  |. E8 3391FBFF    CALL BatchPic.0045F65C
004A6529  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A652C  |. E8 1BDFF5FF    CALL BatchPic.0040444C
004A6531  |. 83F8 08        CMP EAX,8  //必须是8位
004A6534  |. 74 3F          JE SHORT BatchPic.004A6575
004A6536  |. 6A 10          PUSH 10
004A6538  |. 8D55 F8        LEA EDX,DWORD PTR SS:[EBP-8]
004A653B  |. A1 D4FF4A00    MOV EAX,DWORD PTR DS:[4AFFD4]
004A6540  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A6542  |. E8 D18AFDFF    CALL BatchPic.0047F018
004A6547  |. 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
004A654A  |. E8 FDE0F5FF    CALL BatchPic.0040464C
004A654F  |. 50             PUSH EAX
004A6550  |. 68 C4664A00    PUSH BatchPic.004A66C4
004A6555  |. 8BC3           MOV EAX,EBX
004A6557  |. E8 20F9FBFF    CALL BatchPic.00465E7C
004A655C  |. 50             PUSH EAX                                 ; |hOwner
004A655D  |. E8 CE08F6FF    CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
004A6562  |. 8B83 28030000  MOV EAX,DWORD PTR DS:[EBX+328]
004A6568  |. 8B10           MOV EDX,DWORD PTR DS:[EAX]
004A656A  |. FF92 C4000000  CALL DWORD PTR DS:[EDX+C4]
004A6570  |. E9 F9000000    JMP BatchPic.004A666E
004A6575  |> 8D55 F4        LEA EDX,DWORD PTR SS:[EBP-C]
004A6578  |. 8B83 28030000  MOV EAX,DWORD PTR DS:[EBX+328]
004A657E  |. E8 D990FBFF    CALL BatchPic.0045F65C
004A6583  |. 8B45 F4        MOV EAX,DWORD PTR SS:[EBP-C]
004A6586  |. 50             PUSH EAX
004A6587  |. 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
004A658A  |. E8 151C0000    CALL BatchPic.004A81A4
004A658F  |. 8B45 F0        MOV EAX,DWORD PTR SS:[EBP-10]
004A6592  |. 5A             POP EDX
004A6593  |. E8 8C160000    CALL BatchPic.004A7C24//这个函数里进行验证
004A6598  |. 84C0           TEST AL,AL
004A659A  |. 0F84 94000000  JE BatchPic.004A6634
004A65A0  |. A1 10FD4A00    MOV EAX,DWORD PTR DS:[4AFD10]
004A65A5  |. C600 01        MOV BYTE PTR DS:[EAX],1
004A65A8  |. 8D55 EC        LEA EDX,DWORD PTR SS:[EBP-14]
004A65AB  |. 8B83 28030000  MOV EAX,DWORD PTR DS:[EBX+328]
004A65B1  |. E8 A690FBFF    CALL BatchPic.0045F65C
004A65B6  |. 8B55 EC        MOV EDX,DWORD PTR SS:[EBP-14]
004A65B9  |. A1 38FD4A00    MOV EAX,DWORD PTR DS:[4AFD38]
004A65BE  |. E8 1DDCF5FF    CALL BatchPic.004041E0
004A65C3  |. 8D55 E8        LEA EDX,DWORD PTR SS:[EBP-18]
004A65C6  |. 8B83 28030000  MOV EAX,DWORD PTR DS:[EBX+328]
004A65CC  |. E8 8B90FBFF    CALL BatchPic.0045F65C
004A65D1  |. 8B45 E8        MOV EAX,DWORD PTR SS:[EBP-18]
004A65D4  |. 50             PUSH EAX
004A65D5  |. A1 E4FF4A00    MOV EAX,DWORD PTR DS:[4AFFE4]
004A65DA  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A65DC  |. B9 DC664A00    MOV ECX,BatchPic.004A66DC                ;  ASCII "KEY"
004A65E1  |. BA E8664A00    MOV EDX,BatchPic.004A66E8                ;  ASCII "REGCODE"
004A65E6  |. 8B30           MOV ESI,DWORD PTR DS:[EAX]
004A65E8  |. FF56 04        CALL DWORD PTR DS:[ESI+4]
004A65EB  |. 6A 40          PUSH 40
004A65ED  |. 8D55 E4        LEA EDX,DWORD PTR SS:[EBP-1C]
004A65F0  |. A1 D4FF4A00    MOV EAX,DWORD PTR DS:[4AFFD4]
004A65F5  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A65F7  |. E8 1C8AFDFF    CALL BatchPic.0047F018
004A65FC  |. 8B45 E4        MOV EAX,DWORD PTR SS:[EBP-1C]
004A65FF  |. E8 48E0F5FF    CALL BatchPic.0040464C
004A6604  |. 50             PUSH EAX
004A6605  |. 68 F0664A00    PUSH BatchPic.004A66F0
004A660A  |. 8BC3           MOV EAX,EBX
004A660C  |. E8 6BF8FBFF    CALL BatchPic.00465E7C
004A6611  |. 50             PUSH EAX                                 ; |hOwner
004A6612  |. E8 1908F6FF    CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
004A6617  |. A1 C4FE4A00    MOV EAX,DWORD PTR DS:[4AFEC4]
004A661C  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A661E  |. 8B80 74030000  MOV EAX,DWORD PTR DS:[EAX+374]
004A6624  |. 33D2           XOR EDX,EDX
004A6626  |. E8 518FFBFF    CALL BatchPic.0045F57C
004A662B  |. 8BC3           MOV EAX,EBX
004A662D  |. E8 9257FDFF    CALL BatchPic.0047BDC4
004A6632  |. EB 3A          JMP SHORT BatchPic.004A666E
004A6634  |> 6A 10          PUSH 10
004A6636  |. 8D55 E0        LEA EDX,DWORD PTR SS:[EBP-20]
004A6639  |. A1 D4FF4A00    MOV EAX,DWORD PTR DS:[4AFFD4]
004A663E  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004A6640  |. E8 D389FDFF    CALL BatchPic.0047F018
004A6645  |. 8B45 E0        MOV EAX,DWORD PTR SS:[EBP-20]
004A6648  |. E8 FFDFF5FF    CALL BatchPic.0040464C
004A664D  |. 50             PUSH EAX
004A664E  |. 68 C4664A00    PUSH BatchPic.004A66C4
004A6653  |. 8BC3           MOV EAX,EBX
004A6655  |. E8 22F8FBFF    CALL BatchPic.00465E7C
004A665A  |. 50             PUSH EAX                                 ; |hOwner
004A665B  |. E8 D007F6FF    CALL <JMP.&user32.MessageBoxA>           ; \MessageBoxA
004A6660  |. 8B83 28030000  MOV EAX,DWORD PTR DS:[EBX+328]
004A6666  |. 8B10           MOV EDX,DWORD PTR DS:[EAX]
004A6668  |. FF92 C4000000  CALL DWORD PTR DS:[EDX+C4]
004A666E  |> 33C0           XOR EAX,EAX
004A6670  |. 5A             POP EDX
004A6671  |. 59             POP ECX
004A6672  |. 59             POP ECX
004A6673  |. 64:8910        MOV DWORD PTR FS:[EAX],EDX
004A6676  |. 68 BD664A00    PUSH BatchPic.004A66BD
004A667B  |> 8D45 E0        LEA EAX,DWORD PTR SS:[EBP-20]
004A667E  |. BA 02000000    MOV EDX,2
004A6683  |. E8 28DBF5FF    CALL BatchPic.004041B0
004A6688  |. 8D45 E8        LEA EAX,DWORD PTR SS:[EBP-18]
004A668B  |. BA 02000000    MOV EDX,2
004A6690  |. E8 1BDBF5FF    CALL BatchPic.004041B0
004A6695  |. 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]
004A6698  |. E8 EFDAF5FF    CALL BatchPic.0040418C
004A669D  |. 8D45 F4        LEA EAX,DWORD PTR SS:[EBP-C]
004A66A0  |. E8 E7DAF5FF    CALL BatchPic.0040418C
004A66A5  |. 8D45 F8        LEA EAX,DWORD PTR SS:[EBP-8]
004A66A8  |. E8 DFDAF5FF    CALL BatchPic.0040418C
004A66AD  |. 8D45 FC        LEA EAX,DWORD PTR SS:[EBP-4]
004A66B0  |. E8 D7DAF5FF    CALL BatchPic.0040418C
004A66B5  \. C3             RETN

我们来看验证函数BatchPic.004A7C24的核心部分:
前面略去许多与验证无关的代码....
004A7E0C   . 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
004A7E0F   . E8 38C6F5FF    CALL BatchPic.0040444C
004A7E14   . 8BC8           MOV ECX,EAX
004A7E16   . 83E9 04        SUB ECX,4
004A7E19   . BA 03000000    MOV EDX,3
004A7E1E   . 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
004A7E21   . E8 86C8F5FF    CALL BatchPic.004046AC //取假码的3-6位
004A7E26   . 8B45 E8        MOV EAX,DWORD PTR SS:[EBP-18]
004A7E29   . E8 7E0AF6FF    CALL BatchPic.004088AC
004A7E2E   . 8BD8           MOV EBX,EAX
004A7E30   . 8D45 E4        LEA EAX,DWORD PTR SS:[EBP-1C]
004A7E33   . 50             PUSH EAX
004A7E34   . B9 08000000    MOV ECX,8
004A7E39   . BA 05000000    MOV EDX,5
004A7E3E   . 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
004A7E41   . E8 66C8F5FF    CALL BatchPic.004046AC//取机器码的367396
004A7E46   . 8B45 E4        MOV EAX,DWORD PTR SS:[EBP-1C]
004A7E49   . E8 5E0AF6FF    CALL BatchPic.004088AC
004A7E4E   . 8BF0           MOV ESI,EAX
004A7E50   . B9 4BC70700    MOV ECX,7C74B
004A7E55   . 8BD3           MOV EDX,EBX
004A7E57   . 8BC6           MOV EAX,ESI
004A7E59   . E8 76F9FFFF    CALL BatchPic.004A77D4 //又看到了我们核心函数(1),再次被调用,看来关键还是在这里
004A7E5E   . 52             PUSH EDX
004A7E5F   . 50             PUSH EAX
004A7E60   . 8D45 E0        LEA EAX,DWORD PTR SS:[EBP-20]
004A7E63   . 50             PUSH EAX
004A7E64   . 8D45 DC        LEA EAX,DWORD PTR SS:[EBP-24]
004A7E67   . E8 3C020000    CALL BatchPic.004A80A8
004A7E6C   . 8B45 DC        MOV EAX,DWORD PTR SS:[EBP-24]
004A7E6F   . E8 D8C5F5FF    CALL BatchPic.0040444C
004A7E74   . 83E8 03        SUB EAX,3
004A7E77   . 50             PUSH EAX
004A7E78   . 8D45 D8        LEA EAX,DWORD PTR SS:[EBP-28]
004A7E7B   . E8 28020000    CALL BatchPic.004A80A8
004A7E80   . 8B45 D8        MOV EAX,DWORD PTR SS:[EBP-28]
004A7E83   . B9 04000000    MOV ECX,4
004A7E88   . 5A             POP EDX
004A7E89   . E8 1EC8F5FF    CALL BatchPic.004046AC
004A7E8E   . 8B45 E0        MOV EAX,DWORD PTR SS:[EBP-20]
004A7E91   . E8 160AF6FF    CALL BatchPic.004088AC
004A7E96   . 99             CDQ
004A7E97   . 3B5424 04      CMP EDX,DWORD PTR SS:[ESP+4]//这里一定是0 
004A7E9B   . 75 03          JNZ SHORT BatchPic.004A7EA0
004A7E9D   . 3B0424         CMP EAX,DWORD PTR SS:[ESP]  //这是关键的比较,一定要相等才行
004A7EA0   > 5A             POP EDX
004A7EA1   . 58             POP EAX
004A7EA2   . 75 04          JNZ SHORT BatchPic.004A7EA8
004A7EA4   . B3 01          MOV BL,1
004A7EA6   . EB 02          JMP SHORT BatchPic.004A7EAA
004A7EA8   > 33DB           XOR EBX,EBX
004A7EAA   > 33C0           XOR EAX,EAX
004A7EAC   . 5A             POP EDX
004A7EAD   . 59             POP ECX
004A7EAE   . 59             POP ECX
004A7EAF   . 64:8910        MOV DWORD PTR FS:[EAX],EDX
004A7EB2   . EB 18          JMP SHORT BatchPic.004A7ECC
004A7EB4   .^E9 CBBAF5FF    JMP BatchPic.00403984
下面我来重点说说核心函数(1)
004A77D4  /$ 53             PUSH EBX
004A77D5  |. 56             PUSH ESI
004A77D6  |. 57             PUSH EDI
004A77D7  |. 83C4 F8        ADD ESP,-8
004A77DA  |. 8BD9           MOV EBX,ECX
004A77DC  |. 8BFA           MOV EDI,EDX
004A77DE  |. 8BF0           MOV ESI,EAX
004A77E0  |. 83FF 01        CMP EDI,1
004A77E3  |. 76 3C          JBE SHORT BatchPic.004A7821
004A77E5  |. 8BC3           MOV EAX,EBX
004A77E7  |. 33D2           XOR EDX,EDX
004A77E9  |. 52             PUSH EDX
004A77EA  |. 50             PUSH EAX
004A77EB  |. 8BC6           MOV EAX,ESI
004A77ED  |. 33D2           XOR EDX,EDX
004A77EF  |. F7F3           DIV EBX
004A77F1  |. 8BC2           MOV EAX,EDX
004A77F3  |. 33D2           XOR EDX,EDX
004A77F5  |. 52             PUSH EDX
004A77F6  |. 50             PUSH EAX
004A77F7  |. 8BC3           MOV EAX,EBX
004A77F9  |. 33D2           XOR EDX,EDX
004A77FB  |. 52             PUSH EDX
004A77FC  |. 50             PUSH EAX
004A77FD  |. 8BD7           MOV EDX,EDI
004A77FF  |. 4A             DEC EDX
004A7800  |. 8BCB           MOV ECX,EBX
004A7802  |. 8BC6           MOV EAX,ESI
004A7804  |. E8 CBFFFFFF    CALL BatchPic.004A77D4
004A7809  |. E8 66D8F5FF    CALL BatchPic.00405074
004A780E  |. E8 C1D7F5FF    CALL BatchPic.00404FD4
004A7813  |. E8 5CD8F5FF    CALL BatchPic.00405074
004A7818  |. 890424         MOV DWORD PTR SS:[ESP],EAX
004A781B  |. 895424 04      MOV DWORD PTR SS:[ESP+4],EDX
004A781F  |. EB 11          JMP SHORT BatchPic.004A7832
004A7821  |> 8BC6           MOV EAX,ESI
004A7823  |. 33D2           XOR EDX,EDX
004A7825  |. F7F3           DIV EBX
004A7827  |. 8BC2           MOV EAX,EDX
004A7829  |. 33D2           XOR EDX,EDX
004A782B  |. 890424         MOV DWORD PTR SS:[ESP],EAX
004A782E  |. 895424 04      MOV DWORD PTR SS:[ESP+4],EDX
004A7832  |> 8B0424         MOV EAX,DWORD PTR SS:[ESP]
004A7835  |. 8B5424 04      MOV EDX,DWORD PTR SS:[ESP+4]
004A7839  |. 59             POP ECX
004A783A  |. 5A             POP EDX
004A783B  |. 5F             POP EDI
004A783C  |. 5E             POP ESI
004A783D  |. 5B             POP EBX
004A783E  \. C3             RETN
首先注意到函数调用的入口出都引用了常数0x7c74b,另外我们还发现这个调用是递归式的!看下面四行,仔细看这4行的每个函数在实现什么功能啊!
004A7804  |. E8 CBFFFFFF    CALL BatchPic.004A77D4 //递归调用
004A7809  |. E8 66D8F5FF    CALL BatchPic.00405074
004A780E  |. E8 C1D7F5FF    CALL BatchPic.00404FD4
004A7813  |. E8 5CD8F5FF    CALL BatchPic.00405074


BatchPic.00405074的代码如下
00405074  /$ 55             PUSH EBP
00405075  |. 53             PUSH EBX
00405076  |. 56             PUSH ESI
00405077  |. 57             PUSH EDI
00405078  |. 31FF           XOR EDI,EDI
0040507A  |. 8B5C24 14      MOV EBX,DWORD PTR SS:[ESP+14]
0040507E  |. 8B4C24 18      MOV ECX,DWORD PTR SS:[ESP+18]
00405082  |. 09C9           OR ECX,ECX
00405084  |. 75 08          JNZ SHORT BatchPic.0040508E
00405086  |. 09D2           OR EDX,EDX
00405088  |. 74 5D          JE SHORT BatchPic.004050E7
0040508A  |. 09DB           OR EBX,EBX
0040508C  |. 74 59          JE SHORT BatchPic.004050E7
0040508E  |> 09D2           OR EDX,EDX
00405090  |. 79 0A          JNS SHORT BatchPic.0040509C
00405092  |. F7DA           NEG EDX
00405094  |. F7D8           NEG EAX
00405096  |. 83DA 00        SBB EDX,0
00405099  |. 83CF 01        OR EDI,1
0040509C  |> 09C9           OR ECX,ECX
0040509E  |. 79 07          JNS SHORT BatchPic.004050A7
004050A0  |. F7D9           NEG ECX
004050A2  |. F7DB           NEG EBX
004050A4  |. 83D9 00        SBB ECX,0
004050A7  |> 89CD           MOV EBP,ECX
004050A9  |. B9 40000000    MOV ECX,40
004050AE  |. 57             PUSH EDI
004050AF  |. 31FF           XOR EDI,EDI
004050B1  |. 31F6           XOR ESI,ESI
004050B3  |> D1E0           /SHL EAX,1
004050B5  |. D1D2           |RCL EDX,1
004050B7  |. D1D6           |RCL ESI,1
004050B9  |. D1D7           |RCL EDI,1
004050BB  |. 39EF           |CMP EDI,EBP
004050BD  |. 72 0B          |JB SHORT BatchPic.004050CA
004050BF  |. 77 04          |JA SHORT BatchPic.004050C5
004050C1  |. 39DE           |CMP ESI,EBX
004050C3  |. 72 05          |JB SHORT BatchPic.004050CA
004050C5  |> 29DE           |SUB ESI,EBX
004050C7  |. 19EF           |SBB EDI,EBP
004050C9  |. 40             |INC EAX
004050CA  |>^E2 E7          \LOOPD SHORT BatchPic.004050B3
004050CC  |. 89F0           MOV EAX,ESI
004050CE  |. 89FA           MOV EDX,EDI
004050D0  |. 5B             POP EBX
004050D1  |. F7C3 01000000  TEST EBX,1
004050D7  |. 74 07          JE SHORT BatchPic.004050E0
004050D9  |. F7DA           NEG EDX
004050DB  |. F7D8           NEG EAX
004050DD  |. 83DA 00        SBB EDX,0
004050E0  |> 5F             POP EDI
004050E1  |. 5E             POP ESI
004050E2  |. 5B             POP EBX
004050E3  |. 5D             POP EBP
004050E4  |. C2 0800        RETN 8
004050E7  |> F7F3           DIV EBX
004050E9  |. 92             XCHG EAX,EDX
004050EA  |. 31D2           XOR EDX,EDX
004050EC  \.^EB F2          JMP SHORT BatchPic.004050E0
小心看那个循环在干什么,呵呵。

BatchPic.00404FD4
00404FD4  /$ 52             PUSH EDX
00404FD5  |. 50             PUSH EAX
00404FD6  |. 8B4424 10      MOV EAX,DWORD PTR SS:[ESP+10]
00404FDA  |. F72424         MUL DWORD PTR SS:[ESP]
00404FDD  |. 89C1           MOV ECX,EAX
00404FDF  |. 8B4424 04      MOV EAX,DWORD PTR SS:[ESP+4]
00404FE3  |. F76424 0C      MUL DWORD PTR SS:[ESP+C]
00404FE7  |. 01C1           ADD ECX,EAX
00404FE9  |. 8B0424         MOV EAX,DWORD PTR SS:[ESP]
00404FEC  |. F76424 0C      MUL DWORD PTR SS:[ESP+C]
00404FF0  |. 01CA           ADD EDX,ECX
00404FF2  |. 59             POP ECX
00404FF3  |. 59             POP ECX
00404FF4  \. C2 0800        RETN 8
这个函数比较简单,是在做乘法,在OD里面可以看到它总是会去乘同一个数,那就是你的机器码里的367396.
我们把这个核心函数记为F,我们在前面说过,F(3033,0x2027)=367396,而现在我们验证的时候,却计算的是F(367396,XXXX)=AA,如果结果AA=3033的话就验证成功了,这里的XXXX就是假码的3-6位。相信对密码学比较熟悉的人看了上面的代码已经清楚了。由于应用了递归可能大家不太容易看清楚F函数到底在干什么,请大家务必用简单的XXXX去跟踪一下,我就是这样跟踪分析出来的。
   经过跟踪分析我们发现:F(A,B)的功能就是计算 A^B mod 0x7c74b !!
那么我们现在再回头分析一下:
  3033^ 0x2027 mod 0x7c74b =367396,我们现在要求这样一个数XXXX,使得
  367396^XXXX  mod 0x7c74b =3033,就可以了,也就是:
  3033^(0x2027*XXXX) mode 0x7c74b =3033.
我们知道,a ^fi(p) = 1 mod p, 这里fi()是欧拉函数,也就是说我们只需要找这样的XXXX使得 0x2027*XXXX mod fi(0x7c74b) =1,并且由数论知识我们知道这样的XXXX是一定有的,这是因为0x2027和0x7c74b是互素的。好了通过分解0x7c74b我们得到fi(0x7c74b)后,再通过辗转相除发就可以得到XXXX了。从这里我们可以看出其实只要XXXX是正确的,你的机器码是什么已经不重要了啊!!也就是说所有的注册码都由XXXX决定。这就是我开始时为什么没有具体讲机器码的得来和后续注册码的参与运算的原因!
好了,我们来总结一下,注册码的格式是ABXXXXCD的形式,只有XXXX是固定的,对所有的机器都是一样的,也就是说,程序作者最多可以发送10000个不同的注册码。不知道我讲清楚了没有,为了大家学习验证方便,我在这里给出这个XXXX,它就是7967。其实大家通过穷举都可以算出来的,由于只有4位,只需要穷举10000次就可以了。
  再说两句,由于0x7c74b不是素数,因子比较多,所以只能说是类RSA的运算方式;由于指数0x2027的暴露,使得我们的破解运算变得很方便,而且由于指数固定,导致了注册码的固定,只要一个注册码泄漏,所有的注册码都泄漏了。这是作者的一个败笔。
  其实这种验证方法是很好的,只是作者没有用好。下面来讲讲如何把这种验证算法用好,也就是RSA签名算法的应用:
  1.作者选取两个大素数p,q, N=pq,p和q长度相当,至少都是512比特长度的,这样N就是1024以上长度的了. 选取一个秘密指数e,计算公开指数d,使得
ed mod fi(N) =1,这里fi(N)=(p-1)(q-1). e作者自己保存好,d要放入程序中以后验证要用到。
  2.用户发送机器码A给作者,作者计算 B = A^e mod N, 并把B作为注册码发送给用户。
  3.用户端程序计算 C = B^d mod N, 如果C=A,则接受注册,否则失败。
这里步骤1相当于作者对A进行RSA签名,步骤3就是验签。注意到我们并没有在程序里透露关于e的信息,所以可以做到一机一码,即使知道了某些注册码,也很难攻破整个验证签名系统!另外如果我们的程序被完全反汇编了,敌手了解了全部的验证过程,它想进行破解作出注册机也是很难的,这是因为,它要通过A,B,d来求e(这是最好的情况,因为他未必能获得正确的A,B对,更不用说多对了),他要么是求离散对数问题,要么是直接破解RSA,分解大数N,这都是困难的,因为我们的N太大了。
    但是这个方法还有一个致命的问题,也就是如果他成功的窃取了两对(A,B),我们分别记为(A1,B1),(A2,B2)的话(注意这里这两对可以是一样的),那么它可以伪造一个合法的签名对(A1A2,B1B2)!这是乘法和乘方的运算关系所导致的。对于这个问题,我们就只有配以其他加密方法来辅助解决了。
   好了,终于写完了,不知道我讲清楚了没有,欢迎大家一起讨论。