Win32汇编学习笔记01.环境配置-C/C++基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net

环境配置

masm32下载

官网:http://www.masm32.com/

安装

成功标志

环境配置:

    • 将masm32下的bin目录添加到path
    • 新建include,将masm32目录下的inclcude目录添加进去
    • 新建lib,将masm32目录下的lib目录添加进去

测试代码
.386
.model flat, stdcall
option casemap:none include windows.inc
include user32.inc includelib user32.lib .data
g_sz db "hello world", 0
.code
START:
invoke MessageBoxA, NULL, offset g_sz, NULL, MB_OK
end START

编译链接后可以生成可执行文件就带配置成功

编译链接:
1. 编译
ml /c /coff %1.asm(coff--PE)
ml默认⽣成的⽂件格式是16位的,通过 /coff 32位程序的可执⾏⽂件格式来指定32位的格式
2. 链接
link /subsystem:windows %1.obj
通过 /subsystem 来指定⼦系统, windows 是窗⼝程序, console 是控制台程序
编译脚本 build.bat:
@echo off
set include=D:\masm32\include
set lib=D:\masm32\lib
set path=D:\masm32\bin;D:\OllyICE_1.10 del D:\OllyICE_1.10\udd\*.udd ml /c /coff %1.asm
if errorlevel 1 goto err link /subsystem:windows %1.obj
if errorlevel 1 goto err OllyICE.exe %1.exe :err

或者

ml /c /coff  %1.asm

link /subsystem:windows %1..obj

D:\OllyICE_1.10\OllyICE.exe %1.exe

pause
代码在scode高亮

16位与32位汇编的区别

1.源文件格式

  • 文件头固定三件套:

  • .386					; 表示使用的是386的是指令集
    .model flat, stdcall ; 指明内存模型和调用约定
    option casemap:NONE ; 其它选项,和ml或link的命令选项等价,32位汇编一般只用casemap-NONE
    • **msdn宏汇编官网:**https://docs.microsoft.com/en-us/cpp/assembler/masm/directives-reference?view=msvc-160
        • 8086和286都是16位的,从386开始是32位,后缀+P的指可以使用跳转指令的(适用于面向内核)。
      • casemap 最好只设 NONE 设all可能导致部分头文件没法用
    • 分段:32位汇编取消 了分段,改用内存属性来划分,称作节(section)、内存区或内存块。
      • 编写时每种类型可以定义多个,编译期会自动被同类归置

.386					; 表示使用的是386的是指令集,最低版本,也可以用更高版本,常用386
.model flat, stdcall ; 指明内存模型和调用约定 只有c或者 stdcall
option casemap:NONE ; 其它选项,和ml或link的命令选项等价,32位汇编一般只用casemap-NONE .data
g_sz db "hello world", 0
.data
g_sz0 db "hello world", 0 .data?
g_sz dw ? .const
g_sz1 db "test test", 0 .code START:
end START

寄存器

寄存器长度

32位 扩充了 8 个通用寄存器 和2个 ip 一次 flag 寄存器 , 扩充成了32位,, 低16位仍然保留原来的名字, 高16位没有名字,要访问需要自己移位 , 段寄存器没有扩充且其功能发生了改变

寄存器组

调试

32位汇编调试⼀般使⽤OD或者x64dbg,前者可以到看雪下载,后者可以到官⽹下载,两者建议都下

OD(OllICE)

目前只能调试32位程序

https://tool.pediy.com/ 看雪官网

解压密码: pediy.com

使用方式,

  1. 把 exe 文件拖进去
  2. 点击菜单

  1. 附近进程 : 调试正在运行的
  2. 右键用 ollyice 打开

鼠标点击有时候高亮不准是因此你改动了代码,但是软件保存了上次的调试信息,删除即可

删除上次调试保存的信息

  1. 删除该文件里面的文件

  1. 通过OD去删,删除要先退出调试,删完在重新调试,否则内存里仍然还有数据

X32Debug

可以调试64位程序

