首页
社区
课程
招聘
继续逆向之旅――几天以前在本版物色好的一个Crackme
发表于: 2006-8-11 18:35 5778

继续逆向之旅――几天以前在本版物色好的一个Crackme

2006-8-11 18:35
5778

可惜不幸沉溺于游戏,没有及时把它搞出来

下载地址:http://bbs.pediy.com/showthread.php?threadid=29982

使用工具:
 反编译工具:IDA,Resource Hacker
 程序开发包:MASM32

  这是一个“正宗”的窗口程序,不象以往的大多数Crackme只是一个对话框,这里有着从注册窗口类到
建立消息循环的完整过程。有个特点就是该程序只允许运行一个实例,在初始化的时候有用FindWindow检
测是否存在基于自身类名的窗口运行,若已有一个这样的窗口,就不会继续建立第二个窗口。

  创建窗口使用的CreateWindowEx中的两个参数nWidth和nHeight,乍一看令人费解。这两个参数的意义
是指定窗口的大小,以像素为单位,但是现在它们的值都是8000h,而整个屏幕的大小通常也不过是
400h * 300h,怎么显示得下这么大的窗口?并且这个数值也不是CW_USEDEFAULT,CW_USEDEFAULT的值是
80000000h呀!另一方面,实际执行一下程序会发现,窗口实际上还是比较小的,既没有显示一个大到荒唐
的窗口,也不是指定CW_USEDEFAULT的效果。那么这究竟是怎么回事?原来,在建立窗口的WM_CREATE消息
之前先要处理WM_GETMINMAXINFO消息,而窗口过程中对这个消息的处理方式是把窗口的MinTrackSize和
MaxTrackSize(这两个词不知道怎么翻译,意思就是通过拖动边框使得窗口所能达到的最小和最大尺寸)
都设置为280 * 160,正是由于这里设置了正确的数值,窗口在显示的时候才能是合理的大小。在源程序里
我把这两个参数换成了它们本来应该是的数值,虽然这并没有实质性的改进,起码看着直观点吧!

  而在UpdateWindow后面这句InvalidateRect就更令人困惑了:它的第一个参数是dword ptr [ebp+8],
这明显是引用子程序参数的方法,但这是位于主程序中,何来的参数?如果把主程序看成Windows系统调用
的一个子程序,那也勉强可以解释过去,问题是当前的[ebp+8]是什么数值呢?用调试器跟踪会发现它的值
是401000h之类的数值,并不是哪个窗口的句柄。事实上这一句调用是否必要都成很大问题,前面不是已经
有UpdateWindow了吗?在源程序里我姑且保留这一句,但是把它注释掉了。

  接下来进入消息循环,我们将注意力转移到窗口过程上,这个程序中的窗口过程大致可以分为三块:
主窗口的,“注册”对话框的和“关于”对话框的回调过程。在主窗口的“Help”菜单中选择其中的两项
可以分别弹出后面两个对话框。主窗口中的消息分支可以简单归纳为:WM_COMMAND――根据具体内容做进
一步处理;WM_GETMINMAXINFO――设置固定的窗口大小(哪怕最大化了也还是那么大);WM_CREATE或
WM_SIZE――忽略;WM_DESTROY――PostQuitMessage;其他――DefWindowProc。至于WM_L(R)BUTTONDOWN
只要不设计相应分支的代码,一般也是没事发生,可不予考虑。

  “注册”对话框只负责取得用户名和序列号等信息,它通过DialogBoxParam向主调程序返回一个值表
示取得注册信息是否成功,如果取用户名失败或用户名是空串,则返回失败,主调程序就不会继续验证注
册信息,也就没事发生。此外,从程序中看来,在“注册”对话框中每点击一次,整个对话框都会被刷新
一遍,当计算机的运行比较“卡”的时候,可以明显的看到有闪烁。

  “关于”对话框十分简单,这里就略过不提了。

  注册信息的验证还是在主窗口的WM_COMMAND消息分支里完成的,其中sub_40137E这个过程的作用是检
查用户名的各字符,如果有小于'A'的则判为非法,对大于或等于'Z'的那些则减20h,处理完毕以后再调用
sub_4013C2计算用户名的各字符和,这个和与5678h异或后存入eax;然后取得序列号字符串并且各字符减
去'0'后,第一个字符乘以10后加上第二个字符,这个和再乘以10,再加上第三个字符……如此重复一直到
加完最后一个字符,最后的和与1234h异或后存入edi,然后注册成功与否,则看eax是否等于edi。

  从算法的描述上看,作者的意图极有可能是:要将用户名中的小写字母转化为大写字母后再计算字符
