第3章 使用masm

1. win32汇编程序的结构

例子

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Hello.asm
; 使用 Win32ASM 写的 Hello, world 程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Hello.asm
; Link /subsystem:windows Hello.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .386 ;指定使用的指令集
        .model flat,stdcall ;指定内存模式和语言模式(即程序的调用模模式),影响最后生成的可执行文件
                ;stdcall WINDOWS api使用stdcall模式 规定了参数传递的次序
        option casemap:none ;定义了程序中的变量和子程序名大小写敏感
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include     windows.inc
include     user32.inc
includelib  user32.lib
include     kernel32.inc
includelib  kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data
szCaption   db  'A MessageBox !',0
szText      db  'Hello, World !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .code
start:
        invoke  MessageBox,NULL,offset szText,offset szCaption,MB_OK
        invoke  ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        end start

程序的结构

.386
.model flat,stdcall
option casemap:none
<一些include语句>
.stack [堆栈段 的大小] ;不必定义,系统会自动分配 可读可写可执行 可用于缓冲区溢出
.data
<一些初始化过的变量定义>;可读可写的数据,存放在pe文件的_DATA节中
.data?
<一些没有初始化过的变量定义>;未定义变量,临时变量在PE文件的_BSS节
.const
<一些常量定义>;可读不可写
.code ;在PE文件的_TEXT节 不可写的,可通过修改PE头来可写
<代码>
<开始标号>
        <其它语句>
end 开始标号 ;指定程序的开始位置,由开始标号指定,被其它程序调用时可不指定入口
;;表示 注释 \用来换行 \后面可加注释

2. 调用API

在DOS汇编程序中,使用软中断来调用系统api
如打印字符

mov ah,9 ;中断的编号 9表示屏幕显示  需要查询中断表
mov dx, offset szHello
int 21h

windows api的dll

kernel32.dll 系统服务功能 如内存管理、任务管理和动态链接等
gdi32.dll  图形设备功能
user32.dll 用户接口功能 建立窗口和传送消息
Wsock32.dll TCP/IP协议通信

win32 api使用堆栈来传递参数
可参考
下载地址
http://www.phatcode.net/articles.php?id=238#:~:text=Microsoft%20Win32%20Programmer%27s%20Reference.%20The%20Microsoft%20Win32%20Programmer%27s,always%20view%20the%20latest%20API%20information%20at%20MSDN.
需要winhlp32.exe才能打开,这个工具的win10版本的下载地址
https://softpedia-secure-download.com/dl/dac9bc2da8ce59b76f2f4e840b6a7e88/5fe2b789/100259976/software/authoring/winhlp32.msi

调用api

windows api的数据类型可参考下面这篇文章
https://blog.csdn.net/ritman/article/details/50441717

MessageBox的定义

int MessageBox(

    HWND hWnd,  // handle of owner window
    LPCTSTR lpText, // address of text in message box
    LPCTSTR lpCaption,  // address of title of message box  
    UINT uType  // style of message box
   );

使用汇编调用

伪指令 invoke

invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK

等价于

push uType
push lpCaption
push lpText
push hWnd
call MessageBox

api的返回值

返回值 的类型对于汇编程序来说只有dword类型,存放于eax中
若返回值 不能存储在eax中,会将返回值缓冲区的地址存入eax

函数 的声明

函数名 proto [距离] [语言] [参数1]:数据类型,[参数2]:数据类型...

MessageBox的声明

MessageBox Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword
参数名可省略
MessageBox Proto :dword,:dword,:dword,:dword

include语句

语法

include 文件名
或 include <文件名>
include user32.inc
include kernel32.inc

includelib

语法

includelib 文件名
或 includelib <文件名>
include user32.lib
include kernel32.lib

函数的代码放在dll文件中
函数的定位信息和参数数目等信息存放在Lib文件中
链接器和链接时会到指定的库文件中去找api函数的位置信息

API参数中的等值定义

在windows api定义了许多常量,包含在windows.inc文件中
需要在汇编程序中包含这个文件

