首頁>科技>
HWND CreateWindow( LPCTSTR lpClassName,//窗口類名LPCTSTR lpWindowName,//窗口標題名DWORD dwStyle,//窗口的類型與風格 int x,//相對於父窗口偏移int y,//相對於父窗口偏移int nWidth,//自身寬int nHeight,//自身高HWND hWndParent,//父窗口句柄HMENU hMenu,//菜單句柄,對於子窗口是身份IDHINSTANCE hInstance,//應用程序句柄LPVOID lpParam//);

The CreateWindow function creates an overlapped, pop-up, or child window. It specifies the window class, window title, window style, and (optionally) the initial position and size of the window. The function also specifies the window"s parent or owner, if any, and the window"s

void CreateButton(HWND hwnd){		HWND hwndButton;		hwndButton = CreateWindow(			TEXT("button"),			TEXT("按鈕"),			WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_DEFPUSHBUTTON,			10,10,			80,30,			hwnd,			(HMENU)1001,			hInst,			NULL			);			}

創建一個非系統定義窗口

但是在創建一個按鈕時,我們只CreateWindow,其他的都由系統替我們完成了,甚至連窗口處理函數都由系統替我們完成。正常做開發的話,可能僅需瞭解怎麼設計更好看的按鈕,不需要了解系統替我們做了那些工作。但是做逆向你需要深處瞭解系統替我們幹了什麼。每一個窗口都由一個WNDCLASS結構用於描述窗口屬性,接下來我們介紹兩個函數用於獲取窗口WNDCLASS結構。

//獲取類名int GetClassName( HWND hWnd,LPTSTR lpClassName, int nMaxCount);

The GetClassName function retrieves the name of the class to which the specified window belongs.

//獲取窗口WNDCLASS結構信息BOOL GetClassInfo(HINSTANCE hInstance, LPCTSTR lpClassName,LPWNDCLASS lpWndClass);

The GetClassInfo function retrieves information about a window class.

具體使用如下:

TCHAR Buffer[0x20];					GetClassName(hwndButton,Buffer,0x20);					WNDCLASS wc;					GetClassInfo(hInst,Buffer,&wc);	

下個斷點:

WNDCLASS結構體信息

在調試窗口中,我們可以看到系統給按鈕定義類名就是Button,並且按鈕的窗口處理函數地址並在應用程序的內存範圍(0x7xxxxx通常是系統dll的空間),而是由操作系統定義。所以說按鈕是特殊的窗口,當按鈕產生消息時,會向父窗口發生一個WM_COMMAND消息。

按鈕動作傳遞流程圖

WM_COMMAND

#define WM_COMMAND 273 //0x111

The WM_COMMAND message is sent when the user selects a command item from a menu, when a control sends a notification message to its parent window, or when an accelerator keystroke is translated.

If an application enables a menu separator, the system sends a WM_COMMAND message with the low-word of the wParam parameter set to zero when the user selects the separator.

具體的做法如下:

	case WM_COMMAND:			{				switch(LOWORD(wParam))				{				case 1001:					MessageBox(hwnd,"你點的是我","按鈕",MB_OK);					return 0; } }

附:LOWORD是個宏,即取低四位

#define LOWORD(l) ((WORD)((DWORD)(l)))

案例

用OD打開案例:

切換OD窗口

然後單擊右鍵選擇Actulize:

選擇消息斷點

然後我們選擇斷點消息類型(消息類型需要自己測試,比如是按鍵按下觸發還是抬起觸發):

選擇消息類型

下斷完成:

消息斷點被觸發

這個時候我們單步追蹤容易追丟,根據上面的流程圖,我們知道系統會將消息加工WM_COMMAND類型發給應用程序,此時我們就知道系統肯定會訪問應用程序的領空,所以我們只要在代碼段追蹤誰訪問了代碼段就能找到父窗口的消息處理函數。

進入內存空間

找到需要下斷的代碼節(PE文件結構知識,會在另一個合集記錄):

尋找需要下斷的地方

在代碼節選擇誰訪問了該內存:

在代碼節下誰訪問斷點

放開斷點:

放開程序

成功斷到應用程序領空,該領空既是父窗口的消息處理函數:

斷到應用程序領空

此時我們看到[esp+8]為0x135,不是WM_COMMAND常量的0x111,所以我們需要單步跳過此函數(代碼段下了斷點,無法直接跳過),當然我們也可以在此處下消息斷點。

附取消內存訪問斷點:

3
最新評論
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 雲貴高原-草海遊記