【文章标题】: 批量缩略图工具 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)!这是乘法和乘方的运算关系所导致的。对于这个问题,我们就只有配以其他加密方法来辅助解决了。
好了,终于写完了,不知道我讲清楚了没有,欢迎大家一起讨论。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)