串和;并且打算把序列号看成一个十进制整数。但是由于编写程序时粗心大意或者别的原因,导致算法上
存在缺陷,以至于不能实现其初衷。譬如,假如输入的用户名是"PEDIZ"(故意写成Z是为了演示算法的逻
辑问题),本来大写字母应该不变,但是实际上'Z'却要减掉20h――注意到sub_40137E中与'Z'比较后用的
指令是jnb而不是ja――这样字符串的和应该是:

     'P'+'E'+'D'+'I'+'Z'-20h = 15Ch

这个值与1234h xor 5678h――也就是444Ch――异或的结果是4510h,转换成十进制是17680。当然我们用
17680作为序列号输入也可以注册成功,但我们现在打算把17680看成“16千15百18十”――注意:“看成
十进制整数”是没错,可没有说每个数码都只能在0到9之间!想象一下旧式七珠大算盘上某一位的所有算
珠都靠梁的情况――那么:

     16 + '0' = '@'
          15 + '0' = '?'
          18 + '0' = 'B'

换言之,"@?B0"也是正确的序列号!只要符合要求,对于同一个用户名,还可以构造出许多不同的稀奇古
怪的序列号。由于这只是算法的欠严谨,而不是矛盾,我没有去修正它。

  上传内容:1.asm        源码
              1.rc         资源脚本
              Icon_1.ico   图标
              Bitmap_1.bmp 位图资源

====================以下是代码==================
; enum Control_IDs
ICO_MAIN         = 100
ID_MENUEXIT         = 101
ID_MENUREG         = 102
ID_MENUABOUT         = 103
EDT_NAME         = 1000
EDT_SERIAL         = 1001
ID_CHECK         = 1002
ID_CANCEL         = 1003

                public start
start                proc near
                push        NULL                ; lpModuleName
                call        GetModuleHandleA
                mov        ds:hInstance, eax
                push        NULL                ; lpWindowName
                push        offset szMyClass ; "No need to disasm the code!"
                call        FindWindowA
                or        eax, eax        ; 只允许运行一个实例
                jz        short loc_40101D
                retn

loc_40101D:                                ; CODE XREF: start+1Aj
                mov        ds:stMyWndClass.style, CS_VREDRAW or CS_HREDRAW        or CS_GLOBALCLASS
                mov        ds:stMyWndClass.lpfnWndProc, offset _ProcWinMain
                mov        ds:stMyWndClass.cbClsExtra, 0
                mov        ds:stMyWndClass.cbWndExtra, 0
                mov        eax, ds:hInstance
                mov        ds:stMyWndClass.hInstance, eax
                push        ICO_MAIN        ; lpIconName
                push        eax                ; hInstance
                call        LoadIconA
                mov        ds:stMyWndClass.hIcon, eax
                push        IDC_ARROW        ; lpCursorName
                push        NULL                ; hInstance
                call        LoadCursorA
                mov        ds:stMyWndClass.hCursor, eax
                mov        ds:stMyWndClass.hbrBackground, COLOR_MENU + 1
                mov        ds:stMyWndClass.lpszMenuName, offset szIdMenu ;        "MENU"
                mov        ds:stMyWndClass.lpszClassName, offset szMyClass        ; "No need to disasm the code!"
                push        offset stMyWndClass ; lpWndClass
                call        RegisterClassA
                push        NULL                ; lpParam
                push        ds:hInstance        ; hInstance
                push        NULL                ; hMenu
                push        NULL                ; hWndParent
                push        8000h                ; nHeight
                push        8000h                ; nWidth
                push        6Eh                ; Y
                push        0B4h                ; X
                push        WS_OVERLAPPEDWINDOW ; dwStyle
                push        offset szNameWinMain ; "CrackMe        v1.0"
                push        offset szMyClass ; "No need to disasm the code!"
                push        WS_EX_LEFT        ; dwExStyle
                call        CreateWindowExA
                mov        ds:hWinMain, eax
                push        SW_SHOWNORMAL        ; nCmdShow
                push        ds:hWinMain        ; hWnd
                call        ShowWindow
                push        ds:hWinMain        ; hWnd
                call        UpdateWindow
                push        TRUE                ; bErase
                push        NULL                ; lpRect
                push        dword ptr [ebp+8] ; hWnd
                                        ; (401000)
                call        InvalidateRect

