baronG 发表于 2010-10-22 19:06

Win32asm学习 笔记~1

.386
.model flat,stdcall
option casemap:none

;include 定义~
include windows.inc
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 'My first window!',0;这个零是 以零结尾的ANSI字符串
szText db 'winasm32 学习~~~',0



;>>>>>>>>>>>>>>>>
;代码段
;>>>>>>>>>>>>>>>>>

.code

_Proc_Winmain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
LOCAL @stps:PAINTSTRUCT
LOCAL @stRect:RECT
LOCAL @hDc

mov eax,uMsg;得到消息

.if eax == WM_PAINT

invoke BeginPaint,hWnd,addr @stps
mov @hDc,eax;返回设备环境~~~同时填充paintstruct结构

invoke GetClientRect,hWnd,addr @stRect;填充RECT结构

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_Winmain 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
mov @stWndClass.lpfnWndProc, offset _Proc_Winmain
mov @stWndClass.hbrBackground,COLOR_WINDOW+1
mov @stWndClass.lpszClassName, offset szClassName
;注册窗口类
invoke RegisterClassEx , addr @stWndClass



;>>>>>>>>>>>>
;
;建立且display出来
;>>>>>>>>>>>>

invoke CreateWindowEx, WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
100,100,600,400,\
NULL,NULL,hInstance,NULL
mov hWinMain,eax ;返回窗口的句柄

invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain


;>>>>>>>>>>>>
;
;消息循环
;>>>>>>>>>>>>

.while TRUE
invoke GetMessage, addr @stMsg,NULL,0,0
.break .if eax == 0 ; 如果是WM_QUIT消息 getmessage返回0

invoke TranslateMessage,addr @stMsg;用来转换字符的
invoke DispatchMessage,addr @stMsg;通过这个函数把消息传到proc
.endw
ret
_Winmain endp

start:
call _Winmain
invoke ExitProcess,NULL
end start










IDA逆向代码 如下~~~~


