Plan for Windows 3.01 简要算法分析
【文章标题】: Plan for Windows 3.01 简要算法分析
【文章作者】: BeyondMe
【作者邮箱】: futuring@126.com
【作者主页】: http://hi.baidu.com/beyond0769
【软件名称】: Plan for Windows 3.01
【下载地址】: 自己搜索下载
【保护方式】: 序列号
【编写语言】: VC++
【软件介绍】: Plan for Windows,项目计划软件。它和microsoft project相似,并且兼容于microsoft project。可以支持windows 95/98/me/nt/2000/xp系统。它可用作独立的项目计划工具,或者作为microsoft project文件的浏览器。更可和pocket pc 或 handheld pc上的pocket plan合作,以便在任何时间地点更改计划。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
这几天分析的几个软件难度都不大,很适合我辈新手练习。不过每次都有一些新的体会,和大家分享一下。
老办法:OD载入输入假码看错误提示:
用户名:BeyondMe
假码:1234567890
有错误提示, bp MessagBoxA 下断,晕,没用! 再来 bp MessagBoxW ,成功
跳出到程序领空,两次 Ctrl + F9 很快到达算法关键地方。
引用:
004256A0 . 55 PUSH EBP ; 按钮注册事件
004256A1 . 8D6C24 88 LEA EBP,DWORD PTR SS:[ESP-78]
004256A5 . 6A FF PUSH -1
004256A7 . 68 266A4900 PUSH Plan.00496A26 ; SE 处理程序安装
004256AC . 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
004256B2 . 50 PUSH EAX
004256B3 . 64:8925 00000>MOV DWORD PTR FS:[0],ESP
004256BA . 81EC F4000000 SUB ESP,0F4
004256C0 . 56 PUSH ESI
004256C1 . 57 PUSH EDI
004256C2 . 8BF9 MOV EDI,ECX
004256C4 . 6A 01 PUSH 1
004256C6 . 897D 60 MOV DWORD PTR SS:[EBP+60],EDI
004256C9 . C645 6B 01 MOV BYTE PTR SS:[EBP+6B],1
004256CD . E8 1CD60400 CALL Plan.00472CEE
004256D2 . 85C0 TEST EAX,EAX
004256D4 . 0F84 72020000 JE Plan.0042594C
004256DA . 6A 32 PUSH 32
004256DC . 6A 00 PUSH 0
004256DE . 6A 00 PUSH 0
004256E0 . 8D8D 78FFFFFF LEA ECX,DWORD PTR SS:[EBP-88]
004256E6 . E8 B53F0300 CALL Plan.004596A0
004256EB . BE 9CDA4900 MOV ESI,Plan.0049DA9C
004256F0 . 89B5 78FFFFFF MOV DWORD PTR SS:[EBP-88],ESI
004256F6 . 6A 32 PUSH 32
004256F8 . 6A 00 PUSH 0
004256FA . 6A 00 PUSH 0
004256FC . 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
004256FF . C745 74 00000>MOV DWORD PTR SS:[EBP+74],0
00425706 . E8 953F0300 CALL Plan.004596A0
0042570B . 8975 E8 MOV DWORD PTR SS:[EBP-18],ESI
0042570E . 8B47 74 MOV EAX,DWORD PTR DS:[EDI+74] ; 用户名
00425711 . 8B50 FC MOV EDX,DWORD PTR DS:[EAX-4]
00425714 . 8D77 74 LEA ESI,DWORD PTR DS:[EDI+74]
00425717 . 83E8 10 SUB EAX,10
0042571A . 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8] ; 用户名长度
0042571D . B9 01000000 MOV ECX,1
00425722 . 2BCA SUB ECX,EDX
00425724 . 0BC1 OR EAX,ECX
00425726 . C645 74 01 MOV BYTE PTR SS:[EBP+74],1
0042572A . 7D 09 JGE SHORT Plan.00425735
0042572C . 6A 00 PUSH 0
0042572E . 8BCE MOV ECX,ESI
00425730 . E8 0BC9FDFF CALL Plan.00402040
00425735 > 8B36 MOV ESI,DWORD PTR DS:[ESI]
00425737 . 56 PUSH ESI ; 用户名入栈
00425738 . 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
0042573B . E8 C0430300 CALL Plan.00459B00
00425740 . 8B47 70 MOV EAX,DWORD PTR DS:[EDI+70]
00425743 . 8B50 FC MOV EDX,DWORD PTR DS:[EAX-4]
00425746 . 8D77 70 LEA ESI,DWORD PTR DS:[EDI+70]
00425749 . 83E8 10 SUB EAX,10
0042574C . 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
0042574F . B9 01000000 MOV ECX,1
00425754 . 2BCA SUB ECX,EDX
00425756 . 0BC1 OR EAX,ECX
00425758 . 7D 09 JGE SHORT Plan.00425763
0042575A . 6A 00 PUSH 0
0042575C . 8BCE MOV ECX,ESI
0042575E . E8 DDC8FDFF CALL Plan.00402040
00425763 > 8B36 MOV ESI,DWORD PTR DS:[ESI]
00425765 . 56 PUSH ESI
00425766 . 8D8D 78FFFFFF LEA ECX,DWORD PTR SS:[EBP-88]
0042576C . E8 8F430300 CALL Plan.00459B00
00425771 . BE FCFFFFFF MOV ESI,-4
00425776 . E8 B5330300 CALL Plan.00458B30
0042577B . 85C0 TEST EAX,EAX
0042577D . 8945 5C MOV DWORD PTR SS:[EBP+5C],EAX
00425780 . 0F84 8B010000 JE Plan.00425911
00425786 . 8B4D 74 MOV ECX,DWORD PTR SS:[EBP+74]
00425789 . 68 B83A4B00 PUSH Plan.004B3AB8
0042578E . 51 PUSH ECX
0042578F . 68 7C134600 PUSH Plan.0046137C
00425794 . 6A 03 PUSH 3
00425796 . 50 PUSH EAX
00425797 . E8 54C00300 CALL Plan.004617F0 ; 无关紧要
0042579C . 8BF0 MOV ESI,EAX
0042579E . 83C4 14 ADD ESP,14
004257A1 . 85F6 TEST ESI,ESI
004257A3 . 0F85 55010000 JNZ Plan.004258FE
004257A9 . E8 C2330300 CALL Plan.00458B70 ; 无关紧要
004257AE . 8D95 78FFFFFF LEA EDX,DWORD PTR SS:[EBP-88]
004257B4 . 52 PUSH EDX ; /Arg2
004257B5 . 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18] ; |
004257B8 . 50 PUSH EAX ; |Arg1
004257B9 . B9 28F94B00 MOV ECX,Plan.004BF928 ; |
004257BE . E8 9DC4FDFF CALL Plan.00401C60 ; \明显是关键CALL, F7步入
004257C3 . 84C0 TEST AL,AL
004257C5 . 8B7D 60 MOV EDI,DWORD PTR SS:[EBP+60]
004257C8 . 0F84 BE000000 JE Plan.0042588C ; AL=0的话,跳向失败提示处
004257CE . E8 950E0500 CALL Plan.00476668
004257D3 . 8B10 MOV EDX,DWORD PTR DS:[EAX]
004257D5 . 8BC8 MOV ECX,EAX
004257D7 . FF52 0C CALL DWORD PTR DS:[EDX+C]
004257DA . 83C0 10 ADD EAX,10
004257DD . 8945 58 MOV DWORD PTR SS:[EBP+58],EAX
004257E0 . C645 74 02 MOV BYTE PTR SS:[EBP+74],2
004257E4 . E8 7F0E0500 CALL Plan.00476668
004257E9 . 8B10 MOV EDX,DWORD PTR DS:[EAX]
004257EB . 8BC8 MOV ECX,EAX
004257ED . FF52 0C CALL DWORD PTR DS:[EDX+C]
004257F0 . 83C0 10 ADD EAX,10
004257F3 . 8945 64 MOV DWORD PTR SS:[EBP+64],EAX
004257F6 . 8D45 64 LEA EAX,DWORD PTR SS:[EBP+64]
004257F9 . 50 PUSH EAX
004257FA . 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
004257FD . C645 74 03 MOV BYTE PTR SS:[EBP+74],3
00425801 . E8 5A4A0300 CALL Plan.0045A260
00425806 . 8D8D 78FFFFFF LEA ECX,DWORD PTR SS:[EBP-88]
0042580C . 51 PUSH ECX
0042580D . 8D55 E8 LEA EDX,DWORD PTR SS:[EBP-18]
00425810 . 52 PUSH EDX
00425811 . B9 28F94B00 MOV ECX,Plan.004BF928
00425816 . E8 A5CEFDFF CALL Plan.004026C0
0042581B . 8B45 64 MOV EAX,DWORD PTR SS:[EBP+64]
0042581E . 50 PUSH EAX
0042581F . 8D4D 58 LEA ECX,DWORD PTR SS:[EBP+58]
00425822 . 68 B4020000 PUSH 2B4
00425827 . 51 PUSH ECX
00425828 . E8 63DDFDFF CALL Plan.00403590
0042582D . 83C4 0C ADD ESP,0C
00425830 . 56 PUSH ESI ; /Arg3
00425831 . 8B75 58 MOV ESI,DWORD PTR SS:[EBP+58] ; |
00425834 . 6A 40 PUSH 40 ; |Arg2 = 00000040
00425836 . 56 PUSH ESI ; |Arg1
00425837 . E8 01850500 CALL Plan.0047DD3D ; \Plan.0047DD3D
0042583C . 8B45 64 MOV EAX,DWORD PTR SS:[EBP+64]
0042583F . 83C0 F0 ADD EAX,-10
00425842 . C645 74 02 MOV BYTE PTR SS:[EBP+74],2
00425846 . 8D50 0C LEA EDX,DWORD PTR DS:[EAX+C]
00425849 . 83C9 FF OR ECX,FFFFFFFF
0042584C . F0:0FC10A LOCK XADD DWORD PTR DS:[EDX],ECX ; 锁定前缀
00425850 . 49 DEC ECX
00425851 . 85C9 TEST ECX,ECX
00425853 . 7F 08 JG SHORT Plan.0042585D
00425855 . 8B08 MOV ECX,DWORD PTR DS:[EAX]
00425857 . 8B11 MOV EDX,DWORD PTR DS:[ECX]
00425859 . 50 PUSH EAX
0042585A . FF52 04 CALL DWORD PTR DS:[EDX+4]
0042585D > 8D46 F0 LEA EAX,DWORD PTR DS:[ESI-10]
00425860 . C645 74 01 MOV BYTE PTR SS:[EBP+74],1
00425864 . 8D48 0C LEA ECX,DWORD PTR DS:[EAX+C]
00425867 . 83CA FF OR EDX,FFFFFFFF
0042586A . F0:0FC111 LOCK XADD DWORD PTR DS:[ECX],EDX ; 锁定前缀
0042586E . 4A DEC EDX
0042586F . 85D2 TEST EDX,EDX
00425871 . 7F 7D JG SHORT Plan.004258F0
00425873 . 8B08 MOV ECX,DWORD PTR DS:[EAX]
00425875 . 8B11 MOV EDX,DWORD PTR DS:[ECX]
00425877 . 50 PUSH EAX
00425878 . FF52 04 CALL DWORD PTR DS:[EDX+4]
0042587B . 8B45 5C MOV EAX,DWORD PTR SS:[EBP+5C]
0042587E . 50 PUSH EAX
0042587F . E8 0C330300 CALL Plan.00458B90
00425884 . 83C4 04 ADD ESP,4
00425887 . E9 94000000 JMP Plan.00425920
0042588C > 8B77 78 MOV ESI,DWORD PTR DS:[EDI+78]
0042588F . 46 INC ESI
00425890 . 8BC6 MOV EAX,ESI
00425892 . 8BCE MOV ECX,ESI
00425894 . 0FAFC8 IMUL ECX,EAX
00425897 . 69C9 D0070000 IMUL ECX,ECX,7D0 ; 注册失败会死机2秒钟,不知为什么老外的注册验证总喜欢用这玩意儿。
0042589D . 51 PUSH ECX ; /Timeout
0042589E . 8977 78 MOV DWORD PTR DS:[EDI+78],ESI ; |
004258A1 . FF15 E0D34900 CALL DWORD PTR DS:[<&KERNEL32.Sleep>] ; \Sleep
004258A7 . 837F 78 03 CMP DWORD PTR DS:[EDI+78],3
004258AB . 6A FF PUSH -1
004258AD . 6A 30 PUSH 30
004258AF . 7D 1C JGE SHORT Plan.004258CD
004258B1 . 68 91020000 PUSH 291
004258B6 . E8 A4840500 CALL Plan.0047DD5F ; 错误信息框
004258BB . 8B45 5C MOV EAX,DWORD PTR SS:[EBP+5C]
004258BE . 50 PUSH EAX
004258BF . C645 6B 00 MOV BYTE PTR SS:[EBP+6B],0
004258C3 . E8 C8320300 CALL Plan.00458B90
004258C8 . 83C4 04 ADD ESP,4
004258CB . EB 53 JMP SHORT Plan.00425920
004258CD > 68 B9020000 PUSH 2B9
004258D2 . E8 88840500 CALL Plan.0047DD5F
004258D7 . E8 14FDFDFF CALL Plan.004055F0
004258DC . 85C0 TEST EAX,EAX
004258DE . 74 10 JE SHORT Plan.004258F0
004258E0 . 8B50 1C MOV EDX,DWORD PTR DS:[EAX+1C]
004258E3 . 6A 00 PUSH 0 ; /lParam = 0
004258E5 . 6A 00 PUSH 0 ; |wParam = 0
004258E7 . 6A 10 PUSH 10 ; |Message = WM_CLOSE
004258E9 . 52 PUSH EDX ; |hWnd
004258EA . FF15 FCD64900 CALL DWORD PTR DS:[<&USER32.PostMessageW>; \PostMessageW
004258F0 > 8B45 5C MOV EAX,DWORD PTR SS:[EBP+5C]
004258F3 . 50 PUSH EAX
004258F4 . E8 97320300 CALL Plan.00458B90
004258F9 . 83C4 04 ADD ESP,4
004258FC . EB 22 JMP SHORT Plan.00425920
004258FE > 8B45 5C MOV EAX,DWORD PTR SS:[EBP+5C]
00425901 . 85C0 TEST EAX,EAX
00425903 . 8B7D 60 MOV EDI,DWORD PTR SS:[EBP+60]
00425906 . 74 09 JE SHORT Plan.00425911
00425908 . 50 PUSH EAX
00425909 . E8 42320300 CALL Plan.00458B50
0042590E . 83C4 04 ADD ESP,4
00425911 > 56 PUSH ESI
00425912 . B9 28F94B00 MOV ECX,Plan.004BF928
00425917 . E8 14DDFDFF CALL Plan.00403630
0042591C . C645 6B 00 MOV BYTE PTR SS:[EBP+6B],0
00425920 > 8A45 6B MOV AL,BYTE PTR SS:[EBP+6B]
00425923 . 84C0 TEST AL,AL
00425925 . 74 07 JE SHORT Plan.0042592E
00425927 . 8BCF MOV ECX,EDI
00425929 . E8 13B90400 CALL Plan.00471241
0042592E > 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18]
00425931 . C645 74 00 MOV BYTE PTR SS:[EBP+74],0
00425935 . E8 86300300 CALL Plan.004589C0
0042593A . 8D8D 78FFFFFF LEA ECX,DWORD PTR SS:[EBP-88]
00425940 . C745 74 FFFFF>MOV DWORD PTR SS:[EBP+74],-1
00425947 . E8 74300300 CALL Plan.004589C0
0042594C > 8B4D 6C MOV ECX,DWORD PTR SS:[EBP+6C]
0042594F . 5F POP EDI
00425950 . 64:890D 00000>MOV DWORD PTR FS:[0],ECX
00425957 . 5E POP ESI
00425958 . 83C5 78 ADD EBP,78
0042595B . 8BE5 MOV ESP,EBP
0042595D . 5D POP EBP
0042595E . C3 RETN
主算法过程没有做过多重要东西,调试过程中F8快速单步看返回信息,基本上能判断一些CALL是否关键CALL,
于是很多无关紧要的CALL我就不做注释了。有兴趣的朋友可以跳进详细分析。
看关键的东东吧。
004257BE . E8 9DC4FDFF CALL Plan.00401C60 ; \明显是关键CALL, F7步入
引用:
00401C60 /$ 6A FF PUSH -1 ; 核心算法过程
00401C62 |. 68 404F4900 PUSH Plan.00494F40 ; SE 处理程序安装
00401C67 |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
00401C6D |. 50 PUSH EAX
00401C6E |. 64:8925 00000>MOV DWORD PTR FS:[0],ESP
00401C75 |. 83EC 44 SUB ESP,44
00401C78 |. 53 PUSH EBX
00401C79 |. 55 PUSH EBP
00401C7A |. 56 PUSH ESI
00401C7B |. 57 PUSH EDI
00401C7C |. 6A 05 PUSH 5
00401C7E |. 33F6 XOR ESI,ESI
00401C80 |. 56 PUSH ESI
00401C81 |. 894C24 18 MOV DWORD PTR SS:[ESP+18],ECX
00401C85 |. 56 PUSH ESI
00401C86 |. 8D4C24 48 LEA ECX,DWORD PTR SS:[ESP+48]
00401C8A |. BD CE560000 MOV EBP,56CE ; EBP = $56CE = 2222
00401C8F |. E8 0C7A0500 CALL Plan.004596A0
00401C94 |. C74424 3C A8D>MOV DWORD PTR SS:[ESP+3C],Plan.0049DAA8
00401C9C |. 8B7C24 64 MOV EDI,DWORD PTR SS:[ESP+64]
00401CA0 |. 8BCF MOV ECX,EDI
00401CA2 |. 897424 5C MOV DWORD PTR SS:[ESP+5C],ESI
00401CA6 |. E8 957E0500 CALL Plan.00459B40
00401CAB |. 8B5C24 68 MOV EBX,DWORD PTR SS:[ESP+68]
00401CAF |. 8BCB MOV ECX,EBX
00401CB1 |. E8 8A7E0500 CALL Plan.00459B40
00401CB6 |. 68 B0D04B00 PUSH Plan.004BD0B0 ; (UNICODE "www.appzplanet.com"
00401CBB |. 8D4C24 1C LEA ECX,DWORD PTR SS:[ESP+1C]
00401CBF |. E8 7C780500 CALL Plan.00459540
00401CC4 |. 66:397424 1C CMP WORD PTR SS:[ESP+1C],SI
00401CC9 |. C64424 5C 01 MOV BYTE PTR SS:[ESP+5C],1
00401CCE |. 74 4B JE SHORT Plan.00401D1B
00401CD0 |> 8D4424 14 /LEA EAX,DWORD PTR SS:[ESP+14]
00401CD4 |. 50 |PUSH EAX
00401CD5 |. 8D4C24 1C |LEA ECX,DWORD PTR SS:[ESP+1C]
00401CD9 |. 51 |PUSH ECX
00401CDA |. 8BCF |MOV ECX,EDI
00401CDC |. E8 CF750500 |CALL Plan.004592B0
00401CE1 |. 84C0 |TEST AL,AL
00401CE3 |. 0F85 26010000 |JNZ Plan.00401E0F
00401CE9 |. 8D4C24 18 |LEA ECX,DWORD PTR SS:[ESP+18]
00401CED |. 884424 5C |MOV BYTE PTR SS:[ESP+5C],AL
00401CF1 |. E8 CA6C0500 |CALL Plan.004589C0
00401CF6 |. 46 |INC ESI
00401CF7 |. 0FB7C6 |MOVZX EAX,SI
00401CFA |. 8D1480 |LEA EDX,DWORD PTR DS:[EAX+EAX*4]
00401CFD |. 8D04D5 B0D04B>|LEA EAX,DWORD PTR DS:[EDX*8+4BD0B0] ; 检查用户名黑名单
00401D04 |. 50 |PUSH EAX
00401D05 |. 8D4C24 1C |LEA ECX,DWORD PTR SS:[ESP+1C]
00401D09 |. E8 32780500 |CALL Plan.00459540
00401D0E |. 66:837C24 1C >|CMP WORD PTR SS:[ESP+1C],0
00401D14 |. C64424 5C 01 |MOV BYTE PTR SS:[ESP+5C],1
00401D19 |.^ 75 B5 \JNZ SHORT Plan.00401CD0
00401D1B |> 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18]
00401D1F |. C64424 5C 00 MOV BYTE PTR SS:[ESP+5C],0
00401D24 |. E8 976C0500 CALL Plan.004589C0
00401D29 |. 33C0 XOR EAX,EAX ; 初始化计数器为0
00401D2B |. 66:8B47 04 MOV AX,WORD PTR DS:[EDI+4] ; AX=Length(Name)
00401D2F |. 33F6 XOR ESI,ESI
00401D31 |. 66:85C0 TEST AX,AX
00401D34 |. 76 2E JBE SHORT Plan.00401D64
00401D36 |> 66:83FE 05 /CMP SI,5 ; SI=5吗
00401D3A |. 75 09 |JNZ SHORT Plan.00401D45
00401D3C |. 66:3D 0A00 |CMP AX,0A
00401D40 |. 76 03 |JBE SHORT Plan.00401D45
00401D42 |. 8D70 FB |LEA ESI,DWORD PTR DS:[EAX-5] ; if (AX>=10) then ESI=AX - 5
00401D45 |> 0FB7CE |MOVZX ECX,SI ; ECX = 计数器
00401D48 |. 51 |PUSH ECX
00401D49 |. 8BCF |MOV ECX,EDI
00401D4B |. E8 50780500 |CALL Plan.004595A0 ; EAX = ord(Name[n]),
00401D50 |. 0FB700 |MOVZX EAX,WORD PTR DS:[EAX] ; 注意Name以WideString形式保存
00401D53 |. 8DAC68 E0FF00>|LEA EBP,DWORD PTR DS:[EAX+EBP*2+FFE0] ; EBP:=EBP * 2 + EAX + $FFE0;
00401D5A |. 66:8B47 04 |MOV AX,WORD PTR DS:[EDI+4] ; [EDI+4]=Length(Name)
00401D5E |. 46 |INC ESI ; N:=N+1
00401D5F |. 66:3BF0 |CMP SI,AX ; if N < Length(Name) then
00401D62 |.^ 72 D2 \JB SHORT Plan.00401D36 ; 循环,结果只在在EBP
00401D64 |> 8D5424 30 LEA EDX,DWORD PTR SS:[ESP+30]
00401D68 |. 52 PUSH EDX ; /Arg1
00401D69 |. B9 78DB4900 MOV ECX,Plan.0049DB78 ; |
00401D6E |. E8 3DFBFFFF CALL Plan.004018B0 ; \??
00401D73 |. 50 PUSH EAX
00401D74 |. 8D4C24 28 LEA ECX,DWORD PTR SS:[ESP+28]
00401D78 |. C64424 60 02 MOV BYTE PTR SS:[ESP+60],2
00401D7D |. E8 8E770500 CALL Plan.00459510 ; ??
00401D82 |. 8D4C24 30 LEA ECX,DWORD PTR SS:[ESP+30]
00401D86 |. C64424 5C 04 MOV BYTE PTR SS:[ESP+5C],4
00401D8B |. E8 306C0500 CALL Plan.004589C0
00401D90 |. 0FB7C5 MOVZX EAX,BP ; EAX=取 EBP 的低位
00401D93 |. 50 PUSH EAX
00401D94 |. 51 PUSH ECX
00401D95 |. 8BC4 MOV EAX,ESP
00401D97 |. 8D5424 44 LEA EDX,DWORD PTR SS:[ESP+44]
00401D9B |. 8D4C24 2C LEA ECX,DWORD PTR SS:[ESP+2C]
00401D9F |. 896424 6C MOV DWORD PTR SS:[ESP+6C],ESP
00401DA3 |. 52 PUSH EDX
00401DA4 |. 8908 MOV DWORD PTR DS:[EAX],ECX
00401DA6 |. E8 65880500 CALL Plan.0045A610 ; ??
00401DAB |. 83C4 0C ADD ESP,0C
00401DAE |. 53 PUSH EBX
00401DAF |. 8D4C24 40 LEA ECX,DWORD PTR SS:[ESP+40]
00401DB3 |. E8 18710500 CALL Plan.00458ED0 ; 比较函数←从这里找线索
00401DB8 |. 84C0 TEST AL,AL ; AL必须等于0
00401DBA 74 23 JE SHORT Plan.00401DDF ; 不能跳,
00401DBC |. 8D4C24 24 LEA ECX,DWORD PTR SS:[ESP+24]
00401DC0 |. C64424 5C 00 MOV BYTE PTR SS:[ESP+5C],0
00401DC5 |. E8 F66B0500 CALL Plan.004589C0
00401DCA |. 8D4C24 3C LEA ECX,DWORD PTR SS:[ESP+3C]
00401DCE |. C74424 5C FFF>MOV DWORD PTR SS:[ESP+5C],-1
00401DD6 |. E8 E56B0500 CALL Plan.004589C0
00401DDB |. B0 01 MOV AL,1 ; AL标志位赋值为1,表示通过
00401DDD |. EB 7A JMP SHORT Plan.00401E59
00401DDF |> 8B4C24 10 MOV ECX,DWORD PTR SS:[ESP+10]
00401DE3 |. 53 PUSH EBX
00401DE4 |. 57 PUSH EDI
00401DE5 |. E8 96F5FFFF CALL Plan.00401380
00401DEA |. 8D4C24 24 LEA ECX,DWORD PTR SS:[ESP+24]
00401DEE |. 8AD8 MOV BL,AL
00401DF0 |. C64424 5C 00 MOV BYTE PTR SS:[ESP+5C],0
00401DF5 |. E8 C66B0500 CALL Plan.004589C0
00401DFA |. 8D4C24 3C LEA ECX,DWORD PTR SS:[ESP+3C]
00401DFE |. C74424 5C FFF>MOV DWORD PTR SS:[ESP+5C],-1
00401E06 |. E8 B56B0500 CALL Plan.004589C0
00401E0B |. 8AC3 MOV AL,BL
00401E0D |. EB 4A JMP SHORT Plan.00401E59
00401E0F |> 6A FF PUSH -1
00401E11 |. 6A 10 PUSH 10
00401E13 |. 68 BA020000 PUSH 2BA
00401E18 |. E8 42BF0700 CALL Plan.0047DD5F
00401E1D |. 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10]
00401E21 |. 8B40 1C MOV EAX,DWORD PTR DS:[EAX+1C]
00401E24 |. 85C0 TEST EAX,EAX
00401E26 |. 74 10 JE SHORT Plan.00401E38
00401E28 |. 8B48 1C MOV ECX,DWORD PTR DS:[EAX+1C]
00401E2B |. 6A 00 PUSH 0 ; /lParam = 0
00401E2D |. 6A 00 PUSH 0 ; |wParam = 0
00401E2F |. 6A 10 PUSH 10 ; |Message = WM_CLOSE
00401E31 |. 51 PUSH ECX ; |hWnd
00401E32 |. FF15 44D64900 CALL DWORD PTR DS:[<&USER32.SendMessageW>; \SendMessageW
00401E38 |> 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18]
00401E3C |. C64424 5C 00 MOV BYTE PTR SS:[ESP+5C],0
00401E41 |. E8 7A6B0500 CALL Plan.004589C0
00401E46 |. 8D4C24 3C LEA ECX,DWORD PTR SS:[ESP+3C]
00401E4A |. C74424 5C FFF>MOV DWORD PTR SS:[ESP+5C],-1
00401E52 |. E8 696B0500 CALL Plan.004589C0
00401E57 |. 32C0 XOR AL,AL
00401E59 |> 8B4C24 54 MOV ECX,DWORD PTR SS:[ESP+54]
00401E5D |. 5F POP EDI
00401E5E |. 5E POP ESI
00401E5F |. 5D POP EBP
00401E60 |. 64:890D 00000>MOV DWORD PTR FS:[0],ECX
00401E67 |. 5B POP EBX
00401E68 |. 83C4 50 ADD ESP,50
00401E6B \. C2 0800 RETN 8
这个过程前半部分思路比较清晰:通过一个循环来检测用户名是否是黑名单里的用户名,是的话提示这是盗版用户名。
通过循环里重要一句可以知道 :
00401CFD |. 8D04D5 B0D04B>|LEA EAX,DWORD PTR DS:[EDX*8+4BD0B0] ; 检查用户名黑名单
其中 DS:[EDX*8+4BD0B0] 指向内存块:
引用:
004BD0D8 77 00 77 00 77 00 2E 00 66 00 72 00 65 00 65 00 www.free
004BD0E8 73 00 65 00 72 00 69 00 61 00 6C 00 73 00 2E 00 serials.
004BD0F8 63 00 6F 00 6D 00 00 00 66 00 72 00 65 00 65 00 com.free
004BD108 73 00 65 00 72 00 69 00 61 00 6C 00 73 00 2E 00 serials.
004BD118 63 00 6F 00 6D 00 00 00 00 00 00 00 00 00 00 00 com.....
004BD128 6D 00 6F 00 6F 00 6E 00 6F 00 69 00 2E 00 74 00 moonoi.t
004BD138 6B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 k.......
004BD148 00 00 00 00 00 00 00 00 46 00 72 00 65 00 65 00 ....Free
004BD158 20 00 50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 Program
004BD168 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004BD178 5A 00 6F 00 6F 00 6D 00 20 00 5B 00 52 00 45 00 Zoom [RE
004BD188 56 00 45 00 4E 00 47 00 45 00 5D 00 00 00 00 00 VENGE]..
004BD198 00 00 00 00 00 00 00 00 41 00 76 00 65 00 6E 00 ....Aven
004BD1A8 67 00 65 00 72 00 20 00 2F 00 2F 00 20 00 52 00 ger // R
004BD1B8 45 00 56 00 45 00 4E 00 47 00 45 00 00 00 00 00 EVENGE..
004BD1C8 52 00 45 00 56 00 45 00 4E 00 47 00 45 00 20 00 REVENGE
004BD1D8 43 00 72 00 65 00 77 00 00 00 00 00 00 00 00 00 Crew....
004BD1E8 00 00 00 00 00 00 00 00 54 00 65 00 61 00 6D 00 ....Team
004BD1F8 20 00 52 00 45 00 56 00 45 00 4E 00 47 00 45 00 REVENGE
004BD208 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004BD218 61 00 53 00 78 00 50 00 44 00 41 00 00 00 00 00 aSxPDA..
004BD228 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004BD238 00 00 00 00 00 00 00 00 43 00 53 00 43 00 50 00 ....CSCP
004BD248 44 00 41 00 00 00 00 00 00 00 00 00 00 00 00 00 DA......
004BD258 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........
004BD268 61 00 5F 00 53 00 5F 00 78 00 5F 00 50 00 5F 00 a_S_x_P_
004BD278 44 00 5F 00 41 00 00 00 00 00 00 00 00 00 00 00 D_A.....
其实可以在00401CFD偏移处下断,就可以在堆栈里看到待检测的黑名单了,我已经把它记下来,在后期编写注册机的时候
或以考虑也把它过滤掉。
引用:
"www.freeserials.com"
"freeserials.com"
"moonoi.tk"
Free Program"
"Zoom [REVENGE]"
"Avenger // REVENGE"
"REVENGE Crew"
"Team REVENGE"
"aSxPDA"
"CSCPDA"
"a_S_x_P_D_A"
呵呵,看样子是一些国际上有名的破解组织成员的名字。
检测黑名单后,就开始对用户名进行计算了 。下面再COPY这个循环下来对照一下
引用:
00401D29 |. 33C0 XOR EAX,EAX ; 初始化计数器为0
00401D2B |. 66:8B47 04 MOV AX,WORD PTR DS:[EDI+4] ; AX=Length(Name)
00401D2F |. 33F6 XOR ESI,ESI
00401D31 |. 66:85C0 TEST AX,AX
00401D34 |. 76 2E JBE SHORT Plan.00401D64
00401D36 |> 66:83FE 05 /CMP SI,5 ; SI=5吗
00401D3A |. 75 09 |JNZ SHORT Plan.00401D45
00401D3C |. 66:3D 0A00 |CMP AX,0A
00401D40 |. 76 03 |JBE SHORT Plan.00401D45
00401D42 |. 8D70 FB |LEA ESI,DWORD PTR DS:[EAX-5] ; if (AX>=10) then ESI=AX - 5
00401D45 |> 0FB7CE |MOVZX ECX,SI ; ECX = 计数器
00401D48 |. 51 |PUSH ECX
00401D49 |. 8BCF |MOV ECX,EDI
00401D4B |. E8 50780500 |CALL Plan.004595A0 ; EAX = ord(Name[n]),
00401D50 |. 0FB700 |MOVZX EAX,WORD PTR DS:[EAX] ; 注意Name以WideString形式保存
00401D53 |. 8DAC68 E0FF00>|LEA EBP,DWORD PTR DS:[EAX+EBP*2+FFE0] ; EBP:=EBP * 2 + EAX + $FFE0;
00401D5A |. 66:8B47 04 |MOV AX,WORD PTR DS:[EDI+4] ; [EDI+4]=Length(Name)
00401D5E |. 46 |INC ESI ; N:=N+1
00401D5F |. 66:3BF0 |CMP SI,AX ; if N < Length(Name) then
00401D62 |.^ 72 D2 \JB SHORT Plan.00401D36 ; 循环,结果只在在EBP
这个看似简单的循环用Delphi还原的时候还真花了我不少时间,为了最大程序上接近源汇编代码。
里面有几个要注意的地方,看完源代码后再说。
复制内容到剪贴板
代码:var
EBP: LongWord;
SI, AX: integer;
begin
EBP := $56CE;
SI := 0;
AX := Length(Name);
repeat
if SI = 5 then
if AX >= 10 then SI := AX -5 ;
EBP := ord(Name[SI+1]) + EBP * 2 + $FFE0;
inc(SI);
until SI > (AX-1);
end;
1、首先是最后一句循环的次数,一开始用 until SI > AX ,出来的结果总是有问题,原来是多循环了一次。
2、其次函数的定义,一开始把 Name定义成 string 类型,结果发现用中文用户名去注册时,返回结果严重错误。
才发现,原来这是个支持unicode 版本的软件,必须把 Name 定义成 WideString ,问题解决。
至此为此,这个循环后面的代码出现好几个CALL,跟进去结果什么都没有发现,连堆栈和内存都没有什么可疑的地方,
却很快到达关键比较处,非常郁闷,不解决这个问题无法做出注册机。
结果来了灵感,既然过程不清楚也不想去理,就看结果在比较些什么来决定是否通过验证,于是把目光放到最后一个关键比较CALL里面。
这是一个很容易被遗忘的函数,因为它是系统函数,而且不是明码比较。进入这个系统函数看看
00401DB3 |. E8 18710500 CALL Plan.00458ED0 ; 比较函数←从这里找线索
引用:
00458ED0 /$ 53 PUSH EBX
00458ED1 |. 8B5C24 08 MOV EBX,DWORD PTR SS:[ESP+8]
00458ED5 |. 56 PUSH ESI
00458ED6 |. 8BF1 MOV ESI,ECX
00458ED8 |. 66:8B4E 04 MOV CX,WORD PTR DS:[ESI+4] ; 注意CX的值 = 5
00458EDC |. 32C0 XOR AL,AL
00458EDE |. 66:3B4B 04 CMP CX,WORD PTR DS:[EBX+4] ; 用户名长度=10
00458EE2 |. 57 PUSH EDI
00458EE3 |. 75 39 JNZ SHORT Plan.00458F1E ; 如果长度不等于5就失败,修改ZF,让它跳过
00458EE5 |. 8B16 MOV EDX,DWORD PTR DS:[ESI]
00458EE7 |. 8BCE MOV ECX,ESI
00458EE9 |. FF52 04 CALL DWORD PTR DS:[EDX+4]
00458EEC |. 8BF8 MOV EDI,EAX
00458EEE |. 8B03 MOV EAX,DWORD PTR DS:[EBX]
00458EF0 |. 8BCB MOV ECX,EBX
00458EF2 |. FF50 04 CALL DWORD PTR DS:[EAX+4]
00458EF5 |. 0FB756 04 MOVZX EDX,WORD PTR DS:[ESI+4]
00458EF9 |. 33C9 XOR ECX,ECX
00458EFB |. 85D2 TEST EDX,EDX
00458EFD |. 8BD8 MOV EBX,EAX
00458EFF |. B0 01 MOV AL,1
00458F01 |. 7E 1B JLE SHORT Plan.00458F1E
00458F03 |> 66:8B37 /MOV SI,WORD PTR DS:[EDI] ; 注意SI的值,看堆栈,把每次的值记录下来。结果记为R
00458F06 |. 66:3B33 |CMP SI,WORD PTR DS:[EBX] ; 这是假码
00458F09 75 11 |JNZ SHORT Plan.00458F1C ; 不相等的话,就失败。把这句Nop掉。
00458F0B |. 41 |INC ECX
00458F0C |. 83C7 02 |ADD EDI,2
00458F0F |. 83C3 02 |ADD EBX,2
00458F12 |. 3BCA |CMP ECX,EDX
00458F14 |.^ 7C ED \JL SHORT Plan.00458F03
00458F16 |. 5F POP EDI
00458F17 |. 5E POP ESI
00458F18 |. 5B POP EBX
00458F19 |. C2 0400 RETN 4
注意
00458F03 |> 66:8B37 /MOV SI,WORD PTR DS:[EDI] ; 注意SI的值,看堆栈,把每次的值记录下来。结果记为R
这一句在比较些什么。记录下来的结果是
第一次 $30
第二次 $31
第三次 $31
第四次 $33
第五次 $35
没啦 ~~~
可以得知,和注册码在进行比较的字符串是 01135 ,难道就是传说中的注册码了吗??
于是用这个注册码一试,注册成功!!
那01135怎么来,回头看看那个对用户名进行计算的循环的结果 EBP,取其低位 BP,这不是EBP的十进制字符值吗?只不是过前面补0让它
凑够5位数??不用多想,注册机已经出来了。
复制内容到剪贴板
代码:const
BlackNames :array[0..10] of string =(
'www.freeserials.com',
'freeserials.com',
'moonoi.tk',
'Free Program',
'Zoom [REVENGE]',
'Avenger // REVENGE',
'REVENGE Crew',
'Team REVENGE',
'aSxPDA',
'CSCPDA',
'a_S_x_P_D_A');
implementation
{$R *.dfm}
function KeyGen(Name: WideString): string;
//把参数定义为WideString类型使得这个注册机支持中文名注册
var
EBP: LongWord;
BP: Word;
SI, AX: integer;
n:integer;
begin
for n:= 0 to 10 do //过滤黑名单
begin
if BlackNames[n]=Name then
begin
Result:='用户名已经被列入黑名单!';
Exit;
end;
end;
EBP := $56CE;
SI := 0;
AX := Length(Name);
repeat
if SI = 5 then
if AX >= 10 then SI := Ax - 5;
EBP := ord(Name[SI+1]) + EBP * 2 + $FFE0;
inc(SI);
until SI > (AX-1); //注意这里的循环次数
BP := EBP; //取EBP的低位
Result := Format('%.5d', [BP]);
end;
用上面代码算几个码子给大家试试
用户名:BeyondMe
注册码:01135
用户名:海浪轻风
注册码:17444
用户名:www.unpack.cn
注册码:32308
心得:方法决定效率
--------------------------------------------------------------------------------
【版权声明】: 本文原创于http://www.unpacnk.cn, 转载请注明作者并保持文章的完整, 谢谢!
20090407 22:16:56