从汇编分析Win32消息原理

转载 2011年10月31日 20:20:56

 我们用什么工具才能知道windows内核是如何工作,消息是如何处理的呢?

windows的汇编工具MASM32可以让我们非常容易彻底明了WIN32底层工作

窗口程序的核心工作就是3大点,A资源文件的编辑+B窗口的处理主程序+C消息处理程序



MASM32官方下载站点: http://www.masm32.com

在没有使用C++和MFC开发window程序以前,都是用C语言与WIN32的API函数进行编程

在使用C++和MFC开发window之后,由于MFC类库不能完全封装完所有的API函数,以及MFC的类库的复杂性以及MFC大量内置宏,加大了程序员写程序的工作量

一种比C语言更加简洁的汇编语言MASM32+API函数+各种数据结构的开发环境诞生啦

MASM32是微软专门为WINDOWS量身订做的一种高效方便的汇编开发工具



配置和安装MASM32的开发环境

1.从网站下载开发工具,安装到C:或者D:下面的MASM32文件夹中,建议不要改文件夹的名字

2.设置编译环境到windows,用下面的代码建立一个批处理文件为VAR.bat,其中set Masm32Dir=D:\Masm32是指定安装的实际文件夹路径



@echo off
rem 请根据 Masm32 软件包的安装目录修改下面的 Masm32Dir 环境变量!
set Masm32Dir=D:\Masm32
set include=%Masm32Dir%\Include;%include%
set lib=%Masm32Dir%\lib;%lib%
set path=%Masm32Dir%\Bin;%Masm32Dir%;%PATH%
set Masm32Dir=
echo on

3.用编辑器写源文件另存为*.asm,可以从源代码样例中找出测试的代码源文件,也可以用本代码的源代码进行编译和链接

4.编译源文件为*.OBJ ,命令行是ml /c /coff *.asm

5.连接目标*.OBJ文件为*.EXE程序 ,命令行是Link /subsystem:windows *.obj

6.输入得到的*.EXE文件名,可以看到程序的窗口界面



******************************************************************************************************************

下面通过一个完整的代演示一个windows窗口程序的实现过程和工作方式,请把代码另存为win32.asm

实现一个窗口主要由2个程序过程组成

窗口程序的核心工作就是3大点,A资源文件的编辑+B窗口的处理主程序+C消息处理程序



1._Proc()拦截此程序的各种消息,在本代码中只实现窗口重绘消息WM_PAINT和关闭窗口消息WM_CLOSE的处理,其它消息没有处理代码

而GetMessage,sendmessage两个函数都要截到这个窗口的句柄ID,这就是黑客编程最常用的技术
我们在_proc过程对各种消息进行检查,然后指定它们按照作者想要的工作方式进行各种操作,
这就是windows消息处理的核心点



2._WinMain()实现装载资源,填充窗口结构,注册,建立,显示,更新窗口,并进行消息循环

;操作流程是
;1.装载各种资源,如鼠标,图标,菜单,对话框,图片等,本例只装光标资源LoadCursor,0,IDC_ARROW
;2.填充窗口结构数据,各部数据依次填入,指定消息处理的函数为上面_Proc过程,见API的结构WNDCLASSEX
; 见代码mov @stWndClass.lpfnWndProc,offset _Proc
;3.注册窗口结构:把上面定制好的窗口结构在WINDOW注册,见API函数RegisterClassEx
;4.创建窗口:在注册窗口后就应该创建,见API函数CreateWindowEx
;5.显示窗口:在创建成功后显示窗口,见API函数ShowWindow
;6.更新窗口:用WM_PAINT消息不断刷新窗口,见API函数UpdateWindow
; 如消息处函数_Proc没有实现WM_PAINT的处理,则按windows缺省处理,如有处理WM_PAINT的代码,
; 本例已经实现窗口刷新的代码,见.if eax == WM_PAINT,代码段,
; 它在实现在窗口中间的客户区显示文字Win32 Assembly, Simple and powerful!
;7.进入窗口的消息循环
;7.1GetMessage()首先从windows消息对列中取有没有自己的消息,如没有就退出
; 其它程序和窗口也可以用API函数postmessage()发要这个窗口处理的消息到windows消息对列
; 也就是说GetMessage()也可以取得由其它程序用postmessage发给自己的消息
;7.2TranslateMessage()如果有消息则把消息标识进行简化转换,它通常负责键盘和鼠标消息的简化
;7.3DispatchMessage()对消息进行分派处理,把消息处理权转给_Proc这个专用的消息处理函数
;此程序又开始进行下一轮的消息循环