.text:00401000 ;
.text:00401000 ; +-------------------------------------------------------------------------+
.text:00401000 ; |   This file is generated by The Interactive Disassembler (IDA)      |
.text:00401000 ; |   Copyright (c) 2007 by DataRescue sa/nv, <ida@datarescue.com>      |
.text:00401000 ; | Licensed to: Mach EDV Dienstleistungen, Jan Mach, 1 user, adv, 11/2007|
.text:00401000 ; +-------------------------------------------------------------------------+
.text:00401000 ;
.text:00401000 ; Input MD5   : 4A7DBD4285B8F2B42DA88B47AA63778F
.text:00401000
.text:00401000 ; File Name   : D:\radasm\Masm\Projects\CreateWindow\CreateWindow.exe
.text:00401000 ; Format      : Portable executable for 80386 (PE)
.text:00401000 ; Imagebase   : 400000
.text:00401000 ; Section 1. (virtual address 00001000)
.text:00401000 ; Virtual size                  : 000001DC (    476.)
.text:00401000 ; Section size in file          : 00000200 (    512.)
.text:00401000 ; Offset to raw data for section: 00000400
.text:00401000 ; Flags 60000020: Text Executable Readable
.text:00401000 ; Alignment   : default
.text:00401000
.text:00401000               .686p
.text:00401000               .mmx
.text:00401000               .model flat
.text:00401000
.text:00401000 ; ===========================================================================
.text:00401000
.text:00401000 ; Segment type: Pure code
.text:00401000 ; Segment permissions: Read/Execute
.text:00401000 _text         segment para public 'CODE' use32
.text:00401000               assume cs:_text
.text:00401000               ;org 401000h
.text:00401000               assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
.text:00401000
.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000 ; Attributes: bp-based frame
.text:00401000
.text:00401000 ; int __stdcall WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
.text:00401000 WndProc         proc near               ; DATA XREF: Message_While+43o
.text:00401000
.text:00401000 hdc             = dword ptr -54h
.text:00401000 Rect            = tagRECT ptr -50h
.text:00401000 Paint         = tagPAINTSTRUCT ptr -40h
.text:00401000 hWnd            = dword ptr8
.text:00401000 Msg             = dword ptr0Ch
.text:00401000 wParam          = dword ptr10h
.text:00401000 lParam          = dword ptr14h
.text:00401000
.text:00401000               push    ebp
.text:00401001               mov   ebp, esp
.text:00401003               add   esp, 0FFFFFFACh
.text:00401006               push    ebx
.text:00401007               push    edi
.text:00401008               push    esi
.text:00401009               mov   eax, ; 得到消息结构
.text:0040100C               cmp   eax, 0Fh      ; 头文件宏定义
.text:0040100C                                       ; WM_PAINT                           equ 0Fh
.text:0040100C                                       ; 所以这里是判断是否是 .if eax == WM_PAINT
.text:0040100F               jnz   short loc_40104F ; 不是的话就跳到下一个消息的判断
.text:00401011               lea   eax, ; paint结构地址获得
.text:00401014               push    eax             ; lpPaint
.text:00401015               push          ; hWnd
.text:00401018               call    BeginPaint      ; 准备绘制窗口
.text:0040101D               mov   , eax; value is the handle to a display device context for the specified window.
.text:0040101D                                       ; 显示设备环境的句柄?。。。我英语不好。说错请指正
.text:00401020               lea   eax,
.text:00401023               push    eax             ; lpRect
.text:00401024               push          ; hWnd
.text:00401027               call    GetClientRect   ; 获得窗口区域坐标
.text:0040102C               push    25h             ; format
.text:0040102E               lea   eax,
.text:00401031               push    eax             ; lprc
.text:00401032               push    0FFFFFFFFh      ; cchText
.text:00401034               push    offset chText   ; "winasm32 学习~~~"
.text:00401039               push           ; hdc
.text:0040103C               call    DrawTextA       ; 画出来
.text:00401041               lea   eax,
.text:00401044               push    eax             ; lpPaint
.text:00401045               push          ; hWnd
.text:00401048               call    EndPaint
.text:0040104D               jmp   short loc_401080 ; 代表了没有返回值
.text:0040104F ; ---------------------------------------------------------------------------
.text:0040104F
.text:0040104F loc_40104F:                           ; CODE XREF: WndProc+Fj
.text:0040104F               cmp   eax, 10h      ; 比较
.text:0040104F                                       ; WM_CLOSE                           equ 10h
.text:0040104F                                       ; if .eax == WM_CLOSE
.text:00401052               jnz   short loc_401068 ; 不是的交给默认的DefWindowProc
.text:00401054               push    hWnd            ; hWnd
.text:0040105A               call    DestroyWindow   ; 销毁窗口
.text:0040105F               push    0               ; nExitCode
.text:00401061               call    PostQuitMessage ; 发送退出消息,如果不处理WM_CLOSE那就得处理WM_DESTROY消息,不然窗口只会关闭进程不会退出~
.text:00401061                                       ; 因为WM_CLOSE没有出发postquitmessage发送WM_QUIT消息退出循环...
.text:00401066               jmp   short loc_401080 ; 代表了没有返回值
.text:00401068 ; ---------------------------------------------------------------------------
.text:00401068
.text:00401068 loc_401068:                           ; CODE XREF: WndProc+52j
.text:00401068               push        ; lParam
.text:0040106B               push        ; wParam
.text:0040106E               push           ; Msg
.text:00401071               push          ; hWnd
.text:00401074               call    DefWindowProcA
.text:00401079               pop   esi
.text:0040107A               pop   edi
.text:0040107B               pop   ebx
.text:0040107C               leave                   ; mov esp,ebp,pop ebp
.text:0040107D               retn    10h
.text:00401080 ; ---------------------------------------------------------------------------
.text:00401080
.text:00401080 loc_401080:                           ; CODE XREF: WndProc+4Dj
.text:00401080                                       ; WndProc+66j
.text:00401080               xor   eax, eax      ; 代表了没有返回值
.text:00401082               pop   esi
.text:00401083               pop   edi
.text:00401084               pop   ebx
.text:00401085               leave
.text:00401086               retn    10h
.text:00401086 WndProc         endp
.text:00401086
.text:00401089
.text:00401089 ; =============== S U B R O U T I N E =======================================
.text:00401089
.text:00401089 ; wnd结构的大小是 0x30 所以 - 30H? tagMsg在他后边吗? 因为 msg结构大小是1C
.text:00401089 ; 而4c-30 正好等于 1c。。这不是很明白。求解答
.text:00401089 ; Attributes: bp-based frame
.text:00401089
.text:00401089 Message_While   proc near               ; CODE XREF: startp
.text:00401089
.text:00401089 Msg             = tagMSG ptr -4Ch
.text:00401089 var_30          = WNDCLASSEXA ptr -30h
.text:00401089
.text:00401089               push    ebp
.text:0040108A               mov   ebp, esp
.text:0040108C               add   esp, 0FFFFFFB4h ; 分配堆栈
.text:0040108F               push    0               ; lpModuleName
.text:00401091               call    GetModuleHandleA
.text:00401096               mov   hInstance, eax; 返回的是自身进程的实力句柄
.text:0040109B               push    30h             ; 清零的长度
.text:0040109D               lea   eax, ; 得到要清0的源的指针
.text:004010A0               push    eax
.text:004010A1               call    RtlZeroMemory
.text:004010A6               push    7F00h         ; lpCursorName
.text:004010AB               push    0               ; hInstance
.text:004010AD               call    LoadCursorA   ; 加载一个光标
.text:004010B2               mov   , eax ; 返回的是光标句柄
.text:004010B5               push    hInstance
.text:004010BB               pop    ; 进程实例句柄
.text:004010BE               mov   , 30h
.text:004010C5               mov   , 3
.text:004010CC               mov   , offset WndProc ; the window proc address
.text:004010D3               mov   , 6
.text:004010DA               mov   , offset ClassName ; 类名
.text:004010E1               lea   eax,
.text:004010E4               push    eax             ; WNDCLASSEXA *
.text:004010E5               call    RegisterClassExA ; 注册窗口类
.text:004010EA               push    0               ; lpParam
.text:004010EC               push    hInstance       ; hInstance
.text:004010F2               push    0               ; hMenu
.text:004010F4               push    0               ; hWndParent
.text:004010F6               push    190h            ; nHeight
.text:004010FB               push    258h            ; nWidth
.text:00401100               push    64h             ; Y
.text:00401102               push    64h             ; X
.text:00401104               push    0CF0000h      ; dwStyle
.text:00401109               push    offset WindowName ; 窗口名
.text:0040110E               push    offset ClassName ; "MyClass"
.text:00401113               push    200h            ; dwExStyle
.text:00401118               call    CreateWindowExA ; 创建窗口
.text:0040111D               mov   hWnd, eax       ; 窗口句柄
.text:00401122               push    1               ; nCmdShow
.text:00401124               push    hWnd            ; hWnd
.text:0040112A               call    ShowWindow
.text:0040112F               push    hWnd            ; hWnd
.text:00401135               call    UpdateWindow
.text:0040113A
.text:0040113A Message_While_0_:                     ; CODE XREF: Message_While+D6j
.text:0040113A               push    0               ; wMsgFilterMax
.text:0040113C               push    0               ; wMsgFilterMin
.text:0040113E               push    0               ; hWnd
.text:00401140               lea   eax,
.text:00401143               push    eax             ; lpMsg
.text:00401144               call    GetMessageA   ; 获得消息
.text:00401149               or      eax, eax      ; WM_QUIT消息的值是0,所以这里是判断是不是WM_QUIT消息
.text:0040114B               jz      short locret_401161 ; 如果是WM_QUIT就中断退出循环
.text:0040114D               lea   eax, ; 否则得到消息结构地址
.text:00401150               push    eax             ; lpMsg
.text:00401151               call    TranslateMessage ; 转换ascii
.text:00401156               lea   eax,
.text:00401159               push    eax             ; lpMsg
.text:0040115A               call    DispatchMessageA ; 派遣到窗口过程处理切~~
.text:0040115F               jmp   short Message_While_0_
.text:00401161 ; ---------------------------------------------------------------------------
.text:00401161
.text:00401161 locret_401161:                        ; CODE XREF: Message_While+C2j
.text:00401161               leave                   ; mov esp,pop ebp~
.text:00401162               retn
.text:00401162 Message_While   endp
.text:00401162
.text:00401163
.text:00401163 ; =============== S U B R O U T I N E =======================================
.text:00401163
.text:00401163 ; Attributes: noreturn
.text:00401163
.text:00401163               public start
.text:00401163 start         proc near
.text:00401163               call    Message_While   ; 主函数入口
.text:00401168               push    0               ; uExitCode
.text:0040116A               call    ExitProcess
.text:0040116A start         endp