官网: https://x64dbg.com/

x32dbg 调32位 x64dbg 调 64位

调试快捷键

x32dbg 和 OD 的使用方式基本相同,包括快捷键

F4:运行到光标处。

esp: 回到栈顶

+/- 查看 下一步/上一步 运行的代码

菜单 查看断点可以查看所有的断点

指令补充

串操作现在支持一次四个字节的操作(26位只支持最高2字节)

  • 8086所有指令在32位保持原有功能不变,操作数长度扩充到32位。

movsx:高位补0,低位补1。

movzx:全部补0。

寻址

  • 相对于16位汇编,32位寻址的变化:
    • 1.在基址寻址和基址变址寻址两种寻址操作上面更加宽松:
      • 基址寄存器:通用寄存器都可用作基址寄存器;
      • 变址寄存器:除ESP外都可以用作变址寄存器。
      • *当基址为EBP或ESP时,访问的是栈上的数据。
    • 2.同时增加了比例因子寻址:变址寄存器 × 比例因子(1、2、4、8),便于遍历不同长度的数组。

.386
.model flat, stdcall
option casemap:NONE include windows.inc
include user32.inc
includelib user32.lib
.data
g_szTitle db "hello world", 0
.data
g_sz db "hello world", 0
g_sz0 db "hello world", 0
g_ary dw 1111h,2222h,3333h,4444h,5555h
.data?
g_dw dw ?
.const
g_sz1 db "test test",0
.code START:
mov eax,offset g_ary
xor ecx,ecx
mov bx,[eax+ecx*type g_ary]
inc ecx
mov bx,[eax+ecx*type g_ary]
inc ecx
mov bx,[eax+ecx*type g_ary]
inc ecx
mov bx,[eax+ecx*type g_ary] mov eax,offset g_sz
mov ebx,offset g_sz0
mov edx,offset g_sz1
mov ecx,offset g_dw
mov byte ptr [eax],'a' mov esi,1
mov byte ptr [eax+esi],'b' mov edx,offset g_sz1
mov byte ptr [edx+esi+1],'c' ;invoke MessageBoxA, NULL, offset g_szTitle, NULL, MB_OK
end START

调用API,弹MessageBox代码示例

.386                  ; 表示使用的是386的是指令集
.model flat, stdcall ; 指明内存模型和调用约定
option casemap:NONE ; 其它选项,和ml或link的命令选项等价,32位汇编一般只用casemap-NONE include windows.inc
include user32.inc
include kernel32.inc includelib user32.lib
includelib kernel32.lib .data
g_szText db "hello world", 0
g_szTitle db "cr42 asm32", 0 .code
START:
invoke MessageBoxA, NULL, offset g_szText, offset g_szTitle, MB_OK
invoke ExitProcess, 0
end START

汇编版的第一个窗口

SDK 版弹窗

#include <windows.h>

void ShowErrMsg();

