C语言msvc编译器内嵌汇编,【原创】如何使用VS自带工具写Windows汇编程序 Ⅰ

本帖最后由 小俊 于 2017-12-26 11:36 编辑

首先,先说一下我的环境

Windows10版本,和Windows SDK版本都是目前最新的 版本为:1709(16299)

VisualStudio也是最新的

编写Windows程序,当然需要用到Windows API,目前讲两种方式

动态获取函数地址,在这里我就不过多讲解,有兴趣看我前两篇帖子

正常方式,这就是我接下来要讲的了,导入Lib库,然后声明函数原型,就可以直接调用了32位Lib路径为:C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x86

最重要的俩个库为:kernel32.Lib User32.Lib吧这俩个库拷贝到我们的源码目录

55fd2b2273b5a8b4531f72773c469d6e.gif

Source.PNG (2.25 KB, 下载次数: 8)

2017-12-26 08:57 上传

然后在代码中导入

[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

55fd2b2273b5a8b4531f72773c469d6e.gif

386.PNG (32.44 KB, 下载次数: 2)

2017-12-26 09:12 上传

除了386,Masm还支持以下指令集

55fd2b2273b5a8b4531f72773c469d6e.gif

CPU.PNG (11.54 KB, 下载次数: 1)

2017-12-26 09:08 上传

.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

thread-679902-1-1.html

接下来吧代码进行编译,这里用到俩工具: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的开发人员命令提示符

55fd2b2273b5a8b4531f72773c469d6e.gif

VS.PNG (146.6 KB, 下载次数: 0)

2017-12-26 09:57 上传

输入ml,出现这些信息,说明环境没问题

55fd2b2273b5a8b4531f72773c469d6e.gif

ML.PNG (27.32 KB, 下载次数: 1)

2017-12-26 10:10 上传

然后将路径切换到我的源代码路径

cd C:\Users\XiaoJun\Desktop\Source

然后直接编译

ml Source.asm

55fd2b2273b5a8b4531f72773c469d6e.gif

编译.PNG (47.94 KB, 下载次数: 0)

2017-12-26 10:14 上传

恭喜,没有出现警告或者错误

生成了三个文件

55fd2b2273b5a8b4531f72773c469d6e.gif

File.png (40.43 KB, 下载次数: 1)

2017-12-26 10:29 上传

运行

55fd2b2273b5a8b4531f72773c469d6e.gif

Run.png (14.06 KB, 下载次数: 2)

2017-12-26 10:33 上传

没有问题,弹出了个啥也没有的消息框,因为我们给的参数都是0

运行没有问题,我们进一步做一些优化

首先,我为什么用汇编写程序,因为小,而且不依赖C运行时库,不会生成无用代码

但是我一查看文件属性,居然还有2.5k这是我接受不了的,一共这才几条汇编代码

55fd2b2273b5a8b4531f72773c469d6e.gif

Size.png (39.19 KB, 下载次数: 1)

2017-12-26 11:31 上传

我心算了一下,PE头0x200(512)个字节, .text代码段0x200(512)个字节,导入表在 .data段0x200(512)字节,一共应该是1.5k才对呀

所以我打开010Editor一探究竟

55fd2b2273b5a8b4531f72773c469d6e.gif

reloc.png (20.01 KB, 下载次数: 2)

2017-12-26 10:47 上传

发现多了个 .reloc 段,并且PE头占用了0x400(1024)个字节,所以才会那么大

因为多了个.reloc 段,PE头也会多个区段表,所以0x200(512)个字节不够,所以PE头才变成了0x400(1024)个字节

问题找到了,是因为编译器默认开启了随机基址为了修复IAT而产生的重定位,我们关闭随机基址试一试,这里重新用link.exe连接一下

link Source.obj /DYNAMICBASE:NO注:(/DYNAMICBASE:NO为关闭随机基址)

55fd2b2273b5a8b4531f72773c469d6e.gif

link.png (25.03 KB, 下载次数: 0)

2017-12-26 10:59 上传

再来查看一下文件大小

55fd2b2273b5a8b4531f72773c469d6e.gif

15k.png (38.93 KB, 下载次数: 0)

2017-12-26 11:00 上传

和我预期的一样,变成了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表示生成窗口程序,没有控制台啦)

55fd2b2273b5a8b4531f72773c469d6e.gif

ok.png (43.93 KB, 下载次数: 1)

2017-12-26 11:22 上传

编译成功,没有警告或者错误

55fd2b2273b5a8b4531f72773c469d6e.gif

Hello.png (10.32 KB, 下载次数: 1)

2017-12-26 11:23 上传

运行成功,没有问题,黑色的框框也没啦

2b1bef8df4f01fee4fc8b39358cdcfb3.gif

Source.zip

(81.89 KB, 下载次数: 34)

2017-12-26 11:36 上传

点击文件名下载附件

下载积分: 吾爱币 -1 CB

参考:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值