loc_4010F1:                                ; CODE XREF: start+11Bj
                push        0                ; wMsgFilterMax
                push        0                ; wMsgFilterMin
                push        NULL                ; hWnd
                push        offset stMsg        ; lpMsg
                call        GetMessageA
                cmp        ax, 0
                jz        short loc_40111D
                push        offset stMsg        ; lpMsg
                call        TranslateMessage
                push        offset stMsg        ; lpMsg
                call        DispatchMessageA
                jmp        short loc_4010F1

loc_40111D:                                ; CODE XREF: start+105j
                push        ds:stMsg.wParam        ; uExitCode
                call        ExitProcess
start                endp

; Exported entry   1. WndProc

; int __stdcall        ProcWinMain(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
                public _ProcWinMain
_ProcWinMain        proc near                ; DATA XREF: start+27o

hWnd                = dword        ptr  8
uMsg                = dword        ptr  0Ch
wParam                = dword        ptr  10h
lParam                = dword        ptr  14h

                enter        0, 0
                push        esi
                push        edi
                push        ebx
                cmp        [ebp+uMsg], WM_DESTROY
                jz        short loc_401193
                cmp        [ebp+uMsg], WM_RBUTTONDOWN
                jz        short loc_4011A3
                nop
                nop
                nop
                nop
                cmp        [ebp+uMsg], WM_SIZE
                jz        short loc_4011A5
                cmp        [ebp+uMsg], WM_CREATE
                jz        short loc_401176
                cmp        [ebp+uMsg], WM_LBUTTONDOWN
                jz        short loc_4011A1
                cmp        [ebp+uMsg], WM_GETMINMAXINFO
                jz        short loc_4011AC
                cmp        [ebp+uMsg], WM_COMMAND
                jz        short loc_4011D2
                nop
                nop
                nop
                nop
                jmp        short loc_401180

                jmp        short loc_4011E6

loc_401176:                                ; CODE XREF: _ProcWinMain+24j
                mov        eax, 0
                jmp        short loc_4011E6

loc_401180:                                ; CODE XREF: _ProcWinMain+42j
                push        [ebp+lParam]        ; lParam
                push        [ebp+wParam]        ; wParam
                push        [ebp+uMsg]        ; Msg
                push        [ebp+hWnd]        ; hWnd
                call        DefWindowProcA
                jmp        short loc_4011E6

loc_401193:                                ; CODE XREF: _ProcWinMain+Bj
                                        ; _ProcWinMain+B4j
                push        0                ; nExitCode
                call        PostQuitMessage
                mov        eax, 0
                jmp        short loc_4011E6

loc_4011A1:                                ; CODE XREF: _ProcWinMain+2Dj
                jmp        short loc_4011E6

loc_4011A3:                                ; CODE XREF: _ProcWinMain+14j
                jmp        short loc_4011E6

loc_4011A5:                                ; CODE XREF: _ProcWinMain+1Ej
                mov        eax, 0
                jmp        short loc_4011E6

loc_4011AC:                                ; CODE XREF: _ProcWinMain+33j
                mov        ebx, [ebp+lParam]
                mov        [ebx+MINMAXINFO.ptMinTrackSize.x], 118h
                mov        [ebx+MINMAXINFO.ptMinTrackSize.y], 0A0h
                mov        [ebx+MINMAXINFO.ptMaxTrackSize.x], 118h
                mov        [ebx+MINMAXINFO.ptMaxTrackSize.y], 0A0h
                mov        eax, 0
                jmp        short loc_4011E6

loc_4011D2:                                ; CODE XREF: _ProcWinMain+3Cj
                cmp        [ebp+wParam], ID_MENUABOUT
                jz        short loc_4011ED
                cmp        [ebp+wParam], ID_MENUEXIT
                jz        short loc_401193
                cmp        [ebp+wParam], ID_MENUREG
                jz        short loc_401209
                jmp        short $+2

loc_4011E6:                                ; CODE XREF: _ProcWinMain+49j
                                        ; _ProcWinMain+53j _ProcWinMain+69j
                                        ; _ProcWinMain+77j
                                        ; _ProcWinMain:loc_4011A1j
                                        ; _ProcWinMain:loc_4011A3j
                                        ; _ProcWinMain+82j _ProcWinMain+A8j
                                        ; _ProcWinMain+DFj _ProcWinMain+FEj
                                        ; _ProcWinMain+122j _ProcWinMain+129j
                pop        ebx
                pop        edi
                pop        esi
                leave
                retn        10h

loc_4011ED:                                ; CODE XREF: _ProcWinMain+AEj
                push        0                ; dwInitParam
                push        offset _ProcDlgAbout ; lpDialogFunc
                push        [ebp+hWnd]        ; hWndParent
                push        offset TemplateName ; "DLG_ABOUT"
                push        ds:hInstance        ; hInstance
                call        DialogBoxParamA
                jmp        short loc_4011E6

loc_401209:                                ; CODE XREF: _ProcWinMain+BAj
                push        0                ; dwInitParam
                push        offset _ProcDlgReg ; lpDialogFunc
                push        [ebp+hWnd]        ; hWndParent
                push        offset aDlg_regis ; "DLG_REGIS"
                push        ds:hInstance        ; hInstance
                call        DialogBoxParamA
                cmp        eax, 0
                jz        short loc_4011E6
                push        offset szUserName
                call        sub_40137E
                push        eax
                push        offset szSerial
                call        sub_4013D8
                add        esp, 4
                pop        eax
                cmp        eax, ebx
                jz        short loc_40124C
                call        sub_401362
                jmp        short loc_4011E6

loc_40124C:                                ; CODE XREF: _ProcWinMain+11Bj
                call        sub_40134D
                jmp        short loc_4011E6
_ProcWinMain        endp

; BOOL __stdcall ProcDlgReg(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
_ProcDlgReg        proc near                ; DATA XREF: _ProcWinMain+E3o

hWnd                = dword        ptr  8
uMsg                = dword        ptr  0Ch
wParam                = dword        ptr  10h
lParam                = dword        ptr  14h

                enter        0, 0
                push        ebx
                push        esi
                push        edi
                cmp        [ebp+uMsg], WM_INITDIALOG
                jz        short loc_401297
                cmp        [ebp+uMsg], WM_COMMAND
                jz        short loc_4012A1
                cmp        [ebp+uMsg], WM_CLOSE
                jz        loc_4012F7
                cmp        [ebp+uMsg], WM_LBUTTONDOWN
                jz        short loc_40128B
                mov        eax, 0

loc_401284:                                ; CODE XREF: _ProcDlgReg+4Cj
                                        ; _ProcDlgReg+A2j _ProcDlgReg+B2j
                pop        edi
                pop        esi
                pop        ebx
                leave
                retn        10h

loc_40128B:                                ; CODE XREF: _ProcDlgReg+2Aj
                push        TRUE                ; bErase
                push        NULL                ; lpRect
                push        [ebp+hWnd]        ; hWnd
                call        InvalidateRect

loc_401297:                                ; CODE XREF: _ProcDlgReg+Ej
                push        [ebp+hWnd]        ; hWnd
                call        SetFocus
                jmp        short loc_401284

loc_4012A1:                                ; CODE XREF: _ProcDlgReg+17j
                                        ; _ProcDlgReg+80j
                xor        eax, eax
                cmp        [ebp+wParam], ID_CANCEL
                jz        short loc_4012F7
                cmp        [ebp+wParam], ID_CHECK
                jnz        short loc_4012F0
                push        0Bh                ; nMaxCount
                push        offset szUserName ; lpString
                push        EDT_NAME        ; nIDDlgItem
                push        [ebp+hWnd]        ; hDlg
                call        GetDlgItemTextA
                cmp        eax, 1
                mov        [ebp+wParam], ID_CANCEL
                jb        short loc_4012A1
                push        0Bh                ; nMaxCount
                push        offset szSerial        ; lpString
                push        EDT_SERIAL        ; nIDDlgItem
                push        [ebp+hWnd]        ; hDlg
                call        GetDlgItemTextA
                mov        eax, 1
                jmp        short loc_4012F7

loc_4012F0:                                ; CODE XREF: _ProcDlgReg+60j
                mov        eax, 0
                jmp        short loc_401284

loc_4012F7:                                ; CODE XREF: _ProcDlgReg+1Dj
                                        ; _ProcDlgReg+57j _ProcDlgReg+9Bj
                push        eax                ; nResult
                push        [ebp+hWnd]        ; hDlg
                call        EndDialog
                mov        eax, TRUE
                jmp        loc_401284
_ProcDlgReg        endp

; BOOL __stdcall ProcDlgAbout(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
_ProcDlgAbout        proc near                ; DATA XREF: _ProcWinMain+C7o

hDlg                = dword        ptr  8
uMsg                = dword        ptr  0Ch
wParam                = dword        ptr  10h
lParam                = dword        ptr  14h

                enter        0, 0
                push        ebx
                push        esi
                push        edi
                cmp        [ebp+uMsg], WM_COMMAND
                jz        short loc_40132C
                cmp        [ebp+uMsg], WM_CLOSE
                jz        short loc_401335
                mov        eax, 0

loc_401325:                                ; CODE XREF: _ProcDlgAbout+3Aj
                                        ; _ProcDlgAbout+41j
                pop        edi
                pop        esi
                pop        ebx
                leave
                retn        10h

loc_40132C:                                ; CODE XREF: _ProcDlgAbout+Ej
                cmp        [ebp+wParam], 3F2h
                jnz        short loc_401346

loc_401335:                                ; CODE XREF: _ProcDlgAbout+14j
                push        0                ; nResult
                push        [ebp+hDlg]        ; hDlg
                call        EndDialog
                mov        eax, 1
                jmp        short loc_401325

loc_401346:                                ; CODE XREF: _ProcDlgAbout+29j
                mov        eax, 0
                jmp        short loc_401325
_ProcDlgAbout        endp

sub_40134D        proc near                ; CODE XREF: _ProcWinMain:loc_40124Cp
                push        MB_ICONWARNING        ; uType
                push        offset szCapRegSucc ; "Good work!"
                push        offset szTxtRegSucc ; "Great work, mate!\rNow try the next Crac"...
                push        dword ptr [ebp+8] ; hWnd
                call        MessageBoxA
                retn
sub_40134D        endp

sub_401362        proc near                ; CODE XREF: _ProcWinMain+11Dp
                push        MB_OK                ; uType
                call        MessageBeep
                push        MB_ICONWARNING        ; uType
                push        offset aNoLuck        ; "No luck!"
                push        offset aNoLuckThereMat ; "No luck there, mate!"
                push        dword ptr [ebp+8] ; hWnd
                call        MessageBoxA
                retn
sub_401362        endp

sub_40137E        proc near                ; CODE XREF: _ProcWinMain+105p

arg_0                = dword        ptr  4

                mov        esi, [esp+arg_0]
                push        esi

loc_401383:                                ; CODE XREF: sub_40137E+14j
                                        ; sub_40137E+1Cj
                mov        al, [esi]
                test        al, al
                jz        short loc_40139C ; 到达串尾
                cmp        al, 'A'
                jb        short loc_4013AC
                cmp        al, 'Z'
                jnb        short loc_401394
                inc        esi
                jmp        short loc_401383

loc_401394:                                ; CODE XREF: sub_40137E+11j
                call        sub_4013D2
                inc        esi
                jmp        short loc_401383

loc_40139C:                                ; CODE XREF: sub_40137E+9j
                pop        esi
                call        sub_4013C2
                xor        edi, 5678h
                mov        eax, edi
                jmp        short locret_4013C1

loc_4013AC:                                ; CODE XREF: sub_40137E+Dj
                pop        esi
                push        MB_ICONWARNING        ; uType
                push        offset aNoLuck        ; "No luck!"
                push        offset aNoLuckThereMat ; "No luck there, mate!"
                push        dword ptr [ebp+8] ; hWnd
                call        MessageBoxA

locret_4013C1:                                ; CODE XREF: sub_40137E+2Cj
                retn
sub_40137E        endp

sub_4013C2        proc near                ; CODE XREF: sub_40137E+1Fp
                xor        edi, edi
                xor        ebx, ebx

loc_4013C6:                                ; CODE XREF: sub_4013C2+Dj
                mov        bl, [esi]
                test        bl, bl
                jz        short locret_4013D1
                add        edi, ebx
                inc        esi
                jmp        short loc_4013C6

locret_4013D1:                                ; CODE XREF: sub_4013C2+8j
                retn
sub_4013C2        endp

sub_4013D2        proc near                ; CODE XREF: sub_40137E:loc_401394p
                sub        al, 20h
                mov        [esi], al
                retn
sub_4013D2        endp

sub_4013D8        proc near                ; CODE XREF: _ProcWinMain+110p

arg_0                = dword        ptr  4

                xor        eax, eax
                xor        edi, edi
                xor        ebx, ebx
                mov        esi, [esp+arg_0]

loc_4013E2:                                ; CODE XREF: sub_4013D8+1Bj
                mov        al, 0Ah
                mov        bl, [esi]
                test        bl, bl
                jz        short loc_4013F5
                sub        bl, '0'
                imul        edi, eax
                add        edi, ebx
                inc        esi
                jmp        short loc_4013E2

loc_4013F5:                                ; CODE XREF: sub_4013D8+10j
                xor        edi, 1234h
                mov        ebx, edi
                retn
sub_4013D8        endp

; HWND hWinMain
hWinMain        dd 0                        ; DATA XREF: start+C8w        start+CFr
                                        ; start+DAr

; struct tagMSG        stMsg
stMsg                tagMSG <0>                ; DATA XREF: start+F7o        start+107o
                                        ; start+111o start:loc_40111Dr
; WNDCLASSA stMyWndClass
stMyWndClass        WNDCLASSA <0>                ; DATA XREF: start:loc_40101Dw
                                        ; start+8Bo start+27w        start+31w
                                        ; start+3Bw

; HINSTANCE hInstance
hInstance        dd 0                        ; DATA XREF: start+7w start+45r
                                        ; start+97r _ProcWinMain+D4r
                                        ; _ProcWinMain+F0r

aTryToCrackMe        db 'Try to crack me!',0
; char szNameWinMain[]
szNameWinMain        db 'CrackMe v1.0',0     ; DATA XREF: start+B7o
; char szMyClass[]
szMyClass        db 'No need to disasm the code!',0 ; DATA XREF: start+Eo
                                        ; start+81o start+BCo
szIdMenu        db 'MENU',0             ; DATA XREF: start+77o
; char aDlg_regis[]
aDlg_regis        db 'DLG_REGIS',0        ; DATA XREF: _ProcWinMain+EBo
; char TemplateName[]
TemplateName        db 'DLG_ABOUT',0        ; DATA XREF: _ProcWinMain+CFo
; char szCapRegSucc[]
szCapRegSucc        db 'Good work!',0       ; DATA XREF: sub_40134D+2o
; char szTxtRegSucc[]
szTxtRegSucc        db 'Great work, mate!',0Dh,'Now try the next CrackMe!',0
                                        ; DATA XREF: sub_40134D+7o
; char aNoLuck[]
aNoLuck                db 'No luck!',0         ; DATA XREF: sub_401362+9o
                                        ; sub_40137E+31o
; char aNoLuckThereMat[]
aNoLuckThereMat        db 'No luck there, mate!',0 ; DATA XREF: sub_401362+Eo
                                        ; sub_40137E+36o
; char szSerial[]
szSerial        db 10h dup(0)                ; DATA XREF: _ProcWinMain+10Bo
                                        ; _ProcDlgReg+84o
; char szUserName[]
szUserName        db 72h dup(0)                ; DATA XREF: _ProcWinMain+100o
                                        ; _ProcDlgReg+64o
                align 1000h
DATA                ends
                end start
====================以上是代码==================


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 433
活跃值: (176)
能力值: ( LV13,RANK:1250 )
在线值:
发帖
回帖
粉丝
2
没得精么,呵呵,不过我最后的意思可能也没有表达清楚,试着重说一遍:

1. 众所周知,将ASCII码减去20h是将小写字母变成对应的大写字母的方法之一,但是该程序对于输入的用户名只要求各字符都不小于'A'就可以,并没有严格限定为字母;同时减20h的对象并不仅限于小写字母,所有大于或等于'Z'的字符都在此列,特别地'Z'本身也要被减掉20h,已经不完全遵循“小写变大写,大写不变”的初衷了;

2. 将一个字符减去'0',通常是为了把十进数码字符转换成对应的数码值,但是既然序列号没有限制只能输入数码字符,那所有合法输入都会被减去'0',然后看成一个十进制数的某个数码,这样一来,如果我输入的是一些大于'9'的字符,在减去'0'以后,岂非就相当于一个大于或者等于10的“十进制数码”了!就象上面的"@?B0",字符'@'减去'0'以后等于16,那我可以说,'@'相当于是“十进制数码”16,这个'@'在千位上,对应的数值就是“16千”――尽管通常我们都不会这么表达――同样的还有“15百”,“18十”,加起来得到的也是17680,这与直接输入17680并没有什么不同!
2006-8-12 11:23
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
3
呵呵~!兄弟又出手了.学习了
看来还得下一番功夫
2006-8-12 12:27
0
游客
登录 | 注册 方可回帖
返回
//