LRESULT CALLBACK CR42WindowProc(HWND hwnd,      // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch (uMsg)
{
case WM_LBUTTONDOWN:
{
WORD wX = LOWORD(lParam);
WORD xY = HIWORD(lParam); char szBuf[MAXBYTE] = {0};
wsprintf(szBuf, "x:%d y:%d", wX, xY);
MessageBox(hwnd, szBuf, NULL, MB_OK); return 0;
}
case WM_CLOSE:
{
int nRet = MessageBox(hwnd, "亲,是否要关闭窗口!", NULL, MB_OKCANCEL);
if (nRet == IDOK)
{
DestroyWindow(hwnd);//销毁窗口
}
return 0;
}
case WM_DESTROY://窗口已经被销毁
PostQuitMessage(0);
return 0;
} return DefWindowProc(hwnd, uMsg, wParam, lParam); //自己不想处理的消息,交给系统默认处理即可
} int WINAPI WinMain(HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;//窗口风格
wc.lpfnWndProc = CR42WindowProc;//函数
wc.cbClsExtra = 0;//窗口类对象额外内存大小,一般不用
wc.cbWndExtra = 0;//窗口实例对象额外内存大小,一般不用
wc.hInstance = hInstance;//实例句柄
wc.hIcon = NULL;//没有图标
wc.hCursor = NULL;//没有光标
wc.hbrBackground = (HBRUSH)(COLOR_ACTIVEBORDER + 1);//背景颜色
wc.lpszMenuName = NULL;//没有菜单
wc.lpszClassName = "cr42 class";//窗口类的类名
ATOM nRet = RegisterClass(&wc);
if (nRet == 0)
{
MessageBox(NULL, "注册窗口类失败!", NULL, MB_OK);
return 0;
}
//wc.lpszClassName = "cr42 class2";//窗口类的类名
//nRet = RegisterClass(&wc);
//if (nRet == 0)
//{
// ShowErrMsg();
//}
//DWORD dwErr = GetLastError(); //创建窗口实例
HWND hWnd = CreateWindow("cr42 class", //窗口类类名
"我的第一个窗口",
WS_OVERLAPPEDWINDOW,//重叠窗口
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,//坐标和尺寸大小
NULL,//父窗口,没有
NULL,//菜单,没有
hInstance,
NULL);//参数,暂时不用
if (hWnd == NULL)
{
ShowErrMsg();
return 0;
} //3 显示窗口
ShowWindow(hWnd, SW_SHOW);//正常显示窗口 //4. 更新窗口
UpdateWindow(hWnd); // WM_MOUSEMOVE
//WM_KEYDOWN //消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
//CR42WindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
DispatchMessage(&msg);
} #if 0
DWORD dw = CS_HREDRAW | CS_VREDRAW; //多种风格组合
if (dw & CS_HREDRAW)//判断风格
{
}
dw = dw & (~CS_HREDRAW); //取消风格 #endif // 位运算在SDK中广泛应用
return 0;
} void ShowErrMsg()
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
// Free the buffer.
LocalFree(lpMsgBuf);
}

ASM32 版