include windows.inc

3. 标号 变量和数据结构

MASM变量的命名规范

可以用字母 数字 下划线和@ $ ?
第一个符号不能是数字
长度小于240
不能使用指令名等关键字
在作用域中必须唯一

3.1 标号

语法

标号名:   目的指令 ;在当前 的子程序中跳转
或
标号名::  目的指令 ;在当前程序中跳转

当用@@作标号时,可以用@F 和@B来引用 @F表示本条指令后的第一个@@标号,@B表示本条指令前的第一个@@标号,程序中可以有多个@@标号


image.png

3.2 全局变量

数据类型


image.png

只有在定义全局变量时可使用缩写
示例

.data
wHour   dw ?  ;word类型未初始化
wMinute  dw   10  ;word类型变量wMinute 值为10
_hWnd    dd   ?  ;双字类型 未初始化
word_Buffer  dw 100 dup (1,2)  ;定义了一个word数组  1,2重复100遍
szBuffer  byte  1024 dup (?) ;定义了一个1024字节的缓冲区
szText db 'Hello World!'  ;定义了一个12字节的字符串
szText db 'hello world!',0dh,0ah,'jlfajflafj',0dh,0ah,0;byte类型变量定义时,引号定义的字符串和数值定义的方法可混用

未初始化的变量为0

3.3 局部变量

使用栈来管理局部变量
语法

local 变量名1[[重复数量][:类型]]

不能使用类型缩写
定义dword类型的变量时,可省略类型
不能使用dup指令
不能与全局变量重名
例子

local loc1[1024]:byte
local loc2
local loc3:WNDCLASS

使用

image.png

生成的pe文件后,反汇编得到以下指令
image.png

注意 FFFFFFF8表示-8 请参考https://blog.csdn.net/moshiyaofei/article/details/88353435
leave指令 相当于 mov esp,ebp pop ebp
上例中局部变量排列的顺序

局部变量的初始值是随机的,使用局部变量一定要初始化

3.4 数据结构

C语句结构体的定义

汇编中结构体的定义


汇编定义
使用结构体来定义数据

引用

mov eax,stWndClass.lpfnWndProc

也可以这样


image.png

嵌套定义结构体


image.png

movzx指令


sizeof lengthof

sizeof 变量名 类型名或数据结构 名
lengthof 变量名 类型名或数据结构名
sizeof伪指令可以取变量 数据类型或数据结构以字节为单位的长度
lengthof可以取变量中数据的项数

lstrlen用于记录字符串的长度

offset 对于全局变量
用于获取变量的地址 编译时已经确定
对于局部变量是使用ebp来取其地址的,所以不可以用offset来获取它的地址

addr
addr 局部变量名和全局变量名
当addr后接全局变量时,编译器会自动按照offset的用法来
当addr后接局部变量时,编译器会自动用lea指令先把地址取到eax中,然后用eax来代替变量地址使用

4 使用子程序

4.1 子程序的定义

子程序的定义

image.png

4.2 参数传递和堆栈平衡

image.png
image.png

C类型和stdcall类型是先把右边的参数先压入堆栈。
PASCAL类型先把左边的参数压入堆栈
C类型的调用者使用call指令完成后,自行用add esp,8指令将参数空间清除
PASCAL和stdcall则不管这个事,子程序会使用ret 8来实现堆栈平衡
win32 api的调用方式是stdcall


ebp指针 参数和局部变量的关系

5 高级语法

5.1 条件测试

条件测试伪指令会被翻译成cmp test之类的汇编指令


image.png

限制 表达式的左边只能是变量或寄存器,不能为常数
表达式的两边不能同时为变量,但可以同时为寄存器
标志位


image.png

5.2 分支语句

MASM的if伪指令和对应的汇编指令

注意.if 和if的区别


image.png

5.3 循环语句

伪指令语法

伪指令


伪指令

汇编指令


对应的汇编指令

6 代码风格

6.1 变量和函数的

匈牙利表示法

image.png

约定


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356