在程式前加一個密碼輸入框的過程!

看雪資料發表於2003-08-01

最近在家無事,嘗試著修改一下軟體,在程式前加一個密碼輸入框,輸入密碼正確才能進入遊戲,否則退出。

程式名:暴力天使(一個小遊戲),當然參考了pll621的文章,在此表示感謝!

首先,需要一個對話方塊資源,用ResourceHacker開啟程式,發現有一個現成的對話方塊資源:

103 DIALOGEX 22, 17, 179, 50
style DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
EXstyle WS_EX_TOOLWINDOW
CAPTION "About"
LANGUAGE LANG_JAPANESE, 0x1
FONT 9, "MS Pゴシック"
{
  CONTROL 107, 2, STATIC, SS_ICON | WS_CHILD | WS_VISIBLE, 4, 8, 20, 20
  CONTROL "BAROQUE-SHOOTING", -1, STATIC, SS_LEFT | SS_NOPREFIX | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 8, 76, 8
  CONTROL "(C)2000 STING ALL RIGHT RESERVED", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 52, 40, 124, 8
  CONTROL "STINGWEB", 1000, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 128, 4, 48, 28
  CONTROL "[TIMEATTACK]", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 72, 20, 46, 8
}

去掉一些無用的標籤,然後加上一個Edit控制元件,修改後的資源如下:

103 DIALOGEX 100, 100, 186, 70
style DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
EXstyle WS_EX_TOOLWINDOW
CAPTION "Please Input the Password"
LANGUAGE LANG_JAPANESE, 0x1
FONT 9, "MS Pゴシック"
{
  CONTROL "", 100, EDIT, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 18, 25, 94, 14
  CONTROL "確定", 1000, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 126, 26, 48, 12
  CONTROL "Please Input The Password!!", 0, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 17, 9, 94, 14
}

用OD開啟程式,發現有兩處呼叫DialogParamBoxA處,我就用了0040ED8E處的呼叫,讓程式的OEP指向0040ED8E