查找变量定义 或者 函数的文件或库

 
.386 ; 表示使用的是386的是指令集 .model flat, stdcall ; 指明内存模型和调用约定 option casemap:NONE ; 其它选项,和ml或link的命令选项等价,32位汇编一般只用casemap-NONE include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib .data g_szClassName db "cr42asm32Class", 0 g_szTitle db "这个是我的第一个汇编窗口", 0 .code ; 过程函数 WindowProc PROC stdcall hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg == WM_CLOSE invoke PostQuitMessage, 0 ;退出 .ENDIF invoke DefWindowProc, hWnd, uMsg, wParam, lParam ret WindowProc ENDP ;函数入口 WinMain Proc hInstance:HINSTANCE local @wc:WNDCLASS ;窗口类 local @hWnd:HWND ;窗口句柄 local @msg:MSG ;消息队列 ;sdk注册窗口类 ;WNDCLASS wc; ;wc.style = CS_HREDRAW | CS_VREDRAW;//窗口风格 ;wc.lpfnWndProc = CR42WindowProc; //函数 ;wc.cbClsExtra = 0; //窗口类对象额外内存大小,一般不用 ;wc.cbWndExtra = 0; //窗口实例对象额外内存大小,一般不用 ;wc.hInstance = hInstance; //实例句柄 ;wc.hIcon = NULL; //没有图标 ;wc.hCursor = NULL; //没有光标 ;wc.hbrBackground = (HBRUSH)(COLOR_ACTIVEBORDER + 1);//背景颜色 ;wc.lpszMenuName = NULL;//没有菜单 ;wc.lpszClassName = "cr42 class";//窗口类的类名 ;ATOM nRet = RegisterClass(&wc); ;if (nRet == 0) ;{ ; return 0; ;} ; 注册窗口类 mov @wc.style, CS_VREDRAW or CS_HREDRAW mov @wc.lpfnWndProc, offset WindowProc mov @wc.cbClsExtra,0 mov @wc.cbWndExtra, 0 push hInstance pop @wc.hInstance ;设置图标 invoke LoadIcon,NULL,IDI_APPLICATION mov @wc.hIcon,eax ;设置光标 invoke LoadCursor,NULL,IDC_ARROW mov @wc.hCursor,eax mov @wc.hbrBackground, COLOR_WINDOW+1 mov @wc.lpszMenuName,NULL mov @wc.lpszClassName, offset g_szClassName invoke RegisterClassA, addr @wc .IF eax == 0 ret .ENDIF ; HWND hWnd = CreateWindow("cr42 class", //窗口类类名 ; "我的第一个窗口", ; WS_OVERLAPPEDWINDOW,//重叠窗口 ; CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,//坐标和尺寸大小 ; NULL,//父窗口,没有 ; NULL,//菜单,没有 ; hInstance, ; NULL);//参数,暂时不用 ;if (hWnd == NULL) ;{ ; return 0; ;} ; 创建窗口示例 返回值 eax 窗口句柄 invoke CreateWindowExA, 0, offset g_szClassName, offset g_szTitle, WS_OVERLAPPEDWINDOW or WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL, NULL, hInstance, NULL .IF eax == NULL ret .ENDIF mov @hWnd,eax ;ShowWindow(hWnd, SW_SHOW); ;显示窗口 ;UpdateWindow(hWnd); ;更新窗口 ;显示窗口 invoke ShowWindow, @hWnd,SW_SHOW ;更新窗口 invoke UpdateWindow,@hWnd ;MSG msg; ;while (GetMessage(&msg, NULL, 0, 0)) ;{ ; TranslateMessage(&msg); ; DispatchMessage(&msg); ;} ; 消息循环 .WHILE TRUE invoke GetMessage, addr @msg, NULL, 0, 0 .IF eax == 0 .break .ENDIF invoke TranslateMessage, addr @msg invoke DispatchMessage, addr @msg .ENDW ret WinMain endp START: invoke GetModuleHandleA, NULL ;获取实例句柄 invoke WinMain, eax ;调用入口函数 invoke ExitProcess, 0 ;退出程序 end START 
 

Win32汇编学习笔记01.环境配置的更多相关文章

  1. OpenGL 学习笔记 01 环境配置

    以下教程仅适用于Mac下的Xcode编程环境!其他的我也不会搞. 推荐教程:opengl-tutorial  本项目Github网址       OpenGL太可怕了...必需得把学的记下来,不然绝壁 ...

  2. Qt5学习笔记(1)-环境配置(win+64bit+VS2013)

    Qt5学习笔记(1)-环境配置 工欲善其事必先-不装-所以装软件 久不露面,赶紧打下酱油. 下载 地址:http://download.qt.io/ 这个小网页就可以下载到跟Qt有关的几乎所有大部分东 ...

  3. 【lua学习笔记】——环境配置

    1 开发平台 windows7 64位 2 下载链接 http://www.lua.org/download.html 3 安装完成-环境配置 4  运行 WIN+R 运行 cmd 运行lua,显示配 ...

  4. 学习笔记-ionic3 环境配置搭建到打包

    折腾了两周总算理清楚了,参考的链接如下: https://blog.csdn.net/zeternityyt/article/details/79655150  环境配置 https://segmen ...

  5. Maven 学习笔记——Maven环境配置(1)

    在学习Selenium的过程中,接触到了Maven(项目管理工具),不至于学一路忘一路,左耳朵进右耳多出,还是决定边学边记录,毕竟听的不如 看的,看的不如写的吗.首先学一样东西,肯定得明确学的是什么, ...

  6. WP8 学习笔记(001_环境配置)

    Step 1  WP8 的开发要求64位操作系统,Windows 8及以上版本,需要激活版,建议网上买一个注册码.详见安装双系统. Step 2 安装好系统并已经激活之后,需要安装Windows Ph ...

  7. tensorflow学习笔记(1)-环境配置

    配置环境anaconda3+windows10+pycharm+python==3.5.2+tensorflow==1.1.4+cuda10.0+cudnn7 https://www.anaconda ...

  8. 学习笔记----php环境配置

    Php开发环境自定义搭建 (万事开头难) 第一步:Apache安装(httpd-2.4.37-win64-VC15.zip) 下载已编译apache安装包:Apachelounge官方下载地址:htt ...

  9. 《基于Nginx的中间件架构》学习笔记---1.环境配置

    一.环境调试确认 (四项确认) 1.确认系统网络 ping www.baidu.com 2.确认yum可用 yum list|grep gcc 3.确认关闭iptables规则 iptables -L ...

  10. JAVA学习笔记1——环境配置

    ·JDK 发展史 1995 java语言诞生 1996 JDK1.0发布 1997 JDK1.1发布 1998 JDK1.2发布(Java2),JFC/Swing技术发布 1999 Java被分成了J ...

