消息斷點+內存斷點定位窗口過程

在調試比較複雜的Win32程序時,要找到窗口過程並不容易,OD提供了兩個工具:消息斷點和內存斷點,善用這兩個工具可以大大提高調試的效率。
消息斷點是給指定的消息設置斷點,本質還是條件斷點;內存斷點有訪問斷點和修改斷點,本文使用的是訪問斷點。
下面是詳細步驟。

示例程序

現在有一個模擬登錄的程序,效果圖如下:
在這裏插入圖片描述
輸入正確的賬號和密碼會提示成功,否則提示錯誤,現在並不知道賬號密碼。
在這裏插入圖片描述

破解步驟

只要找到點擊按鈕的窗口函數,就能看到賬號密碼了。對於簡單的程序,可以從WinMain開始跟,不過這樣效率低,要善用工具。

首先用OD打開程序,F9執行,讓界面跑起來
在這裏插入圖片描述
點擊W窗口,可以枚舉出所有窗口
在這裏插入圖片描述

第一次進來是空白的,右鍵點擊actualize,窗口就枚舉出來了
在這裏插入圖片描述

在這裏插入圖片描述

這裏要注意,ClsProc 是窗口過程的地址,但是這個並不是我們要找的窗口過程,因爲按鈕是系統預定義的窗口類,因此使用的是windows的窗口函數。
因此,我們下消息斷點的時候,選擇的事件並不是WM_COMMAND,而應該是鼠標左鍵相關的消息。我們通過測試,發現觸發窗口過程的動作是左鍵鬆開,因此消息斷點就是左鍵鬆開的斷點。
現在,右鍵按鈕,選擇消息斷點,如圖:

在這裏插入圖片描述
選擇 WM_LBUTTONUP 消息:
在這裏插入圖片描述
在這裏插入圖片描述
現在消息斷點已經下好,點擊登錄按鈕,在系統的button窗口過程處停下:
在這裏插入圖片描述
按鈕的窗口過程最終會調用對話框的窗口過程,這部分代碼存在於exe的代碼段,因此,只要使用內存訪問斷點就可以很輕易地找到對話框的窗口過程了。

點擊M窗口,打開Memory map界面
在這裏插入圖片描述
找到EXE代碼段,右鍵設置內存訪問斷點:
在這裏插入圖片描述
F9運行,就會在對話框的窗口過程處停下
在這裏插入圖片描述
觀察堆棧窗口,[ESP+0x8] 就是窗口過程的第二個參數,即消息ID。
按鈕點擊在BUTTON的窗口過程中觸發的是WM_LBUTTONDOWN 和 WM_LBUTTONUP,然後轉發到用戶定義的窗口過程,會變成 WM_COMMAND(0x111),觀察堆棧,如果[ESP+0x8]不是0x111,那麼F9運行直到是爲止。(注意要先取消掉內存斷點,否則F9也是一步一斷)

在這裏插入圖片描述
終於找到點擊按鈕觸發的 WM_COMMAND 了,現在可以單步執行找到處理代碼了。
因爲已經找到窗口過程,可以設置條件斷點,當參數2是WM_COMMAND ,LPARAM是按鈕的句柄時才斷下:

在這裏插入圖片描述
ESP+0x10是第四個參數LPARAM,如果是WM_COMMAND,該參數是控件的句柄,0x810298則是我第一次找到WM_COMMAND時記錄的參數4.
在這裏插入圖片描述
繼續跟進,找到了校驗賬號密碼的函數,該函數傳入了對話框的句柄,目的是爲了調用 GetDlgItem 獲取文本框句柄,然後調用 GetWindowText 獲取文本框內容。
在這裏插入圖片描述

校驗函數如果返回非0,則表示登錄成功,顯示恭喜的對話框,因此只要跟進去,應該就能找到賬號密碼。
在這裏插入圖片描述

分析一下它幹了什麼,第一個 GetWindowTextA 字符串的地址是EAX,PUSH EAX 的前兩行 也就是 401048 處,是把 [ESP+C]的地址給了EAX,也就是說[ESP+C]就是字符串的地址,同理[ESP+5C]存的是另一個字符串的地址。

在這裏插入圖片描述

從 0040105C 開始就是校驗賬號密碼。
查資料得知,REPNE SCASB 是以字節爲單位遍歷字符串,EDI存的是字符串的地址,該指令遍歷字符串,直到遇到AL中的字符爲止,此處AL是0,CX每循環一次就會減一,但不包括空字符那次。

那麼當CX初始值是FF時,執行完指令後,CX的值就是字符串加上結尾空字符的長度,的負數!接下來就是NOT ECX 和 DEC ECX,一頓操作下來,ECX存的就是字符串不含結尾空字符的長度,也就是strlen的效果。

再看程序,計算出長度後,與3比較,如果不等,直接返回0
在這裏插入圖片描述

所以得出第一個結論,賬號的長度必須等於3,不等於3則校驗失敗。
同樣地,分析出密碼的長度必須是5。
因此,只要滿足賬號長度是3,密碼長度是5,就校驗成功。

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章