0040ED8E   > 8B15 6C0D4700  MOV EDX,DWORD PTR DS:[470D6C]            ;  Case 68 ('h') of switch 0040ED5B
0040ED94   . 6A 00          PUSH 0                                   ; /lParam = NULL
0040ED96   . 68 40F14000    PUSH SHOOTING.0040F140                   ; |DlgProc = SHOOTING.0040F140
0040ED9B   . 57             PUSH EDI                                 ; |hOwner
0040ED9C   . 6A 67          PUSH 67                                  ; |pTemplate = 67
0040ED9E   . 52             PUSH EDX                                 ; |hInst => NULL
0040ED9F   . FF15 74914100  CALL DWORD PTR DS:[<&USER32.DialogBoxPar>; \DialogBoxParamA
0040EDA5   . E9 DB000000    JMP SHOOTING.0040EE85

透過40ED96處,我知道此視窗的訊息處理程式在40F140處。(DialogParamBoxA函式產生的是模式視窗,有自己的訊息處理過程。如果沒有現成的DialogParamBoxA呼叫,可以自己模仿下面程式構建一個)

0040F140   . 8B4424 08      MOV EAX,DWORD PTR SS:[ESP+8]
0040F144   . 2D 10010000    SUB EAX,110                              ;  Switch (cases 110..111)
'''110 = WM_INITDIALOG
0040F149   . 74 52          JE SHORT SHOOTING.0040F19D
0040F14B   . 48             DEC EAX
'''111=WM_COMMAND
0040F14C   . 74 05          JE SHORT SHOOTING.0040F153
0040F14E   . 33C0           XOR EAX,EAX                              ;  Default case of switch 0040F144
0040F150   . C2 1000        RETN 10
0040F153   > 8B4424 0C      MOV EAX,DWORD PTR SS:[ESP+C]             ;  Case 111 of switch 0040F144
0040F157   . 25 FFFF0000    AND EAX,0FFFF
0040F15C   . 7E 3F          JLE SHORT SHOOTING.0040F19D
0040F15E   . 83F8 02        CMP EAX,2
0040F161   . 7E 2D          JLE SHORT SHOOTING.0040F190
0040F163   . 3D E8030000    CMP EAX,3E8'注意3E8為“確定”按鈕的ID
0040F168   . 75 33          JNZ SHORT SHOOTING.0040F19D;原來按此按鈕會連線到以下網站
0040F16A   . A1 98D44100    MOV EAX,DWORD PTR DS:[41D498]
0040F16F   . 6A 05          PUSH 5                                   ; /IsShown = 5
0040F171   . 6A 00          PUSH 0                                   ; |DefDir = NULL
0040F173   . 6A 00          PUSH 0                                   ; |Parameters = NULL
0040F175   . 50             PUSH EAX                                 ; |FileName => "http://www.sting.co.jp/"
0040F176   . 68 BCD04100    PUSH SHOOTING.0041D0BC                   ; |Operation = "open"
0040F17B   . FF15 BC914100  CALL DWORD PTR DS:[<&USER32.GetDesktopWi>; |[GetDesktopWindow
0040F181   . 50             PUSH EAX                                 ; |hWnd
0040F182   . FF15 38914100  CALL DWORD PTR DS:[<&SHELL32.ShellExecut>; \ShellExecuteA
0040F188   . B8 01000000    MOV EAX,1
0040F18D   . C2 1000        RETN 10
0040F190   > 8B4C24 04      MOV ECX,DWORD PTR SS:[ESP+4]
0040F194   . 6A 02          PUSH 2                                   ; /Result = 2
0040F196   . 51             PUSH ECX                                 ; |hWnd
0040F197   . FF15 5C914100  CALL DWORD PTR DS:[<&USER32.EndDialog>]  ; \EndDialog
0040F19D   > B8 01000000    MOV EAX,1                                ;  Case 110 of switch 0040F144  
0040F1A2   . C2 1000        RETN 10

我修改為:

0040F140   . 8B4424 08      MOV EAX,DWORD PTR SS:[ESP+8]
0040F144   . 2D 10010000    SUB EAX,110                              ;  Switch (cases 110..111)
0040F149   . 74 52          JE SHORT TRY_SH-M.0040F19D
0040F14B   . 48             DEC EAX
0040F14C   . 74 05          JE SHORT TRY_SH-M.0040F153
0040F14E   . 33C0           XOR EAX,EAX                              ;  Default case of switch 0040F144
0040F150   . C2 1000        RETN 10
0040F153   > 8B4424 0C      MOV EAX,DWORD PTR SS:[ESP+C]             ;  Case 111 of switch 0040F144
0040F157   . 90             NOP
0040F158   . 90             NOP
0040F159   . 90             NOP
0040F15A   . 90             NOP
0040F15B   . 90             NOP
0040F15C   . 90             NOP
0040F15D   . 90             NOP
0040F15E   . 83F8 02        CMP EAX,2
0040F161   . 7E 2D          JLE SHORT TRY_SH-M.0040F190
0040F163   . 3D E8030000    CMP EAX,3E8
0040F168   . 0F84 B29A0000  JE TRY_SH-M.00418C20;如果按鈕按下,則跳到我自己的程式碼,見下!
0040F16E   . 3D 64000001    CMP EAX,1000064;在Edit(ID=64H)控制元件具有焦點時,eax=100064
0040F173   . 90             NOP;我們不做任何處理,返回。
0040F174   . 90             NOP
0040F175   . 90             NOP;中間無用程式碼,都nop掉
0040F176   . 90             NOP
0040F177   . 90             NOP
0040F178   . 90             NOP
0040F179   . 90             NOP
0040F17A   . 90             NOP
0040F17B   . 90             NOP
0040F17C   . 90             NOP
0040F17D   . 90             NOP
0040F17E   . 90             NOP
0040F17F   . 90             NOP
0040F180   . 90             NOP
0040F181   . 90             NOP
0040F182   . 90             NOP
0040F183   . 90             NOP
0040F184   . 90             NOP
0040F185   . 90             NOP
0040F186   . 90             NOP
0040F187   . 90             NOP
0040F188   . B8 01000000    MOV EAX,1
0040F18D   . C2 1000        RETN 10
0040F190   > 8B4C24 04      MOV ECX,DWORD PTR SS:[ESP+4]
0040F194   . 6A 02          PUSH 2                                   ; /Result = 2
0040F196   . 51             PUSH ECX                                 ; |hWnd
0040F197   . FF15 5C914100  CALL DWORD PTR DS:[<&USER32.EndDialog>]  ; \EndDialog
0040F19D   > B8 01000000    MOV EAX,1                                ;  Case 110 of switch 0040F144
0040F1A2   . C2 1000        RETN 10

0040F168跳到這裡:

00418C20   > 68 70DA4100    PUSH TRY_SH-M.0041DA70                   ; /Title = "Please Input the Password"
00418C25   . 6A 00          PUSH 0                                   ; |Class = 0
00418C27   . FF15 9C914100  CALL DWORD PTR DS:[<&USER32.FindWindowA>>; \FindWindowA
00418C2D   . A3 00DD4100    MOV DWORD PTR DS:[41DD00],EAX
;找到對話方塊,獲得控制程式碼,放入[41DD00]

00418C32   . 6A 20          PUSH 20                                  ; /Count = 20 (32.)
00418C34   . 68 00DC4100    PUSH TRY_SH-M.0041DC00                   ; |Buffer = TRY_SH-M.0041DC00
00418C39   . 90             NOP                                      ; |
00418C3A   . 6A 64          PUSH 64                                  ; |ControlID = 64 (100.)
00418C3C   . FF35 00DD4100  PUSH DWORD PTR DS:[41DD00]               ; |hWnd = NULL
00418C42   . FF15 93505700  CALL DWORD PTR DS:[575093]               ; \GetDlgItemTextA
;呼叫GetDlgItemTextA,獲得Edit框的內容

00418C48   . BF 00DC4100    MOV EDI,TRY_SH-M.0041DC00
00418C4D   . BE 60DA4100    MOV ESI,TRY_SH-M.0041DA60                ;  ASCII "cobra1111"
00418C52   . B9 09000000    MOV ECX,9     ;重複九次len(cobra1111)=9
00418C57   . F3:A6          REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
;比較密碼是否為cobra1111,如果是,則可進入遊戲;否則繼續比較
00418C59   .^74 95          JE SHORT TRY_SH-M.00412327      ;到程式原來的OEP

00418C5B   . BF 00DC4100    MOV EDI,TRY_SH-M.0041DC00
00418C60   . BE A0DA4100    MOV ESI,TRY_SH-M.0041DAA0                ;  ASCII "jjxme"
00418C65   . B9 05000000    MOV ECX,5
00418C6A   . F3:A6          REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
00418C6C   . 74 19          JE SHORT TRY_SH-M.00418C87     ;比較是否為jjxme,如果是可進入作弊模式(呵呵)


如果都不是,則出錯。
00418C6E   . 6A 00          PUSH 0                                   ; /style = MB_OK|MB_APPLMODAL
00418C70   . 68 B0DA4100    PUSH TRY_SH-M.0041DAB0                   ; |Title = "Wrong!!"
00418C75   . 68 B8DA4100    PUSH TRY_SH-M.0041DAB8                   ; |Text = "密碼錯誤!你不能玩遊戲!!"
00418C7A   . 6A 00          PUSH 0                                   ; |hOwner = NULL
00418C7C   . FF15 58914100  CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00418C82   . 33C0           XOR EAX,EAX
00418C84   . C2 1000        RETN 10;返回訊息處理

418C6C跳到這裡:

00418C87   > C605 00DC4100 >MOV BYTE PTR DS:[41DC00],1;用[41DC00]為1,則進入作弊模式(時間無限)
;用遊戲修改器就能找到關鍵點,在此不詳述
00418C8E   .^E9 5DFFFFFF    JMP TRY_SH-M.00418BF0

00418C93   > 803D 00DC4100 >CMP BYTE PTR DS:[41DC00],1;如果為1,則跳過減少時間的程式碼
00418C9A   .^0F84 7352FFFF  JE TRY_SH-M.0040DF13
00418CA0   . 833D 48134700 >CMP DWORD PTR DS:[471348],2;不然,則回覆原程式程式碼,沒有作弊模式
00418CA7   .^0F83 5052FFFF  JNB TRY_SH-M.0040DEFD
00418CAD   . 48             DEC EAX
00418CAE   . 66:8946 2A     MOV WORD PTR DS:[ESI+2A],AX
00418CB2   .^E9 5C52FFFF    JMP TRY_SH-M.0040DF13

把以下程式修改:
0040DEF4   . 73 07          JNB SHORT SHOOTING.0040DEFD
0040DEF6   . 48             DEC EAX
0040DEF7   . 66:8946 2A     MOV WORD PTR DS:[ESI+2A],AX
修改後:
0040DEF4   . E9 9AAD0000    JMP TRY_SH-M.00418C93;跳到自己的程式碼,見上!
0040DEF9     90             NOP
0040DEFA     90             NOP

現在來解決對話方塊右上角的“x”按鈕了,如果不處理的話,即使密碼不正確,按了這個鍵也會進入遊戲。
本來我想在訊息處理過程中處理這個東西,後來沒有成功。還好我發現了一個更簡單的方法:

0040ED8E   > 8B15 6C0D4700  MOV EDX,DWORD PTR DS:[470D6C]            ;  Case 68 ('h') of switch 0040ED5B
0040ED94   . 6A 00          PUSH 0                                   ; /lParam = NULL
0040ED96   . 68 40F14000    PUSH SHOOTING.0040F140                   ; |DlgProc = SHOOTING.0040F140
0040ED9B   . 57             PUSH EDI                                 ; |hOwner
0040ED9C   . 6A 67          PUSH 67                                  ; |pTemplate = 67
0040ED9E   . 52             PUSH EDX                                 ; |hInst => NULL
0040ED9F   . FF15 74914100  CALL DWORD PTR DS:[<&USER32.DialogBoxPar>; \DialogBoxParamA
0040EDA5   . E9 DB000000    JMP SHOOTING.0040EE85;由於按了x按鈕後會關閉對話方塊,然後就會來到這一句,我只要改這一句就行了。好,改為 JMP 00418CB7

00418CB7   > 6A 00          PUSH 0                                   ; /style = MB_OK|MB_APPLMODAL
00418CB9   . 68 80DB4100    PUSH TRY_SH-M.0041DB80                   ; |Title = "再見!"00
00418CBE   . 68 86DB4100    PUSH TRY_SH-M.0041DB86                   ; |Text = "再見! 歡迎下次再來!!"
00418CC3   . 6A 00          PUSH 0                                   ; |hOwner = NULL
00418CC5   . FF15 58914100  CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
00418CCB   .^E9 8A97FFFF    JMP TRY_SH-M.0041245A

顯示一個“歡迎下次再來”的對話方塊後,跳到退出程式的程式碼(程式中現成的):

0041245A  |> 68 FF000000    PUSH 0FF                                 ; /ExitCode = FF
0041245F  \. FF15 28914100  CALL DWORD PTR DS:[<&KERNEL32.ExitProces>; \ExitProcess
00412465   . C3             RETN

OK!基本完成了!
修改過程中,DialogBoxParamA是原程式中沒有的,用LoadPE匯入即可。
從分利用程式中原本就有的程式碼!


在這裡我問一個問題:
在418C93處,我原本打算用這樣的方法來修改掉程式中的程式碼:
mov byte ptr[40DEF4],90
mov byte ptr[40DEF5],90
但是不能執行,不知為何?記得在看雪的書中有過這樣的例子的!
更奇怪的是,如果我在執行這句之前,用OD隨便修改一下記憶體中的資料,指令就能正常執行了。
望高手指教!


小弟第一次寫這樣的文章,思路混亂,表達不清,望諸位諒解!
謝謝!!


相關文章