逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

#行家计划#这篇学习记录可能比较长,请大家耐心看完,待我缓缓道来,如果觉得文章对各位看官有帮助,请点赞支持!多余的话就不说了,本篇的主要内容是获悉子窗口的本质与消息断点的应用与本质。

按钮是什么?

为了快速进入主题,函数参数的说明仅作简要介绍。

HWND CreateWindow( LPCTSTR lpClassName,//窗口类名 LPCTSTR lpWindowName,//窗口标题名 DWORD dwStyle,//窗口的类型与风格 int x,//相对于父窗口偏移 int y,//相对于父窗口偏移 int nWidth,//自身宽 int nHeight,//自身高 HWND hWndParent,//父窗口句柄 HMENU hMenu,//菜单句柄,对于子窗口是身份ID HINSTANCE 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 ); }

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

简陋按钮

在第一章我们创建一个窗口时,我们写了很多代码,如下图:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

创建一个非系统定义窗口

但是在创建一个按钮时,我们只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);

下个断点:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

WNDCLASS结构体信息

在调试窗口中,我们可以看到系统给按钮定义类名就是Button,并且按钮的窗口处理函数地址并在应用程序的内存范围(0x7xxxxx通常是系统dll的空间),而是由操作系统定义。所以说按钮是特殊的窗口,当按钮产生消息时,会向父窗口发生一个WM_COMMAND消息。

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

按钮动作传递流程图

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.

CreateWindow的第九个参数,就是按钮的标识,当消息是WM_COMMAND时,使用wParam的低四位表示按钮的身份ID(即那个按钮触发了消息)。

具体的做法如下:

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

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

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

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

点击按钮结果

消息断点

有时候逆向的程序不像这个这么简单,可能没有像上文那么容易找到窗口处理函数。这个时候我就需要一点技巧,消息断点的本质也是条件断点。

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

案例

用OD打开案例:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

切换OD窗口

然后单击右键选择Actulize:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

Actualize

我看到按钮窗口的句柄,消息处理函数等等,接下来需要在消息处理函数处下断。这个我们需要注意的是我们要下断点的类型。

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

选择消息断点

然后我们选择断点消息类型(消息类型需要自己测试,比如是按键按下触发还是抬起触发):

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

选择消息类型

下断完成:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

下断完成

点击按钮触发断点:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

消息断点被触发

这个时候我们单步追踪容易追丢,根据上面的流程图,我们知道系统会将消息加工WM_COMMAND类型发给应用程序,此时我们就知道系统肯定会访问应用程序的领空,所以我们只要在代码段追踪谁访问了代码段就能找到父窗口的消息处理函数。

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

进入内存空间

找到需要下断的代码节(PE文件结构知识,会在另一个合集记录):

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

寻找需要下断的地方

在代码节选择谁访问了该内存:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

在代码节下谁访问断点

放开断点:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

放开程序

成功断到应用程序领空,该领空既是父窗口的消息处理函数:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

断到应用程序领空

此时我们看到[esp 8]为0x135,不是WM_COMMAND常量的0x111,所以我们需要单步跳过此函数(代码段下了断点,无法直接跳过),当然我们也可以在此处下消息断点。

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

WM_COMMAND

现在接受的就是按钮的消息处理函数,同时[ESP C]代表的是按钮标识,即那个按钮触发的消息,此时我们就可以追踪按钮触发后的逻辑。

附取消内存访问断点:

逆向学习4-消息断点与子窗口的窗口处理函数(按钮的秘密)

取消内存访问断点

此篇到此结束,下文预告,与应用资源有关,如更换图标等等。该文仅为学习记录,如有不足,望海涵,不足之处请在评论区批评指正。本文及该合集文章仅限学习,不可用于非法用途,一切后果与本人无关。如果大家喜欢此文,还请关注,点个赞,评个论,您的认可,是我写作的动力。感谢观看。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年12月8日 下午1:46
下一篇 2022年12月8日 下午2:00

相关推荐