;其它程序可以直接用API函数sendmessage()发消息给这个窗口指定的消息处理函数_proc



以下源代码用EDITPLUS编辑OK,用MASM32工具编译OK,win32.exe在windows XP运行正常

每次重载编译,都得删除以前的*.OBJ文件和*.EXE文件,否则编译和连接不过去

*********************************************************************************************

;source code filename is win32.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming >
; win32.asm
; 窗口程序的模板代码
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff win32.asm
; Link /subsystem:windows win32.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386 ;使用CPU386的指指令集
.model flat,stdcall ;函数的参数传递为标准调用,左-右
option casemap:none ;源代码勿略大小写区分
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Include 文件定义,它通常把*.LIB和*.INC包含到此程序中来
; *.inc功能C++的*.H头文件,*.LIB如同C++的DLL,LIB是以C语言实现的API函数做成的静态链接库文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc ;它包含了大量的windows的宏定义和windows常用的数据结构
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段 常用于定义程序的全局变量
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?

.const
szClassName db 'MyClass',0
szCaptionMain db 'win32 Assembly!',0
szText db 'Win32 Assembly, Simple and powerful !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程_Proc(主要实现对消息的处理,在此程序中只处理了WM_PAINT和WM_CLOSE消息,让它在程序的客户区显示文字)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Proc proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
local @stPs:PAINTSTRUCT
local @stRect:RECT
local @hDc
mov eax,uMsg
;通过uMsg移入EAX来判断常用消息,uMsg通常包含windows常用消息,wParam,lParam通常包含键盘和鼠标的消息
;********************************************************************
;对WM_PAINT消息进行处理的消息代码段,负责把文件显示在程序的客户区的中央位置
;显示文字是Win32 Assembly, Simple and powerful !
.if eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax

invoke GetClientRect,hWnd,addr @stRect
invoke DrawText,@hDc,addr szText,-1,\
addr @stRect,\
DT_SINGLELINE or DT_CENTER or DT_VCENTER

invoke EndPaint,hWnd,addr @stPs
;********************************************************************
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret
_Proc endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG

invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;********************************************************************
; 注册窗口类
;********************************************************************
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW

Win32汇编教程2 - 消息框

在本课中,我们将用汇编语言写一个 Windows 程序,程序运行时将弹出一个消息框并显示"Win32 assembly is great!"。 理论: Windows 为编写应用程序提供了大量的资...
  • snddman
  • snddman
  • 2011年12月07日 20:09
  • 296

Win32汇编获取窗体的mousehover消息

默认情况下Windows窗体是不会响应WM_MOUSELEAVE和WM_MOUSEHOVER消息的,通过使用_TrackMouseEvent这个函数可以激活这两个消息。在调用这个函数后,当鼠标在指定窗...

Win32汇编--图形操作--GDI原理

Win32汇编--图形操作--GDI原理   Windows是基于图形界面的,所以在Win32编程中,图形操作是最常用的操作。GDI的意义在于将程序对图形界面的操作和硬件设备隔绝开来,在程序中可以...

C指针原理(31)-win32汇编及.NET调试

.NET堆栈原理 1、用调试器调试线程  1)栈调用 以下面代码为例 Imports System.Threading      Public Class Form1       ...

Windows热键注册(反汇编方法 查看win32api 原理)

要像系统注册一个全局热键,需要用到RegisterHotKey,函数用法如下(MSDN): BOOL RegisterHotKey(                   HWND hWnd,  ...
  • whatday
  • whatday
  • 2012年09月19日 20:02
  • 3108

cocos2d-x整体框架源码分析以及启动过程原理(win32)

原文地址:http://blog.csdn.net/jinble03/article/details/20006407 引言:如果你想深入了解cocos2d-x的整个框架和运行流程,...

cocos2d-x整体框架源码分析以及启动过程原理(win32)

转载请注明,原文地址:http://blog.csdn.net/jinble03/article/details/20006407 引言:如果你想深入了解cocos2d-x的整个框架和运行流程,如果...

Cocos2d-x:整体框架源码分析以及启动过程原理(win32)

原文地址:http://blog.csdn.net/jinble03/article/details/20006407 引言:如果你想深入了解cocos2d-x的整个框架和运行流程,如果你想知道整个启...
  • vivi_12
  • vivi_12
  • 2017年07月12日 17:52
  • 160

Cocos2d-x:整体框架源码分析以及启动过程原理(win32)

原文地址:http://blog.csdn.net/jinble03/article/details/20006407 引言:如果你想深入了解cocos2d-x的整个框架和运行流程,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从汇编分析Win32消息原理
举报原因:
原因补充:

(最多只允许输入30个字)