随机推荐

  1. Top-N推荐算法 Top-N recommendation Algorithms

    引言 推荐算法是计算机专业中的一种算法,通过一些计算,能够推测用户喜欢的东西,在互联网环境中应用比较广泛.Top-N算法在生活中非常常见,比如学术论文推荐论文.音乐软件推荐歌曲等. 今天看到一篇名叫& ...

  2. Stream4Graph:动态图上的增量计算

    作者:张奇 众所周知,当我们需要对数据做关联性分析的时候,一般会采用表连接(SQL join)的方式完成.但是SQL join时的笛卡尔积计算需要维护大量的中间结果,从而对整体的数据分析性能带来巨大影 ...

  3. web站点常见漏洞及解决方法

    1.PHP Web表单哈希冲突拒绝服务漏洞 漏洞分析:PHP 5.3.9之前版本在计算表单参数哈希值的实现上存在拒绝服务漏洞,该漏洞源于未提前限制哈希冲突.攻击者可利用该漏洞通过发送小量的特制webf ...

  4. OkHTTP发送POST请求传送JSON数据

    导入依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> ...

  5. docker pause 命令使用

    暂停正在运行的镜像容器 用途是在启动的容器的过程又的容器启动快了 有的还没有就绪 调试过程使用 a3: 正在运行的镜像容器简称 暂停: docker pause a3 解除暂停: docker unp ...

  6. DeepSeek引发的AI发展路径思考

    DeepSeek引发的AI发展路径思考 参考文章来源于科技导报 ,作者李国杰院士 | 哈工大 DeepSeek 技术前沿与应用讲座 1. DeepSeek 的科技突破 7 天之内 DeepSeek 的 ...

  7. 包装类--java进阶day05

    1.包装类 比如要让s+100,输出223.如果直接相加,结果是123100,这时就可以将s转换为包装类,然后再用包装类进行相加 2.包装类类型 3.手动拆/装箱 我们这里只介绍Integer,其他包 ...

  8. static修饰成员方法、static修饰成员的特点总结、浅聊主方法-java se进阶 day01

    1.工具类的介绍 工具类不是用于描述事物的类,而是帮我们完成事情的类(打工) 如图 当我们编写完这个类后,我们会发现一件事,这个类自己本身并没有意义,这个类完全是给用户进行调用方法的 既然是专门给用户 ...

  9. 基于C#的学生社团管理系统(简单基础版)

    前言 该系统为个人独立编写测试,也算自己的孩子吧,虽然基础功能简单但是也为了大家能有个可以借鉴,可以改写的模版使用,我就写个博客让大家参考,但是拒绝搬运售卖. * 正式介绍 该系统基于C#开发,使用V ...

  10. 我对TamperMonkey的不满-更新中

    我认为我的电脑上的TamperMonkey插件的值得考虑的不足: 没有提供一个把脚本最小化的功能 不能编辑热键 脚本icon不能使用svg 没有提供一种很好的能够区分别人的脚本和自己的脚本的方式,自己 ...