baronG 发表于 2010-10-22 23:50

本帖最后由 baronG 于 2010-10-22 23:53 编辑

代码全部来自,win32asm 琢石成器,
本楼 bin
bin :receive.exe and send.exe


00               .model flat
.text:00401000
.text:00401000 ; ===========================================================================
.text:00401000
.text:00401000 ; Segment type: Pure code
.text:00401000 ; Segment permissions: Read/Execute
.text:00401000 _text         segment para public 'CODE' use32
.text:00401000               assume cs:_text
.text:00401000               ;org 401000h
.text:00401000               assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
.text:00401000
.text:00401000 ; =============== S U B R O U T I N E =======================================
.text:00401000
.text:00401000 ; Attributes: bp-based frame
.text:00401000
.text:00401000 ; int __stdcall sub_401000(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
.text:00401000 sub_401000      proc near               ; DATA XREF: sub_401076+4Ao
.text:00401000
.text:00401000 hWnd            = dword ptr8
.text:00401000 Msg             = dword ptr0Ch
.text:00401000 wParam          = dword ptr10h
.text:00401000 lParam          = dword ptr14h
.text:00401000
.text:00401000               push    ebp
.text:00401001               mov   ebp, esp
.text:00401003               push    ebx
.text:00401004               push    edi
.text:00401005               push    esi
.text:00401006               mov   eax,
.text:00401009               cmp   eax, 10h      ; if eax < 10h
.text:00401009                                       ; go to 401022
.text:0040100C               jnz   short loc_401022 ; if eax <WM_SETTEXT
.text:0040100C                                       ; go 401055
.text:0040100C                                       ;
.text:0040100E               push    hWnd            ; hWnd
.text:00401014               call    DestroyWindow
.text:00401019               push    0               ; nExitCode
.text:0040101B               call    PostQuitMessage
.text:00401020               jmp   short loc_40106D
.text:00401022 ; ---------------------------------------------------------------------------
.text:00401022
.text:00401022 loc_401022:                           ; CODE XREF: sub_401000+Cj
.text:00401022               cmp   eax, 0Ch      ; if eax <WM_SETTEXT
.text:00401022                                       ; go 401055
.text:00401022                                       ;
.text:00401025               jnz   short loc_401055
.text:00401027               push   
.text:0040102A               push   
.text:0040102D               push    offset aReceiveWm_sett ; "Receive Wm_settext message\r\nparam: %08x"...
.text:00401032               push    offset Text   ; LPSTR 拷贝到的~ 字符串 输入缓冲区
.text:00401037               call    wsprintfA
.text:0040103C               add   esp, 10h
.text:0040103F               push    0               ; uType
.text:00401041               push    offset WindowName ; "Receive Message"
.text:00401046               push    offset Text   ; lpText 输出得到的字符串
.text:0040104B               push          ; hWnd
.text:0040104E               call    MessageBoxA
.text:00401053               jmp   short loc_40106D
.text:00401055 ; -----------------------------------------------------------------















Send.exe

___________________


.text:00401000               public start
.text:00401000 start         proc near
.text:00401000               push    0               ; lpWindowName
.text:00401002               push    offset ClassName ; "Class1"
.text:00401007               call    FindWindowA
.text:0040100C               or      eax, eax      ; 判断是否获得窗口句柄
.text:0040100E               jz      short loc_401068 ; 没有找到就~~
.text:00401010               mov   hWnd, eax       ; 保存句柄
.text:00401015               push    offset aTextSendToOthe ; "Text send to other windows"
.text:0040101A               push    offset aPressOkToStart ; "press ok to start SendMessage,param: %0"...
.text:0040101F               push    offset Text   ; LPSTR~要发送到另外一个进程的字符串
.text:00401024               call    wsprintfA
.text:00401029               add   esp, 0Ch
.text:0040102C               push    0               ; uType

页: [1]
查看完整版本: Win32asm学习 笔记~1