好友
阅读权限20
听众
最后登录1970-1-1
|
小俊
发表于 2017-12-26 11:25
本帖最后由 小俊 于 2017-12-26 11:36 编辑
首先,先说一下我的环境
Windows10版本,和Windows SDK版本都是目前最新的 版本为:1709(16299)
VisualStudio也是最新的 <VC++ 2017 v141 工具集(x86,x64)>
编写Windows程序,当然需要用到Windows API,目前讲两种方式
- 动态获取函数地址,在这里我就不过多讲解,有兴趣看我前两篇帖子
- 正常方式,这就是我接下来要讲的了,导入Lib库,然后声明函数原型,就可以直接调用了
32位Lib路径为:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x86
最重要的俩个库为:kernel32.Lib User32.Lib 吧这俩个库拷贝到我们的源码目录
然后在代码中导入
[Asm] 纯文本查看 复制代码 ;导入Lib库
includelib kernel32.Lib
includelib User32.Lib
声明函数原型,例如:
[Asm] 纯文本查看 复制代码 ExitProcess proto,dwExitCode:dword
MessageBoxA proto,hWnd:dword,pText:dword,pTitle:dword,uType:dword
调用函数:例如
[Asm] 纯文本查看 复制代码 invoke MessageBoxA,0,0,0,0
invoke ExitProcess,0
整体代码:
[Asm] 纯文本查看 复制代码 .386
.model flat,stdcall
option casemap:none
;导入Lib库
includelib kernel32.Lib
includelib User32.Lib
;声明函数原型
ExitProcess proto,dwExitCode:dword
MessageBoxA proto,hWnd:dword,pText:dword,pTitle:dword,uType:dword
;代码段
.code
main:
invoke MessageBoxA,0,0,0,0
invoke ExitProcess,0
end main
这里,我再为小白解释一下代码,老鸟跳过
.386 为指令集,微软的解释:https://msdn.microsoft.com/zh-cn/library/ss9fh0d6.aspx
除了386,Masm还支持以下指令集
.Model 我个人理解为指定内存模型,微软的解释:https://msdn.microsoft.com/zh-cn/library/ss9fh0d6.aspx
第一个参数基本为(必选):FLAT
第二个为调用约定:常用的有两种STDCALL, C
FLAT 为平坦模式,学过80386的应该都找到,寻址方式都为段加偏移,而平坦模式段基址都为0(fs,gs除外)所以平坦模式线性地址等于虚拟地址
STDCALL调用约定和C的调用约定 区别就是一个内平衡栈 ,一个外平衡栈 ,入栈顺序都是从右向左依次入栈
option casemap:none 为区分大小写,没什么好解释的了
proto 声明函数原型
invoke 调用函数
这俩个是Masm的伪指令,并不是汇编
例如:
[Asm] 纯文本查看 复制代码 invoke ExitProcess,0
等于:
[Asm] 纯文本查看 复制代码 push 0
call ExitProcess
接下来吧代码进行编译,这里用到俩工具:ml.exe link.exe
32位路径为:C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\bin\Hostx86\x86
再我电脑上路径为这个,你电脑我就不确定了。但是这个不重要,如果你电脑上装了VS的话,那么你的开始菜单里面应该有 VS 2017的开发人员命令提示符
输入ml,出现这些信息,说明环境没问题
然后将路径切换到我的源代码路径
cd C:\Users\XiaoJun\Desktop\Source
然后直接编译
ml Source.asm
恭喜,没有出现警告或者错误
生成了三个文件
运行
没有问题,弹出了个啥也没有的消息框,因为我们给的参数都是0
运行没有问题,我们进一步做一些优化
首先,我为什么用汇编写程序,因为小,而且不依赖C运行时库,不会生成无用代码
但是我一查看文件属性,居然还有2.5k这是我接受不了的,一共这才几条汇编代码
我心算了一下,PE头0x200(512)个字节, .text 代码段0x200(512)个字节,导入表在 .data段0x200(512)字节,一共应该是1.5k才对呀
所以我打开010Editor一探究竟
发现多了个 .reloc 段,并且PE头占用了0x400(1024)个字节,所以才会那么大
因为多了个.reloc 段,PE头也会多个区段表,所以0x200(512)个字节不够,所以PE头才变成了0x400(1024)个字节
问题找到了,是因为编译器默认开启了随机基址为了修复IAT而产生的重定位,我们关闭随机基址试一试,这里重新用link.exe连接一下
link Source.obj /DYNAMICBASE:NO 注:(/DYNAMICBASE:NO 为关闭随机基址)
再来查看一下文件大小
和我预期的一样,变成了1.5k
完善一下代码
[Asm] 纯文本查看 复制代码 .386
.model flat,stdcall
option casemap:none
;导入Lib库
includelib kernel32.Lib
includelib User32.Lib
;声明函数原型
ExitProcess proto,dwExitCode:dword
MessageBoxA proto,hWnd:dword,pText:dword,pTitle:dword,uType:dword
;只读数据段
.const
lpStr db "Hello World!",0
lpTitle db "Title",0
;代码段
.code
main:
invoke MessageBoxA,0,offset lpStr,offset lpTitle,0
invoke ExitProcess,0
end main
编译 ml Source.asm /link /DYNAMICBASE:NO /SUBSYSTEM:WINDOWS 注:(/SUBSYSTEM:WINDOWS表示生成窗口程序,没有控制台啦)
编译成功,没有警告或者错误
运行成功,没有问题,黑色的框框也没啦
Source.zip
(81.89 KB, 下载次数: 35)
参考:
http://kipirvine.com/asm/gettingStartedVS2017/index.htm
https://msdn.microsoft.com/zh-cn/library/hb5z4sxd.aspx
https://msdn.microsoft.com/zh-cn/library/y0zzbyt4.aspx
|
免费评分
-
查看全部评分
|